使用Requests和Django从脚本登录网页

时间:2014-07-03 20:14:12

标签: python django python-requests django-authentication

我在Django中编写了一个Web应用程序。我需要将一些数据发布到python脚本的表单中。禁用登录时,帖子(r2)可正常工作。我有正确的登录请求(r1),但它现在给我一个404错误的表单帖子(r2)。登录似乎没有转移到第二个请求。 csrftoken和sessionid被硬编码用于测试,因为它没有识别它们。相关代码(删除了网址):

url_login='../pecasRunLog/accounts/login/'
url_add_run='../pecasRunLog/model/'+region+'/add_run/'

client = requests.session()
client.get(url_login)
csrftoken = client.cookies['csrftoken']
login_data = {'username':user,'password':password, 'csrfmiddlewaretoken':csrftoken, 'next': '/pecasRunLog/'}
r1=client.post(url_login,data=login_data)

payload={'model_region':region_id,'scendir':scendir, 'mapit_scenario': schema, 'run_name':schema+timestamp, 'run_computer_name':os.environ['COMPUTERNAME'], 'run_computer_ip':get_lan_ip(), 'declared_user':declared_user, 'logged_in_user':getpass.getuser(), 'sd_schema':schema, 'sd_database':database, 'sd_host':get_lan_ip(), 'sd_port':pgport,'mapit_schema':schema, 'mapit_database':database, 'mapit_host':get_lan_ip(), 'mapit_port':pgport,'start_date':start_date, 'start_time':start_time, 'end_date':end_date, 'end_time':end_time,'logged_manually':3, 'csrfmiddlewaretoken':csrftoken, 'sessionid':'jtvv50cs3iyo9bjthbr2diujfmrrlsnf'}
r2=requests.post(url_add_run,payload)

3 个答案:

答案 0 :(得分:8)

由于r2需要r1返回的Cookie,因此无法正常工作。这可能无法修复,但如果不进行至少此更改,则不太可能。为此,您可以在整个脚本中使用相同的会话,或者在第一个请求之后将cookie传递给每个请求。

以下是使用整个会话的内容:

url_login='../pecasRunLog/accounts/login/'
url_add_run='../pecasRunLog/model/'+region+'/add_run/'

client = requests.session()
client.get(url_login)
csrftoken = client.cookies['csrftoken']
login_data = {'username':user,'password':password, 'csrfmiddlewaretoken':csrftoken, 'next': '/pecasRunLog/'}
r1=client.post(url_login,data=login_data)

payload={'model_region':region_id,'scendir':scendir, 'mapit_scenario': schema, 'run_name':schema+timestamp, 'run_computer_name':os.environ['COMPUTERNAME'], 'run_computer_ip':get_lan_ip(), 'declared_user':declared_user, 'logged_in_user':getpass.getuser(), 'sd_schema':schema, 'sd_database':database, 'sd_host':get_lan_ip(), 'sd_port':pgport,'mapit_schema':schema, 'mapit_database':database, 'mapit_host':get_lan_ip(), 'mapit_port':pgport,'start_date':start_date, 'start_time':start_time, 'end_date':end_date, 'end_time':end_time,'logged_manually':3, 'csrfmiddlewaretoken':csrftoken, 'sessionid':'jtvv50cs3iyo9bjthbr2diujfmrrlsnf'}
r2=client.post(url_add_run,payload)

以下是在整个脚本中传递Cookie的内容:

url_login='../pecasRunLog/accounts/login/'
url_add_run='../pecasRunLog/model/'+region+'/add_run/'

r0 = requests.get(url_login)
csrftoken = r0.cookies['csrftoken']
login_data = {'username':user,'password':password, 'csrfmiddlewaretoken':csrftoken, 'next': '/pecasRunLog/'}
r1=requests.post(url_login,data=login_data,cookies=r0.cookies)

payload={'model_region':region_id,'scendir':scendir, 'mapit_scenario': schema, 'run_name':schema+timestamp, 'run_computer_name':os.environ['COMPUTERNAME'], 'run_computer_ip':get_lan_ip(), 'declared_user':declared_user, 'logged_in_user':getpass.getuser(), 'sd_schema':schema, 'sd_database':database, 'sd_host':get_lan_ip(), 'sd_port':pgport,'mapit_schema':schema, 'mapit_database':database, 'mapit_host':get_lan_ip(), 'mapit_port':pgport,'start_date':start_date, 'start_time':start_time, 'end_date':end_date, 'end_time':end_time,'logged_manually':3, 'csrfmiddlewaretoken':csrftoken, 'sessionid':'jtvv50cs3iyo9bjthbr2diujfmrrlsnf'}
r2=requests.post(url_add_run,payload,cookies=r1.cookies)

如果这些都不起作用,请仔细查看cookie,也许你会发现问题。

答案 1 :(得分:5)

我只是面临同样的问题。

看起来django使用不同的URL登录帖子而不是登录主页。

此代码适用于我

import requests
URL1='http://localhost:8000/admin/'
URL='http://localhost:8000/admin/login/?next=/admin/'
UN='bino'
PWD='sendhimin'
client = requests.session()

# Retrieve the CSRF token first
client.get(URL1)  # sets the cookie
csrftoken = client.cookies['csrftoken']

login_data = dict(username=UN, password=PWD, csrfmiddlewaretoken=csrftoken)
r = client.post(URL2, data=login_data, headers={"Referer": "foo"})

答案 2 :(得分:0)

试试这个:

url_login='../pecasRunLog/accounts/login/'
url_add_run='../pecasRunLog/model/'+region+'/add_run/'

with requests.session() as client:
    client.get(url_login)
    csrftoken = client.cookies['csrftoken']
    login_data = {'username':user,'password':password, 'csrfmiddlewaretoken':csrftoken, 'next': '/pecasRunLog/'}
    r1=client.post(url_login,data=login_data)

    payload={'model_region':region_id,'scendir':scendir, 'mapit_scenario': schema, 'run_name':schema+timestamp, 'run_computer_name':os.environ['COMPUTERNAME'], 'run_computer_ip':get_lan_ip(), 'declared_user':declared_user, 'logged_in_user':getpass.getuser(), 'sd_schema':schema, 'sd_database':database, 'sd_host':get_lan_ip(), 'sd_port':pgport,'mapit_schema':schema, 'mapit_database':database, 'mapit_host':get_lan_ip(), 'mapit_port':pgport,'start_date':start_date, 'start_time':start_time, 'end_date':end_date, 'end_time':end_time,'logged_manually':3, 'csrfmiddlewaretoken':csrftoken, 'sessionid':'jtvv50cs3iyo9bjthbr2diujfmrrlsnf'}
    r2=client.post(url_add_run,payload)

如果这样做,我认为问题是你先从新创建的会话发帖,然后你做一个常规的帖子,你应该继续从会话发布