使用Google Apps Script登录外部网站做爬虫时身份验证异常求解
问题原因&修复方案
你代码存在以下4处配置遗漏/错误,是导致返回通用错误页的核心原因:
- POST目标URL不匹配:你代码中POST请求的URL和登录表单的action属性目标不一致,表单action末尾多了一个编码后的双引号
%22,你的请求URL缺少该后缀,导致提交到了错误路径,服务端直接返回通用错误页(标题为Fout),不会出现验证失败的error-panel元素。 - RememberMe参数提交错误:浏览器正常提交的表单数据包含两个RememberMe参数
RememberMe=true&RememberMe=false,但你用JS对象定义payload时,重复的键名会被后面的赋值覆盖,实际只会提交RememberMe=1,和服务端预期的参数格式不符。 - 缺Content-Type头声明:显式添加和浏览器一致的
Content-Type: application/x-www-form-urlencoded请求头,避免服务端解析表单数据异常。 - Accept-Encoding配置错误:不要直接在headers中添加Accept-Encoding字段,UrlFetchApp有专门的
acceptEncoding高级参数控制压缩内容解码,直接写在headers中可能导致响应无法被正确解析。
修改后的核心代码片段
function login() { // 修复1:使用和表单action一致的POST URL,添加末尾的%22 const url = "https://login.test-aankoop.be/SignIn?wa=wsignin1.0&wtrealm=eur://euroconsumers.pro.flinesc.nl-be/%22"; const getUrl = "https://login.test-aankoop.be/SignIn?wa=wsignin1.0&wtrealm=eur://euroconsumers.pro.flinesc.nl-be/"; try { Logger.log("make a GET for %s", getUrl); var response = UrlFetchApp.fetch(getUrl); var responseSetCookie = response.getAllHeaders()['Set-Cookie']; Logger.log("Response headers - raw Set-Cookie \n %s", responseSetCookie); // 修复2:手动拼接payload字符串,避免重复键被覆盖,参数值和浏览器提交的保持一致 var payload = `__RequestVerificationToken=${GetReqVerTokenFromHtml(response)}&Identification=bob@example.com&Password=ThePassword&RememberMe=true&RememberMe=false`; var headers = { "Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Connection": "keep-alive", "Cookie": GetConstructedCookie(responseSetCookie), "Origin": "https://login.test-aankoop.be", // 修复3:显式添加Content-Type头 "Content-Type": "application/x-www-form-urlencoded", "Referer": getUrl, "Upgrade-Insecure-Requests":"1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0" } var parameters = { "headers": headers, "method" : "post", "payload": payload, // 修复4:用专门参数开启压缩支持,不要在headers里加Accept-Encoding "acceptEncoding": "gzip, deflate, br", "followRedirects": true } Logger.log("make a POST for %s", url); response = UrlFetchApp.fetch(url,parameters); $ = Cheerio.load(response.getContentText()); if ($('.error-panel').html() == null) { Logger.log("No error panel found!"); Logger.log("Title of page is %s", $("title").text()); } else { Logger.log("OK error panel found")} } catch (ex) { Logger.log("something went wrong...\n %s", ex); } } // 其余工具函数保持不变即可
修改完成后重新运行,就能拿到包含error-panel的验证失败响应了。
内容的提问来源于stack exchange,提问作者BertAR
相关产品推荐
相关产品推荐

