刮刮需要登录的网站

时间:2013-05-10 21:00:54

标签: python python-requests

我正在尝试用BeautifulSoup抓一个网站。该网站要求我登录。请查看我的代码。

from bs4 import BeautifulSoup as bs
import requests
import sys

user = 'user'
password = 'pass'

# Url to login page
url = 'main url'

# Starts a session
session = requests.session(config={'verbose': sys.stderr})

login_data = {
'loginuser': user,
'loginpswd': password,
'submit': 'login',
}

r = session.post(url, data=login_data)

# Accessing a page to scrape
r = session.get('specific url')
soup = bs(r.content)

我在看到这里的一些帖子后想出了这个代码,所以我猜它应该是有效的,但打印的内容仍然好像我已经注销了。

当我运行此代码时,会打印出来:

2013-05-10T22:49:45.882000   POST   >the main url to login<
2013-05-10T22:49:46.676000   GET    >error page of the main url page as if the logging in failed<
2013-05-10T22:49:46.761000   GET    >the specific url<

当然,登录详细信息是正确的。 需要一些帮助的人。

@EDIT

我如何在上面实现标题?

opener = urllib2.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]

2 个答案:

答案 0 :(得分:3)

首先,您不应该使用早于1.2.0的任何版本的请求。如果您发现错误(我们可能会),我们根本不会支持它们。

其次,您可能会寻找的是:

import requests
from requests.packages.urllib3 import add_stderr_logger

add_stderr_logger()
s = requests.Session()

s.headers['User-Agent'] = 'Mozilla/5.0'

# after examining the HTML of the website you're trying to log into
# set name_form to the name of the form element that contains the name and
# set password_form to the name of the form element that will contain the password
login = {name_form: username, password_form: password}
login_response = s.post(url, data=login)
for r in login_response.history:
    if r.status_code == 401:  # 401 means authentication failed
        sys.exit(1)  # abort

pdf_response = s.get(pdf_url)  # Your cookies and headers are automatically included

我评论了代码来帮助你。您也可以尝试@ FastTurtle建议使用HTTP Basic Auth,但如果您首先尝试发布到表单,则可以继续尝试按照上述方式进行操作。另外,请确保loginuserloginpswd是正确的表单元素名称。如果他们不是,这可能是这里的潜在问题.b

答案 1 :(得分:1)

requests模块支持多种类型的身份验证。幸运的是,您尝试解析的网站使用HTTP Basic Auth,在这种情况下,发送凭据非常简单。

此示例取自the requests website。您可以通过请求here和标题here了解有关身份验证的更多信息。

s = requests.Session()
s.auth = ('user', 'pass')
s.headers.update({'x-test': 'true'})

# both 'x-test' and 'x-test2' are sent
s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})
相关问题