如何使用 Python 的 Requests 模块“登录”到网站?

Posted

技术标签:

【中文标题】如何使用 Python 的 Requests 模块“登录”到网站?【英文标题】:How to "log in" to a website using Python's Requests module? 【发布时间】:2012-08-07 05:28:46 【问题描述】:

我正在尝试使用 Python 中的 Requests 模块发布登录网站的请求,但它并没有真正起作用。我是新手……所以我不知道是否应该制作我的用户名和密码 cookie 或我发现的某种类型的 HTTP 授权 (??)。

from pyquery import PyQuery
import requests

url = 'http://www.locationary.com/home/index2.jsp'

所以现在,我想我应该使用“post”和 cookie....

ck = 'inUserName': 'USERNAME/EMAIL', 'inUserPass': 'PASSWORD'

r = requests.post(url, cookies=ck)

content = r.text

q = PyQuery(content)

title = q("title").text()

print title

我感觉我在做饼干这件事上做错了……我不知道。

如果没有正确登录,主页的标题应该是“Locationary.com”,如果是,应该是“主页”。

如果您能向我解释一些关于请求和 cookie 的事情并帮助我解决这个问题,我将不胜感激。 :D

谢谢。

...它仍然没有真正起作用。好的...所以这是主页 html 在您登录之前所说的内容:

</td><td><img src="http://www.locationary.com/img/LocationaryImgs/icons/txt_email.gif">    </td>
<td><input class="Data_Entry_Field_Login" type="text" name="inUserName" id="inUserName"  size="25"></td>
<td><img src="http://www.locationary.com/img/LocationaryImgs/icons/txt_password.gif"> </td>
<td><input  class="Data_Entry_Field_Login"  type="password" name="inUserPass"     id="inUserPass"></td>

所以我认为我做得对,但输出仍然是“Locationary.com”

第二次编辑:

我希望能够长时间保持登录状态,并且每当我请求该域下的页面时,我希望内容显示为就像我已登录一样。

【问题讨论】:

【参考方案1】:

如果您想要的信息在您登录后立即被定向到的页面上...

让我们调用你的ck 变量payload,就像在python-requests 文档中一样:

payload = 'inUserName': 'USERNAME/EMAIL', 'inUserPass': 'PASSWORD'
url = 'http://www.locationary.com/home/index2.jsp'
requests.post(url, data=payload)

否则...

请参阅下面的https://***.com/a/17633072/111362。

【讨论】:

我使用 urllib、urrlib2 和 cookielib 以及一些 HTTP 标头使其以不同的方式工作。 遗憾的是我无法删除它,因为它是公认的答案。我不认为我在发布这个问题时理解了这个问题(后来澄清了),所以不知道为什么它被接受了。我的回答只有在您需要的数据在您登录后被重定向到的页面上时才有效。 @tigerFinch 有更好的答案。【参考方案2】:

我知道你找到了另一种解决方案,但是对于像我这样发现这个问题的人来说,寻找相同的东西,可以通过以下请求来实现:

首先,像 Marcus 所做的那样,检查登录表单的来源以获得三条信息——表单发布到的 url,以及用户名和密码字段的名称属性。在他的示例中,它们是 inUserName 和 inUserPass。

完成后,您可以使用requests.Session() 实例向登录网址发出发布请求,并将您的登录详细信息作为有效负载。从会话实例发出请求与正常使用请求基本相同,只是增加了持久性,允许您存储和使用 cookie 等。

假设您的登录尝试成功,您可以简单地使用会话实例向站点发出进一步的请求。识别您的 cookie 将用于授权请求。

示例

import requests

# Fill in your details here to be posted to the login form.
payload = 
    'inUserName': 'username',
    'inUserPass': 'password'


# Use 'with' to ensure the session context is closed after use.
with requests.Session() as s:
    p = s.post('LOGIN_URL', data=payload)
    # print the html returned or something more intelligent to see if it's a successful login page.
    print p.text

    # An authorised request.
    r = s.get('A protected web page url')
    print r.text
        # etc...

【讨论】:

然而问题是,如何获取 POST 登录表单?我如何知道它是否被称为 inUserName 而不是用户名、USERNAME 等? @Twinkle 查看表单的 HTML 源代码以了解它们在此处的名称。 s.text 似乎不起作用,但我仍然给你一些投票的爱,因为我向我展示了这个可爱的请求......语法 @HalcyonAbrahamRamirez 我认为这不是您寻求帮助的正确地方。我建议阅读有关您挑战的问题,特别是:***.com/questions/21928368/…,如果您无法解决,请打开您自己的问题。 如果用户名和密码输入没有 name 或 id 属性怎么办?【参考方案3】:

让我尽量简单,假设站点的URL是http://example.com/,假设你需要填写用户名和密码来注册,所以我们现在去登录页面说http://example.com/login.php并查看它的来源代码并搜索将在表单标记中的操作 URL,例如

 <form name="loginform" method="post" action="userinfo.php">

现在用 userinfo.php 生成绝对 URL,即 'http://example.com/userinfo.php',现在运行一个简单的 python 脚本

import requests
url = 'http://example.com/userinfo.php'
values = 'username': 'user',
          'password': 'pass'

r = requests.post(url, data=values)
print r.content

我希望有一天这对某个地方的人有所帮助。

【讨论】:

不错 - 请注意,有时检查名称/密码字段的元素可能会显示调用的文件而不是按钮(我刚刚在按钮检查时说“操作”,URL 是通过检查显示的usr / pass 字段) 如果您使用的是 chrome,请在网络选项卡上打开 devtools,在发出请求后,您可以检查实际值、密钥以及它们发送到的位置,这对于以下表单很有用不要使用传统的机制,而是使用 javascript/ajax 来处理表单。 在这种情况下,关于如何使网页直接弹出而不是打印页面内容的任何想法? 您需要使用webbrowser 模块 他上面的print r.content也是错误的,他应该使用print(r.content)【参考方案4】:

找出用户名&lt;...name=username.../&gt; 和密码&lt;...name=password../&gt; 在网站表单中使用的输入名称,并在下面的脚本中替换它们。还要替换 URL 以指向要登录的所需站点。

login.py

#!/usr/bin/env python

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
payload =  'username': 'user@email.com', 'password': 'blahblahsecretpassw0rd' 
url = 'https://website.com/login.html'
requests.post(url, data=payload, verify=False)

在尝试使用未经验证的 SSL 证书登录网站时,使用 disable_warnings(InsecureRequestWarning) 将使脚本的任何输出静音。

额外:

要在基于 UNIX 的系统上从命令行运行此脚本,请将其放置在一个目录中,即 home/scripts 并将此目录添加到您的路径中 ~/.bash_profile 或终端使用的类似文件中。

# Custom scripts
export CUSTOM_SCRIPTS=home/scripts
export PATH=$CUSTOM_SCRIPTS:$PATH

然后在home/scripts/login.py中创建一个指向这个python脚本的链接

ln -s ~/home/scripts/login.py ~/home/scripts/login

关闭你的终端,启动一个新终端,运行login

【讨论】:

【参考方案5】:

requests.Session() 解决方案协助登录到具有 CSRF 保护的表单(如在 Flask-WTF 表单中使用的)。检查是否需要 csrf_token 作为隐藏字段,并使用用户名和密码将其添加到有效负载中:

import requests
from bs4 import BeautifulSoup

payload = 
    'email': 'email@example.com',
    'password': 'passw0rd'
     

with requests.Session() as sess:
    res = sess.get(server_name + '/signin')
    signin = BeautifulSoup(res._content, 'html.parser')
    payload['csrf_token'] = signin.find('input', id='csrf_token')['value']
    res = sess.post(server_name + '/auth/login', data=payload)

【讨论】:

【参考方案6】:

某些页面可能需要的不仅仅是登录/通过。甚至可能有隐藏字段。最可靠的方法是使用检查工具并在登录时查看网络选项卡,以查看正在传递的数据。

【讨论】:

以上是关于如何使用 Python 的 Requests 模块“登录”到网站?的主要内容,如果未能解决你的问题,请参考以下文章

入门学Python一定要知道的requests模块安装及使用

入门学Python一定要知道的requests模块安装及使用

python网络爬虫之requests模块

使用 python-requests 模块更新 Session 中的 Cookie

如何在 Python 3.4 而不是 2.7 中安装 requests 模块

使用Python中的'requests'模块发出POST请求