Python requests POST Cookie 会话
大家好,
我正在学习Python中的requests
模块,想做一个简单的项目来获取任何未处理的停车罚单。
请问在GET
请求和POST
请求之间保存会话和cookies的方式对吗?
#!/usr/bin/env python
import requests
import urllib
session = requests.Session()
tokenRequest = session.get('https://paydirect.link2gov.com/NYCParking-Plate/ItemSearch')
sessionToken = tokenRequest.cookies['__RequestVerificationToken']
sessionCookies = tokenRequest.cookies
sessionHeaders = tokenRequest.headers
payload = {
'__RequestVerificationToken': sessionToken,
'ItemSearchQuestionUserInput': 'myplate',
'Questions[0].IsRequired': 'True',
'Questions[0].Sequence': 1,
'Questions[0].Text': 'PlateNumber',
'Questions[0].Type': 'Text',
'ItemSearchQuestionUserInput[1].QuestionAnswer': 'NY',
'Questions[1].IsRequired': 'True',
'Questions[1].Sequence': 2,
'Questions[1].Text': 'State',
'Questions[1].Type': 'Text',
'Questions[2].IsRequired': 'False',
'Questions[2].Sequence': 3,
'Questions[2].Text': 'PlateType',
'Questions[2].Type': 'Text',
'SubmitButton': 'Continue'
}
raw = urllib.urlencode(payload)
plateRequest = session.post('https://paydirect.link2gov.com/NYCParking-Plate/ItemSearch/Submit', data=raw, headers=sessionHeaders, cookies=sessionCookies)
print plateRequest.text
看起来好像不行……我肯定是漏掉了什么简单的东西。这个网站在这里:https://paydirect.link2gov.com/NYCParking-Plate/ItemSearch
谢谢!
1 个回答
8
看起来服务器对接收一个明确的 Content-Type: application/x-www-form-urlencoded
头信息很在意,而这个 requests
库默认并不会发送这个头信息。此外,如果你在表单中直接提交 __RequestVerificationToken
的值,服务器也不会接受这个值——你需要从 https://paydirect.link2gov.com/NYCParking-Plate/ItemSearch
返回的表单中解析出实际的值。你的表单数据也没有按照原始表单的输入字段来填写——你漏掉了一些字段,而且你传递的是 ItemSearchQuestionUserInput
,而不是 ItemSearchQuestionUserInput[0].QuestionAnswer
。还有一点是,你实际上是把第一次请求得到的 响应 头信息当作第二次请求的 请求 头信息,这样做并不合理——这两个上下文是不能互换的。
我已经修改了你的代码,现在我收到的消息是“我们找不到任何匹配项。请检查你的输入并重试。”这个消息在浏览器中提交表单时也会出现——我没有实际的美国车牌来测试。请注意,我引入了一个额外的依赖,即 lxml
模块,用于解析第一次请求返回的表单。
#!/usr/bin/env python
import requests
import urllib
from lxml import etree
session = requests.Session()
session.headers.update({'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36'})
tokenRequest = session.get('https://paydirect.link2gov.com/NYCParking-Plate/ItemSearch')
parser = etree.HTMLParser()
tree = etree.fromstring(tokenRequest.text, parser)
verificationToken = tree.xpath('//form//input[@name="__RequestVerificationToken"]/@value')[0]
sessionCookies = tokenRequest.cookies
payload = {
'__RequestVerificationToken': verificationToken,
'ItemSearchQuestionUserInput[0].QuestionAnswer': 'myplate',
'Questions[0].IsRequired': 'True',
'Questions[0].Options': '',
'Questions[0].DefaultAnswer': '',
'Questions[0].Sequence': 1,
'Questions[0].Text': 'PlateNumber',
'Questions[0].Type': 'Text',
'ItemSearchQuestionUserInput[1].QuestionAnswer': 'NY',
'Questions[1].IsRequired': 'True',
'Questions[1].Options': '',
'Questions[1].DefaultAnswer': '',
'Questions[1].Sequence': 2,
'Questions[1].Text': 'State',
'Questions[1].Type': 'Text',
'ItemSearchQuestionUserInput[2].QuestionAnswer': '',
'Questions[2].IsRequired': 'False',
'Questions[2].Options': '',
'Questions[2].DefaultAnswer': '',
'Questions[2].Sequence': 3,
'Questions[2].Text': 'PlateType',
'Questions[2].Type': 'Text',
'SubmitButton': 'Continue'
}
raw = urllib.urlencode(payload)
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
plateRequest = session.post('https://paydirect.link2gov.com/NYCParking-Plate/ItemSearch/Submit', data=raw, cookies=sessionCookies, headers=headers)
print plateRequest.text