如何用Google Apps Script抓取需登录的cinedi.com站点数据?
解决Google Apps Script登录ASP.NET站点并抓取数据的问题
针对你遇到的登录cinedi.com失败的问题,核心原因是ASP.NET站点的表单验证机制和请求参数构造错误,以下是具体解决方案:
问题诊断
当前代码存在两个关键错误:
- 把登录用户名/密码放在了
headers里,而ASP.NET表单提交的参数应放在请求的**payload(表单数据)**中 - 缺少ASP.NET表单必需的隐藏验证字段:
__VIEWSTATE、__VIEWSTATEGENERATOR、__EVENTVALIDATION等,这些字段是站点验证请求合法性的核心依据
正确实现步骤
1. 获取登录页面,提取必要字段和会话Cookie
先请求登录页面,获取页面中的隐藏验证字段,同时保存服务器返回的Cookie(用于维持会话状态)。
2. 构造完整的登录表单提交参数
将用户名、密码,加上所有提取到的隐藏字段,以及提交按钮的参数一起放入请求的payload中。
3. 发送登录请求并保存会话Cookie
登录成功后,服务器会更新会话Cookie,后续请求必须带上这个Cookie才能访问授权页面。
4. 使用授权Cookie抓取目标数据
用保存的Cookie请求需要的页面,即可获取登录后的数据。
完整代码示例
function fetchCinediData() { const loginUrl = "http://www.cinedi.com/Login.aspx?ReturnUrl=%2fDefault.aspx"; const targetUrl = "http://www.cinedi.com/Default.aspx"; // 登录后要访问的页面 const login = "mylogin"; const password = "mypass"; // 第一步:获取登录页面,提取隐藏字段和初始Cookie let loginPageResponse = UrlFetchApp.fetch(loginUrl); let loginPageHtml = loginPageResponse.getContentText(); let sessionCookie = loginPageResponse.getAllHeaders()["Set-Cookie"]; // 提取ASP.NET必需的隐藏字段 const viewState = extractHiddenField(loginPageHtml, "__VIEWSTATE"); const viewStateGenerator = extractHiddenField(loginPageHtml, "__VIEWSTATEGENERATOR"); const eventValidation = extractHiddenField(loginPageHtml, "__EVENTVALIDATION"); // 第二步:构造登录请求的payload const payload = { "__LASTFOCUS": "", "__VIEWSTATE": viewState, "__VIEWSTATEGENERATOR": viewStateGenerator, "__EVENTTARGET": "", "__EVENTARGUMENT": "", "__EVENTVALIDATION": eventValidation, "ctl00$Content$TbxLogin": login, "ctl00$Content$TbxPassword": password, "ctl00$Content$BtnLogin": "OK" // 对应HTML中提交按钮的value值 }; // 第三步:发送登录请求 const loginOptions = { method: "POST", headers: { "Cookie": sessionCookie, "Content-Type": "application/x-www-form-urlencoded" }, payload: payload, followRedirects: true, // 自动跟随登录后的跳转 muteHttpExceptions: true // 捕获异常,方便调试 }; let loginResponse = UrlFetchApp.fetch(loginUrl, loginOptions); let newSessionCookie = loginResponse.getAllHeaders()["Set-Cookie"] || sessionCookie; // 第四步:访问目标页面,抓取数据 const targetOptions = { headers: { "Cookie": newSessionCookie } }; let targetResponse = UrlFetchApp.fetch(targetUrl, targetOptions); let targetHtml = targetResponse.getContentText(); // 此处可添加解析HTML并写入谷歌表格的逻辑 // 例如用XmlService或正则提取数据,再通过SpreadsheetApp写入表格 Logger.log(targetHtml); } // 辅助函数:从HTML中提取隐藏字段的值 function extractHiddenField(html, fieldName) { const regex = new RegExp(`<input type="hidden" name="${fieldName}" id="${fieldName}" value="([^"]+)" />`); const match = html.match(regex); return match ? match[1] : ""; }
关键说明
- Cookie处理:ASP.NET通过Cookie维持会话,必须在登录请求和后续请求中正确传递Cookie
- 隐藏字段:
__VIEWSTATE等字段是ASP.NET的视图状态验证,每次请求可能变化,必须实时从登录页面提取 - Content-Type:表单提交必须设置为
application/x-www-form-urlencoded,确保服务器能正确解析payload - 调试技巧:启用
muteHttpExceptions后,可通过loginResponse.getResponseCode()查看登录请求状态码(302表示跳转成功,200可能是登录失败)
内容的提问来源于stack exchange,提问作者bricoltou59
相关产品推荐
相关产品推荐

