我希望编写一个可以自动从Bureau of Transportation Statistics Carrier Website下载.zip
个文件的脚本,但是我在Chrome中看到的响应标题有问题当我下载zip文件。我希望得到一个如下所示的响应标题:
HTTP/1.1 302 Object moved
Cache-Control: private
Content-Length: 183
Content-Type: text/html
Location: http://tsdata.bts.gov/103627300_T_T100_SEGMENT_ALL_CARRIER.zip
Server: Microsoft-IIS/8.5
X-Powered-By: ASP.NET
Date: Thu, 21 Apr 2016 15:56:31 GMT
但是,使用我在Chrome网络检查器中看到的相同信息来呼叫requests.post(url, data=params, headers=headers)
时,我收到以下回复:
>>> res.headers
{'Cache-Control': 'private', 'Content-Length': '262', 'Content-Type': 'text/html', 'X-Powered-By': 'ASP.NET', 'Date': 'Thu, 21 Apr 2016 20:16:26 GMT', 'Server': 'Microsoft-IIS/8.5'}
它几乎可以获得所有内容,除非它缺少我需要的Location
密钥,以便下载包含我想要的所有数据的.zip
文件。 同样 Content-Length
值不同,但我不确定这是否是个问题。
我认为我的问题与点击"下载"的事实有关。它在页面上实际发送了两个我可以在Chrome网络控制台中看到的请求。第一个请求是POST
请求,其产生的HTTP
响应为302,然后在响应标头中包含Location
。第二个请求是对响应头的GET
值中指定的URL的Location
请求。
我真的应该在这里发送两个请求吗?为什么我没有像在浏览器中那样使用requests
获得相同的响应标头? FWIW我使用curl -X POST -d /*my data*/
并在我的终端中找到了这个:
<head><title>Object moved</title></head>
<body><h1>Object Moved</h1>This object may be found <a HREF="http://tsdata.bts.gov/103714760_T_T100_SEGMENT_ALL_CARRIER.zip">here</a>.</body>
非常感谢任何帮助!
答案 0 :(得分:1)
我可以使用几乎我可以在Google Chrome网络控制台中看到的所有标题下载我要查找的zip文件。我的标题看起来像这样:
{'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', 'Referer': 'http://www.transtats.bts.gov/DL_SelectFields.asp?Table_ID=293', 'Origin': 'http://www.transtats.bts.gov', 'Upgrade-Insecure-Requests': 1, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36', 'Cookie': 'ASPSESSIONIDQADBBRTA=CMKGLHMDDJIECMNGLMDPOKHC', 'Accept-Language': 'en-US,en;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'application/x-www-form-urlencoded'}
然后我写道:
res = requests.post(url, data=form_data, headers=headers)
从Chrome控制台的“表单数据”部分复制了form_data
。收到请求后,我使用zipfile
和io
模块来解析res
中存储的响应内容。像这样:
import zipfile, io
zipfile.ZipFile(io.BytesIO(res.content))
然后该文件位于我运行Python代码的目录中。
感谢在this thread上回复的用户。