如何使用MSXML2.XMLHTTP60实现需登录的Power Diary页面数据抓取
你当前代码无法完成登录的核心原因是,XMLReq.Open方法中直接传入账号密码的参数仅支持HTTP Basic认证场景,而Power Diary平台采用的是表单会话认证机制,这套逻辑不适用,所以你实际请求拿到的是未登录的登录页HTML,自然找不到对应类名的元素。
正确的实现方案分两步走,需要先提交登录请求获取有效会话,再携带会话访问目标页面:
第一步:先获取登录接口的必要参数
打开浏览器按下F12调出开发者工具,切换到「网络」面板,清空日志后手动在登录页输入账号密码点击登录,找到请求方法为POST的登录请求,记录三个信息:
- 登录请求的提交地址
- 表单提交的参数字段名(通常为账号对应
email/username、密码对应password,大概率还会有__RequestVerificationToken这类隐藏的CSRF校验字段) - 隐藏字段的取值可以先请求登录页HTML解析获取
第二步:修改VBA代码逻辑
修改后的代码示例如下,你需要把抓包拿到的参数对应替换到标注位置:
Option Explicit Sub PowerDiaryLogin() Dim XMLReq As New MSXML2.XMLHTTP60 Dim HTMLDoc As New MSHTML.HTMLDocument Dim loginUrl As String, targetUrl As String Dim postData As String Dim csrfToken As String ' 替换为你抓包拿到的登录请求地址 loginUrl = "https://my.powerdiary.com/Account/Login" targetUrl = "https://my.powerdiary.com/Profile/Client/Search" ' 第一步:请求登录页获取CSRF令牌 XMLReq.Open "GET", loginUrl, False XMLReq.send If XMLReq.Status <> 200 Then MsgBox "获取登录页失败:" & XMLReq.Status & " - " & XMLReq.statusText Exit Sub End If HTMLDoc.body.innerHTML = XMLReq.responseText ' 替换为你页面上CSRF隐藏字段的选择器,比如按name属性获取 csrfToken = HTMLDoc.querySelector("input[name='__RequestVerificationToken']").Value ' 第二步:构造POST登录请求,替换为你实际的账号密码和表单字段名 postData = "email=你的账号&password=你的密码&__RequestVerificationToken=" & csrfToken XMLReq.Open "POST", loginUrl, False XMLReq.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" XMLReq.send postData ' 验证登录是否成功,可根据返回的状态码或者跳转地址判断 If XMLReq.Status = 200 Or XMLReq.Status = 302 Then ' 第三步:登录成功后用同一个XMLReq实例访问目标页面 XMLReq.Open "GET", targetUrl, False XMLReq.send HTMLDoc.body.innerHTML = XMLReq.responseText Dim HTMLRoles As MSHTML.IHTMLElementCollection Set HTMLRoles = HTMLDoc.getElementsByClassName("form-section-title mt10") Debug.Print "找到元素数量:" & HTMLRoles.Length Dim HTMLRole As MSHTML.IHTMLElement For Each HTMLRole In HTMLRoles Debug.Print HTMLRole.tagName, HTMLRole.innerText Next HTMLRole Else MsgBox "登录失败:" & XMLReq.Status & " - " & XMLReq.statusText End If End Sub
注意事项
- 同一个
XMLReq实例会自动保存服务端返回的会话Cookie,不要中途新建实例否则会丢失登录状态 - 如果登录时需要输入验证码,这套XMLHTTP方案无法实现,你需要改用
InternetExplorer.Application对象模拟人工点击、输入的方式完成登录操作 - 如果提交登录后返回400错误,优先检查你提交的表单字段名、CSRF令牌是否和抓包结果一致
内容的提问来源于stack exchange,提问作者Geo Koro
相关产品推荐
相关产品推荐

