Python requests POST Cookie 会话

2 投票
1 回答
6941 浏览
提问于 2025-04-18 04:07

大家好,

我正在学习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

撰写回答