为什么我的 urlFetchApp 函数无法成功登录
Why is my urlFetchApp function failing to successfully login
我正在尝试使用 google 应用程序脚本登录到 ASP.Net 网站并抓取一些我通常必须手动检索的数据。我已经使用 Chrome 开发人员工具来获取正确的负载名称(TEXT_Username、TEXT_Password、_VIEWSTATE、_VIEWSTATEGENERATOR),我还得到了一个 ASP Net session与我的 Post 请求一起发送的 ID。
当我 运行 我的函数时 returns 如果 followRedirects 设置为 false,则响应代码 = 200,如果 followRedirects 设置为 true,则 returns 响应代码 = 302 .不幸的是,在这两种情况下,这些功能都无法成功验证网站。相反,返回的 HTML 是登录页面的 HTML 。
我尝试了不同的 header 变体和参数,但我似乎无法成功登录。
其他几点。当我使用 Developer 工具在 Chrome 中登录时,响应代码似乎是 302 Found。
有没有人对我如何成功登录此站点有任何建议。您是否发现我的函数中有任何可能导致我出现问题的错误。我愿意接受任何和所有的建议。
我的 GAS 功能如下:
function login(cookie, viewState,viewStateGenerator) {
var payload =
{
"__VIEWSTATE" : viewState,
"__VIEWSTATEGENERATOR" : viewStateGenerator,
"TEXT_Username" : "myUserName",
"TEXT_Password" : "myPassword",
};
var header = {'Cookie':cookie};
Logger.log(header);
var options =
{
"method" : "post",
"payload" : payload,
"followRedirects" : false,
"headers" : header
};
var browser = UrlFetchApp.fetch("http://tnetwork.trakus.com/tnet/Login.aspx?" , options);
Utilities.sleep(1000);
var html = browser.getContentText();
var response = browser.getResponseCode();
var cookie2 = browser.getAllHeaders()['Set-Cookie'];
Logger.log(response);
Logger.log(html);
}
function loginPage() {
var options =
{
"method" : "get",
"followRedirects" : false,
};
var browser = UrlFetchApp.fetch("http://tnetwork.trakus.com/tnet/Login.aspx?" , options);
var html = browser.getContentText();
// Utilities.sleep(500);
var response = browser.getResponseCode();
var cookie = browser.getAllHeaders()['Set-Cookie'];
login(cookie);
var regExpGen = new RegExp("<input type=\"hidden\" name=\"__VIEWSTATEGENERATOR\" id=\"__VIEWSTATEGENERATOR\" value=\"(.*)\" \/>");
var viewStateGenerator = regExpGen.exec(html)[1];
var regExpView = new RegExp("<input type=\"hidden\" name=\"__VIEWSTATE\" id=\"__VIEWSTATE\" value=\"(.*)\" \/>");
var viewState = regExpView.exec(html)[1];
var response = login(cookie,viewState,viewStateGenerator);
return response
}
我通过 运行 调用 loginPage() 函数来调用脚本。此函数获取 cookie (session id),然后调用登录函数并传递 session id (cookie)。
这是我使用 Google 的 Chrome 浏览器登录时在 Google 开发者工具网络部分看到的内容:
Remote Address: 66.92.89.141:80
Request URL: http://tnetwork.trakus.com/tnet/Login.aspx
Request Method: POST
Status Code:302 Found
**Request Headers** view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language: en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Content-Length: 252
Content-Type:application/x-www-form-urlencoded
Cookie: ASP.NET_SessionId=jayaejut5hopr43xkp0vhzu4; userCredentials=username=myUsername; .ASPXAUTH=A54B65A54A850901437E07D8C6856B7799CAF84C1880EEC530074509ADCF40456FE04EC9A4E47D1D359C1645006B29C8A0A7D2198AA1E225C636E7DC24C9DA46072DE003EFC24B9FF2941755F2F290DC1037BB2B289241A0E30AF5CB736E6E1A7AF52630D8B31318A36A4017893452B29216DCF2; __utma=260442568.1595796669.1421539534.1425211879.1425214489.16; __utmc=260442568; __utmz=260442568.1421539534.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=190106350.1735963725.1421539540.1425152706.1425212185.18; __utmc=190106350; __utmz=190106350.1421539540.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
Host:tnetwork.trakus.com
Origin:http://tnetwork.trakus.com
Referer:http://tnetwork.trakus.com/tnet/Login.aspx?
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36
**Form Dataview** sourceview URL encoded
__VIEWSTATE: O7YCnq5e471jHLqfPre/YW+dxYxyhoQ/VetOBeA1hqMubTAAUfn+j9HDyVeEgfAdHMl+2DG/9Gw2vAGWYvU97gml5OXiR9E/9ReDaw9EaQg836nBvMMIjE4lVfU=
__VIEWSTATEGENERATOR:F4425990
TEXT_Username:myUsername
TEXT_Password:myPassword
BUTTON_Submit: Log In
更新:该网站似乎正在使用 HttpOnly cookie。因此,我认为我没有捕获整个 cookie,因此我的 header 不正确。因此,我认为我需要将 followRedirects 设置为 false 并手动处理重定向和 cookie。我目前正在研究这个过程,但欢迎任何走过这条路的人提供意见。
我注意到提供的 Chrome 有效载荷包括 BUTTON_Submit: Log In
但您的 POST
有效载荷不包括。我发现对于 GAS 中的 POST
s,如果我在我的 payload
对象中明确设置一个 submit
变量,事情就会变得更加顺利。无论如何,如果您想模仿 Chrome 正在做的事情,这是很好的第一步。
所以在你的情况下,这是一个单行更改:
var payload =
{
"__VIEWSTATE" : viewState,
"__VIEWSTATEGENERATOR" : viewStateGenerator,
"TEXT_Username" : "myUserName",
"TEXT_Password" : "myPassword",
"BUTTON_Submit" : "Log In"
};
终于可以成功登录页面了。问题似乎是 urlFetchApp 无法遵循重定向。我相信这个 Whosebug post: how to fetch a wordpress admin page using google apps script
此 post 描述了导致我成功登录的以下过程:
- 将 followRedirect 设置为 false
- 提交 post 并捕获 cookies
- 使用捕获的 cookie 发出带有适当 url 的 get。
相关代码如下:
var url = "http://myUrl.com/;
var options = {
"method": "post",
"payload": {
"TEXT_Username" : "myUserName",
"TEXT_Password" : "myPassword",
"BUTTON_Submit" : "Log In",
},
"testcookie": 1,
"followRedirects": false
};
var response = UrlFetchApp.fetch(url, options);
if ( response.getResponseCode() == 200 ) {
// Incorrect user/pass combo
} else if ( response.getResponseCode() == 302 ) {
// Logged-in
var headers = response.getAllHeaders();
if ( typeof headers['Set-Cookie'] !== 'undefined' ) {
// Make sure that we are working with an array of cookies
var cookies = typeof headers['Set-Cookie'] == 'string' ? [ headers['Set-Cookie'] ] : headers['Set-Cookie'];
for (var i = 0; i < cookies.length; i++) {
// We only need the cookie's value - it might have path, expiry time, etc here
cookies[i] = cookies[i].split( ';' )[0];
};
url = "http://myUrl/Calendar.aspx";
options = {
"method": "get",
// Set the cookies so that we appear logged-in
"headers": {
"Cookie": cookies.join(';')
}
}
...
我正在尝试使用 google 应用程序脚本登录到 ASP.Net 网站并抓取一些我通常必须手动检索的数据。我已经使用 Chrome 开发人员工具来获取正确的负载名称(TEXT_Username、TEXT_Password、_VIEWSTATE、_VIEWSTATEGENERATOR),我还得到了一个 ASP Net session与我的 Post 请求一起发送的 ID。
当我 运行 我的函数时 returns 如果 followRedirects 设置为 false,则响应代码 = 200,如果 followRedirects 设置为 true,则 returns 响应代码 = 302 .不幸的是,在这两种情况下,这些功能都无法成功验证网站。相反,返回的 HTML 是登录页面的 HTML 。
我尝试了不同的 header 变体和参数,但我似乎无法成功登录。
其他几点。当我使用 Developer 工具在 Chrome 中登录时,响应代码似乎是 302 Found。
有没有人对我如何成功登录此站点有任何建议。您是否发现我的函数中有任何可能导致我出现问题的错误。我愿意接受任何和所有的建议。
我的 GAS 功能如下:
function login(cookie, viewState,viewStateGenerator) {
var payload =
{
"__VIEWSTATE" : viewState,
"__VIEWSTATEGENERATOR" : viewStateGenerator,
"TEXT_Username" : "myUserName",
"TEXT_Password" : "myPassword",
};
var header = {'Cookie':cookie};
Logger.log(header);
var options =
{
"method" : "post",
"payload" : payload,
"followRedirects" : false,
"headers" : header
};
var browser = UrlFetchApp.fetch("http://tnetwork.trakus.com/tnet/Login.aspx?" , options);
Utilities.sleep(1000);
var html = browser.getContentText();
var response = browser.getResponseCode();
var cookie2 = browser.getAllHeaders()['Set-Cookie'];
Logger.log(response);
Logger.log(html);
}
function loginPage() {
var options =
{
"method" : "get",
"followRedirects" : false,
};
var browser = UrlFetchApp.fetch("http://tnetwork.trakus.com/tnet/Login.aspx?" , options);
var html = browser.getContentText();
// Utilities.sleep(500);
var response = browser.getResponseCode();
var cookie = browser.getAllHeaders()['Set-Cookie'];
login(cookie);
var regExpGen = new RegExp("<input type=\"hidden\" name=\"__VIEWSTATEGENERATOR\" id=\"__VIEWSTATEGENERATOR\" value=\"(.*)\" \/>");
var viewStateGenerator = regExpGen.exec(html)[1];
var regExpView = new RegExp("<input type=\"hidden\" name=\"__VIEWSTATE\" id=\"__VIEWSTATE\" value=\"(.*)\" \/>");
var viewState = regExpView.exec(html)[1];
var response = login(cookie,viewState,viewStateGenerator);
return response
}
我通过 运行 调用 loginPage() 函数来调用脚本。此函数获取 cookie (session id),然后调用登录函数并传递 session id (cookie)。
这是我使用 Google 的 Chrome 浏览器登录时在 Google 开发者工具网络部分看到的内容:
Remote Address: 66.92.89.141:80
Request URL: http://tnetwork.trakus.com/tnet/Login.aspx
Request Method: POST
Status Code:302 Found
**Request Headers** view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language: en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Content-Length: 252
Content-Type:application/x-www-form-urlencoded
Cookie: ASP.NET_SessionId=jayaejut5hopr43xkp0vhzu4; userCredentials=username=myUsername; .ASPXAUTH=A54B65A54A850901437E07D8C6856B7799CAF84C1880EEC530074509ADCF40456FE04EC9A4E47D1D359C1645006B29C8A0A7D2198AA1E225C636E7DC24C9DA46072DE003EFC24B9FF2941755F2F290DC1037BB2B289241A0E30AF5CB736E6E1A7AF52630D8B31318A36A4017893452B29216DCF2; __utma=260442568.1595796669.1421539534.1425211879.1425214489.16; __utmc=260442568; __utmz=260442568.1421539534.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=190106350.1735963725.1421539540.1425152706.1425212185.18; __utmc=190106350; __utmz=190106350.1421539540.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
Host:tnetwork.trakus.com
Origin:http://tnetwork.trakus.com
Referer:http://tnetwork.trakus.com/tnet/Login.aspx?
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36
**Form Dataview** sourceview URL encoded
__VIEWSTATE: O7YCnq5e471jHLqfPre/YW+dxYxyhoQ/VetOBeA1hqMubTAAUfn+j9HDyVeEgfAdHMl+2DG/9Gw2vAGWYvU97gml5OXiR9E/9ReDaw9EaQg836nBvMMIjE4lVfU=
__VIEWSTATEGENERATOR:F4425990
TEXT_Username:myUsername
TEXT_Password:myPassword
BUTTON_Submit: Log In
更新:该网站似乎正在使用 HttpOnly cookie。因此,我认为我没有捕获整个 cookie,因此我的 header 不正确。因此,我认为我需要将 followRedirects 设置为 false 并手动处理重定向和 cookie。我目前正在研究这个过程,但欢迎任何走过这条路的人提供意见。
我注意到提供的 Chrome 有效载荷包括 BUTTON_Submit: Log In
但您的 POST
有效载荷不包括。我发现对于 GAS 中的 POST
s,如果我在我的 payload
对象中明确设置一个 submit
变量,事情就会变得更加顺利。无论如何,如果您想模仿 Chrome 正在做的事情,这是很好的第一步。
所以在你的情况下,这是一个单行更改:
var payload =
{
"__VIEWSTATE" : viewState,
"__VIEWSTATEGENERATOR" : viewStateGenerator,
"TEXT_Username" : "myUserName",
"TEXT_Password" : "myPassword",
"BUTTON_Submit" : "Log In"
};
终于可以成功登录页面了。问题似乎是 urlFetchApp 无法遵循重定向。我相信这个 Whosebug post: how to fetch a wordpress admin page using google apps script
此 post 描述了导致我成功登录的以下过程:
- 将 followRedirect 设置为 false
- 提交 post 并捕获 cookies
- 使用捕获的 cookie 发出带有适当 url 的 get。
相关代码如下:
var url = "http://myUrl.com/;
var options = {
"method": "post",
"payload": {
"TEXT_Username" : "myUserName",
"TEXT_Password" : "myPassword",
"BUTTON_Submit" : "Log In",
},
"testcookie": 1,
"followRedirects": false
};
var response = UrlFetchApp.fetch(url, options);
if ( response.getResponseCode() == 200 ) {
// Incorrect user/pass combo
} else if ( response.getResponseCode() == 302 ) {
// Logged-in
var headers = response.getAllHeaders();
if ( typeof headers['Set-Cookie'] !== 'undefined' ) {
// Make sure that we are working with an array of cookies
var cookies = typeof headers['Set-Cookie'] == 'string' ? [ headers['Set-Cookie'] ] : headers['Set-Cookie'];
for (var i = 0; i < cookies.length; i++) {
// We only need the cookie's value - it might have path, expiry time, etc here
cookies[i] = cookies[i].split( ';' )[0];
};
url = "http://myUrl/Calendar.aspx";
options = {
"method": "get",
// Set the cookies so that we appear logged-in
"headers": {
"Cookie": cookies.join(';')
}
}
...