如何使用Python的“请求”模块“登录”网站?


95

我正在尝试使用Python中的“请求”模块发布一个登录到网站的请求,但它实际上无法正常工作。我是新来的...所以我不知道是否应该使用我的用户名和密码cookie或某种我发现的HTTP授权类型(??)。

from pyquery import PyQuery
import requests

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

所以现在,我认为我应该使用“发布”和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

我有一种感觉,我做错了Cookie的事情……我不知道。

如果登录不正确,则主页标题应显示在“ 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”

第二次编辑:

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

Answers:


44

如果您想要的信息在页面上,登录后将立即定向到该页面。

让我们改为调用您的ck变量payload,例如在python-requests文档中:

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

除此以外...

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


我使用urllib,urrlib2和cookielib和一些HTTP标头以不同的方式工作。
马库斯·约翰逊

23
很遗憾,我无法删除它,因为这是公认的答案。我认为发布此问题时并没有理解我的问题(此问题在以后得到澄清),因此不确定为什么会接受。仅当您需要的数据位于登录后重定向到的页面上时,我的答案才有效。@tigerFinch有一个更好的答案。
凯蒂·拉瓦利

228

我知道您已经找到了另一种解决方案,但是对于像我这样的人,如果发现同样的问题,可以通过以下请求来实现:

首先,就像Marcus一样,检查登录表单的源以获取三项信息-表单发布到的URL以及用户名和密码字段的名称属性。在他的示例中,它们是inUserName和inUserPass。

一旦知道了这一点,就可以使用requests.Session()实例向登录URL发出发布请求,并将您的登录详细信息作为有效内容。从会话实例发出请求本质上与正常使用请求相同,它只是增加了持久性,允许您存储和使用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...

12
但是问题是,如何获取POST登录表单?我怎么知道它叫inUserName而不是用户名,USERNAME等?
lsheng 2014年

4
@Twinkle查看表单的HTML源代码,以了解它们在此处的名称。
亚伦·舒马赫

3
s.text似乎不起作用,但是我仍然给您带来投票的热爱,因为它向我展示了可爱的请求...语法
Software Prophets

s.text不起作用,因为它应该是这样的:p = s.post('LOGIN_URL.....然后p.text
Sebastian

2
@HalcyonAbrahamRamirez我认为这不是您寻求帮助的正确位置。我建议阅读有关您挑战的问题,例如:stackoverflow.com/questions/21928368/…,如果无法解决,请打开您自己的问题。
塞巴斯蒂安

36

让我尝试简化一下,假设该站点的URL是http://example.com/,并且假设您需要通过填充用户名和密码进行注册,所以我们在登录页面上输入http:// example。 com / login.php,然后查看其源代码并搜索操作网址,该网址将在表单标签中,例如

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

现在使用userinfo.php来创建绝对URL,该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

我希望这有一天能对某人有所帮助。


1
不错-注意,有时检查name / pass字段的元素可能会显示调用的文件而不是按钮(我只是在按钮检查中说了“ action”,URL是通过检查usr / pass字段显示的)
baxx

2
如果您使用的是chrome,请打开“网络”标签上的devtools,并在发出请求后可以检查实际值,键值以及它们的发送目的地,这对于不使用传统机制的表单很有用,使用javascript / ajax处理表单。
罗伯托·阿罗斯梅纳

1
在这种情况下,关于如何使网页直接弹出而不是打印页面内容的任何想法?

您将需要使用webbrowser模块
R. Barrett

也是他上面print r.content是错误的,他应该使用print(r.content)
·贝瑞特

6

找出用于用户名<...name=username.../>和密码的网站表单上输入的名称,<...name=password../>并在下面的脚本中替换它们。另外,替换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)

指某东西的用途 disable_warnings(InsecureRequestWarning)当尝试使用未经验证的SSL证书登录站点时会使脚本的任何输出静音。

额外:

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

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

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

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

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


4

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

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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.