使用 Perl 的 mechanize 模块,几乎一切皆有可能。但不幸的是,我没有使用 perl,我仍然希望能够使用 python 完成所需的工作。我必须自动化的登录页面无法直接访问。浏览器中可见的 URL 不包含 Web 表单(也不包含任何内容,以 Web 2.0 的方式,它只是一堆 xhr 请求并内置于 javascript),但有一个我可以直接使用curl 发布到的 URL。文档表明
browser.open(url, data=whatever)
可能会做出明智的决定,但它似乎仍在使用 GET http 方法。或者可能,它正在使用 POST,但正在执行 application/x-www-form-urlencoded
而不是 json。
有问题的代码非常基本:
r = br.open('https://major-retailer.com/api/client/experience/v1/load', data=json.dumps(j))
这一切只是给了我一个通用的错误请求响应:
mechanize._response.get_seek_wrapper_class.<locals>.httperror_seek_wrapper: HTTP Error 400: Bad Request
我可以通过请求来完成这项工作,但仅限于这篇最初的文章,之后管理 cookie 和引荐来源网址等就变得有点难以处理。我在 python mechanize 上能找到的很少的东西表明它可能不足以完成任何复杂的任务,希望情况并非如此。
正确的答案是你不在Python中使用mechanize。
requests
模块有一个会话类,如果用于进行 get 和 post 调用,它将持久保留 cookie 和标头。这也满足了问题的其他部分...您可以直接进行 post 调用,并使用 json 有效负载。有一些小的开销,因为您可能需要执行诸如手动设置用户代理字符串之类的操作。
由于环境原因,这很令人困惑,Python 确实存在一个
mechanize
模块,但似乎已被放弃并且从未完全功能化,至少对于我没有使用博客、reddit 帖子、Stack 答案的搜索词,或其他任何东西都强调这是一个 requests
功能。
相关代码应如下所示:
import requests
session = requests.Session()
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'}
session.headers = headers
# irrelevant details code
r = session.post('https://majorretailer.com/api/client/experience/v1/load', json={'data':{'searchType':'BY_EMAIL_AND_PHONE','lob':'RETAIL','securityAccountLookupInput':{'email': u}}})
只要您继续使用会话对象进行 http 调用,一切都应该可以正常工作。如果您需要手动设置 cookie(例如,因为您已经从 javascript 文件中对其进行了正则表达式),那么您可以这样做:
session.cookies.set('access_token', r.json().get('access_token'),domain='*.majorretailer.com')
顺便说一句,不要忘记最后一个参数的第三个参数。
希望这对某人有帮助,我本来打算删除问题本身,但我认为这太令人困惑了,我需要自己提供答案。
tldr;
requests
模块是 Python 中正确的 mechanize 模块,或者说足够接近。