我正在尝试使用Python中的“请求”模块发布一个登录网站的请求,但它实际上无法正常工作。我是新来的...所以我不知道是否应该使用我的用户名和密码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


我感觉我做错了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”

第二次编辑:

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

#1 楼

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

让我们改为调用ck变量payload,就像在python-requests docs中一样:

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标头以不同的方式工作。

–马库斯·约翰逊(Marcus Johnson)
2012年8月10日在11:43



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

–凯蒂·拉瓦利
2015年3月10日在16:10

#2 楼

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

首先,像马库斯所做的那样,检查登录表单的源以获取三项信息-表单发布到的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...


评论


但是问题是,如何获取POST登录表单?我怎么知道它是否被称为inUserName而不是用户名,USERNAME等?

– lsheng
2014年4月4日在6:43



@Twinkle查看该表单的HTML源代码,以查看在那里的名称。

–亚伦·舒马赫(Aaron Schumacher)
2014年4月7日13:05

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

–软件先知
14年6月16日在21:03

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

–塞巴斯蒂安
15年7月23日在9:35

如果用户名和密码输入没有名称或ID属性怎么办?

– stackPusher
17年12月9日,下午1:58

#3 楼

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

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


之类的形式标记现在使用userinfo.php使其绝对现在将是“ http://example.com/userinfo.php”的URL,现在运行一个简单的python脚本

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

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


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

评论


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

–baxx
15年12月4日在20:20

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

– Roberto Arosemena
16年8月6日,0:52

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

–user6315578
17年7月19日在10:07

您将需要使用webbrowser模块

–R。Barrett
1月8日19:25



另外他上面的打印r.content是错误的,他应该使用print(r.content)

–R。Barrett
1月8日19:25

#4 楼

找出用于用户名<...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


然后在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 楼

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