使用 requests.post 登录导致“错误 405 不允许”

Posted

技术标签:

【中文标题】使用 requests.post 登录导致“错误 405 不允许”【英文标题】:Login using requests.post results in "Error 405 Not allowed" 【发布时间】:2018-11-20 04:29:20 【问题描述】:

我的目标是从 consumerreports.com 抓取数据,因此我在这个项目中使用了“requests”和“beautifulsoup”。除了网络抓取之外,我在通过请求成功登录 consumerreports.com 时遇到了很多麻烦。

这是我的代码:我创建了两个文本文件,我在其中写了帖子和回复,所以我可以检查它是否成功登录。

import requests
import os.path

#declares any necessary variables
#file1, file2 to check if login is successful

save_path = '/Users/myName/Documents/Webscraping Project/'
login_url = 'https://www.consumerreports.org/cro/index.htm'
my_url = 'https://www.consumerreports.org/cro/index.htm'
pName = os.path.join(save_path, 'post text file'+".txt")
rName = os.path.join(save_path, 'response text file'+".txt")
post_file = open(pName, "w")
response_file = open(rName, "w")

#login using Session class from Requests package
with requests.Session() as s:

    payload = "userName":"myName@university.edu","password":"my_password"
    p = s.post(login_url, data=payload)
    print(p.text)

    r = s.get(my_url)

    #saves files to see if login was successful

    post_file.write(str(p.text.encode('utf-8')))
    response_file.write(str(r.text.encode('utf-8')))
post_file.close()
response_file.close()


print('Files created.')

这是我得到的:

<!DOCTYPE html>
<html>
  <head>
    <title>405 Not allowed.</title>
  </head>
  <body>
    <h1>Error 405 Not allowed.</h1>
    <p>Not allowed.</p>
    <h3>Guru Meditation:</h3>
    <p>XID: #some number </p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>

另外,我查看了'response text file.txt'的内容,通过基本的ctrl+f功能可以确定系统没有成功登录。

似乎网络服务器不接受“post”方法,至少对于这个特定的 url,这就是它返回错误的原因。但是,我不知道如何从这里开始。我在网上看了,有人建议使用

response = requests.get(login_url, headers='User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36')

创建一个用户代理来“登录”或其他什么。我对 python 还是很陌生,所以任何建议都将不胜感激。

【问题讨论】:

【参考方案1】:

您可能需要在s.post 中添加标头。此错误here 有解决方案。它对我有用。希望这会有所帮助。

【讨论】:

【参考方案2】:

原因是登录表单是通过 javascript 创建的。由于单击事件将登录表单添加到 DOM,因此执行请求时它不存在。所有请求都是从页面获取现有内容。如果 URL 确实更改以反映状态(显示登录表单),那么您可以使用它,但它不会。

您需要做的是使用无头浏览器(无头模式下的 chrome 或 firefox)与 Selenium 等库相结合。您可以在无头浏览器中加载站点并使用 Selenium 编写代码进行交互。但是,实施起来更具挑战性。

【讨论】:

感谢您的回复。幸运的是,CR 有一个不需要点击事件的备用登录页面。我用https://secure.consumerreports.org/ec/login 替换了原来的login_url,并且不再收到原来的错误。但是,它仍然没有登录!我查了response_file.txt,仍然没有找到我的名字。成功登录时网页的 HTML 代码包含我的名字,所以response_file.txt 应该也是如此,对吗?我在想,既然网页包含一个提交按钮,我是否必须在我的发布请求中包含某种点击操作?

以上是关于使用 requests.post 登录导致“错误 405 不允许”的主要内容,如果未能解决你的问题,请参考以下文章

requests.post 可以在慢速(但不是死)连接上超时吗? [复制]

day1 post验证登录

关于requests.post().json()获取到的JSON为单引号和NONE的那些事

'QueryDict' object is not callable 错误解析

Python之requests错误Expecting value: line 1 column 1 (char 0)

perl中设置POST登录时的重定向