7

我正在使用 Python 3 作为脚本,该脚本将监视网页上用户个人资料中的更新。这个站点的登录受到 CSRF 对策的保护,这是一件好事。但是,我无法让我的脚本登录到该站点。

  • 我的方法使用mechanicalsoup

    import mechanicalsoup
    
    browser = mechanicalsoup.Browser()
    login_page = browser.get(base_url)
    login_form = login_page.soup.select(".form-signin")[0]
    
    login_form.find(attrs={"name": "username"})['value'] = 'username'
    login_form.find(attrs={"name": "password"})['value'] = 'password'
    
    page2 = browser.submit(login_form, login_url)
    print(str(page2.text))
    
  • 我的方法使用robobrowser

    import re
    from robobrowser import RoboBrowser
    
    browser = RoboBrowser(history=True)
    browser.open(base_url)
    form = browser.get_form(action='/login/')
    
    form["username"] = 'username'
    form["password"] = 'password'
    
    browser.submit_form(form)
    print(str(browser.select))
    

在这两种情况下,我都会得到一个 HTTP 状态403和一条消息说CSRF verification failed. Request aborted.

  • 任何想法如何解决这一问题?
  • 有问题的表单有一个包含 CSRF 令牌的隐藏输入。我猜mechanicalsouprobobrowser将提交此输入。我对吗?还是我必须特殊对待?
  • 我认为这两个包使用的会话将处理像 cookie 之类的所有内容。有什么我错过的吗?
4

2 回答 2

10

我通过设置标题使robobrowser变体工作。Referer

browser.session.headers['Referer'] = base_url

所以对我有用的完整代码如下:

import re
from robobrowser import RoboBrowser

browser = RoboBrowser(history=True)
browser.open(base_url)
form = browser.get_form(action='/login/')

form["username"] = 'username'
form["password"] = 'password'
browser.session.headers['Referer'] = base_url

browser.submit_form(form)
print(str(browser.select))
于 2015-07-27T19:57:13.057 回答
1

您只需在提交的表单中添加用户名和密码,还需要添加 csrf 令牌字段。见下文,我假设您可以找出字段名称和令牌值。

form["username"] = 'username'
form["password"] = 'password'
form["csrffieldname"] = 'csrfvalue' # This is what you are missing

每个表单提交的令牌值都会不同,因此您必须获取表单并解析出 csrf 令牌值并在令牌超时到期之前提交它。

于 2015-07-24T11:14:02.203 回答