使用'请求'用于POST请求的python模块,接收响应就好像它是GET

时间:2017-05-17 13:14:03

标签: python python-requests

所以我试图制作一个检查公交车预订可用性的脚本。这个的起始链接是https://reservation.pc.gc.ca/

在保留框中,需要选择以下内容:

  • 预订:日间使用(导游徒步,Lake O'Hara巴士)
  • Park:Yoho-Lake O' Hara
  • 抵达日期:6月16日
  • 派对大小:2

输入这些选项后,会转到以下页面:https://reservation.pc.gc.ca/Yoho-LakeO'Hara?Calendar

据我了解,如果我向第二个链接发送POST请求并提供正确的数据,则应返回我正在寻找的页面

如果我在选择正确的参数时查看开发工具网络信息,则表单数据为:

  

__ EVENTTARGET:

     

__ EVENTARGUMENT:   __VIEWSTATE:-reallllly long string -

     

__ VIEWSTATEGERERATOR: 8D0E13E6

     

ctl00 $ MainContentPlaceHolder $ rdbListReservationType:事件

     

ddlLocations: 213a1bc9-9218-4e98-9a7f-0f209008e437 **

     

ddlArrivalMonth: 2017-06-16

     

ddlArrivalDay: 19

     

ddlNights: 1

     

ddlDepartureMonth:

     

ddlDepartureDay:

     

ddlEquipment:

     

ddlEquipmentSub:

     

ddlPartySize:2

     

ctl00 $ MainContentPlaceHolder $ chkExcludeAccessible: on

     

ctl00 $ MainContentPlaceHolder $ imageButtonCalendar.x: 64

     

ctl00 $ MainContentPlaceHolder $ imageButtonCalendar.y: 56

所以我写的代码是:

import requests

payload = {
        '__EVENTTARGET': '',
        '__EVENTARGUMENT': '',
        '__VIEWSTATE':-reallly long string-,
        '__VIEWSTATEGENERATOR': '8D0E13E6',
        'ctl00$MainContentPlaceHolder$rdbListReservationType': 'Events',
        'ddlLocations': '213a1bc9-9218-4e98-9a7f-0f209008e437',
        'ddlArrivalMonth': 2017-06-16,
        'ddlArrivalDay': 19,
        'ddlNights': 1,
        'ddlDepartureMonth': '',
        'ddlDepartureDay': '',
        'ddlEquipment': '',
        'ddlEquipmentSub': '',
        'ddlPartySize': 2,
        'ctl00$MainContentPlaceHolder$chkExcludeAccessible': 'on',
        'ctl00$MainContentPlaceHolder$imageButtonCalendar.x': 64,
        'ctl00$MainContentPlaceHolder$imageButtonCalendar.y': 56
        }

r = requests.get(r"https://reservation.pc.gc.ca/Yoho-LakeO'Hara?Calendar", data=payload)

print r.text

r.text最终只是第二个链接,好像没有输入任何参数 - 好像我只是向链接发送了一个普通的GET请求。我尝试将整数的有效负载值转换为字符串,我尝试删除空键:值对。没运气。试图找出我错过的东西。

2 个答案:

答案 0 :(得分:1)

在我看来,有两件事正在发生:

  1. @errata是正确的,这应该是一个POST请求。你差不多就在那里。

  2. 我注意到的是,它似乎将表单数据发布到Home.aspx,并且您在提交表单后看到的URL是该处理和后续重定向的结果。

  3. 您可以尝试将表单数据作为json发布到./Home.aspx。

    我通过Postman发现这几乎有效,但我必须指定内容类型才能获得正确的结果。

    如果您需要知道如何将标题 正文指令添加到.post()方法,则看起来有一个这里有一个很好的例子(尽管可能有点过时): adding header to python request module

    另外,fwiw,看看Postman。如果你对请求缺乏经验并且在Python中没有经验,至少这可能会带来一些试验和错误的负担。

答案 1 :(得分:0)

您正在使用

r = requests.get(r"https://reservation.pc.gc.ca/Yoho-LakeO'Hara?Calendar", data=payload)

而不是

r = requests.post(r"https://reservation.pc.gc.ca/Yoho-LakeO'Hara?Calendar", data=payload)

在您的问题中深入挖掘,我发现您调用的URL实际上是重定向到不同的URL(返回HTTP响应302):

$ curl -I "https://reservation.pc.gc.ca/Yoho-LakeO'Hara"
HTTP/1.1 302 Found
Cache-Control: private
Content-Length: 77273
Content-Type: text/html; charset=utf-8
Location: https://reservation-pc.fjgc-gccf.gc.ca/GccfLanguage.aspx?lang=eng&ret=https%3a%2f%2freservation.pc.gc.ca%3a443%2fYoho-LakeO%27Hara
Server: Microsoft-IIS/8.0
Set-Cookie: ASP.NET_SessionId=qw4p4e2zxjxx0c2zyq014p45; path=/; secure; HttpOnly
Set-Cookie: CookieLocaleName=en-CA; path=/; secure; HttpOnly
X-Powered-By: ASP.NET
X-Frame-Options: SAMEORIGIN
Date: Wed, 17 May 2017 14:22:53 GMT

然而,在响应结果Location之后也是302:

$ curl -I "https://reservation-pc.fjgc-gccf.gc.ca/GccfLanguage.aspx?lang=eng&ret=https%3a%2f%2freservation.pc.gc.ca%3a443%2fYoho-LakeO%27Hara"
HTTP/1.1 302 Found
Cache-Control: private
Content-Length: 179
Content-Type: text/html; charset=utf-8
Location: https://reservation.pc.gc.ca:443/Yoho-LakeO'Hara?gccf=true
Server: Microsoft-IIS/8.0
Set-Cookie: ASP.NET_SessionId=rbcuvexfg4fb340ixtcjd1qy; path=/; secure; HttpOnly
Set-Cookie: _gc_lang=eng; domain=.fjgc-gccf.gc.ca; path=/; secure; HttpOnly
X-Powered-By: ASP.NET
X-Frame-Options: SAMEORIGIN
Date: Wed, 17 May 2017 14:24:55 GMT

所有这些可能会导致请求最终将您的POST转换为GET ......