通过 Python 登录网站 - 如何处理 CSRF?
Login to a website via Python - how to deal with CSRF?
我正在使用 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))
在这两种情况下,我都得到了 403
的 HTTP 状态和 CSRF verification failed. Request aborted.
的消息
- 有什么解决办法吗?
- 有问题的表单有一个包含 CSRF 令牌的隐藏输入。我想
mechanicalsoup
和 robobrowser
也会提交此输入。我对吗?还是必须特殊对待?
- 我认为这两个包使用的会话可以处理 cookie 等所有内容。我错过了什么吗?
您只是在提交的表单中添加用户名和密码,您还需要添加 csrf 令牌字段。请参阅下文,我假设您可以找出字段名称和标记值。
form["username"] = 'username'
form["password"] = 'password'
form["csrffieldname"] = 'csrfvalue' # This is what you are missing
每个表单提交的令牌值都会不同,因此您必须获取表单并解析出 csrf 令牌值并在令牌超时到期之前提交。
我通过设置 Referer
header.
让 robobrowser
变体起作用
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))
我正在使用 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))
在这两种情况下,我都得到了 403
的 HTTP 状态和 CSRF verification failed. Request aborted.
- 有什么解决办法吗?
- 有问题的表单有一个包含 CSRF 令牌的隐藏输入。我想
mechanicalsoup
和robobrowser
也会提交此输入。我对吗?还是必须特殊对待? - 我认为这两个包使用的会话可以处理 cookie 等所有内容。我错过了什么吗?
您只是在提交的表单中添加用户名和密码,您还需要添加 csrf 令牌字段。请参阅下文,我假设您可以找出字段名称和标记值。
form["username"] = 'username'
form["password"] = 'password'
form["csrffieldname"] = 'csrfvalue' # This is what you are missing
每个表单提交的令牌值都会不同,因此您必须获取表单并解析出 csrf 令牌值并在令牌超时到期之前提交。
我通过设置 Referer
header.
robobrowser
变体起作用
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))