我正在尝试通过python脚本从this page下载CSV文件。
但是当我尝试通过浏览器中的链接直接访问CSV文件时,会显示一个协议表单。在允许我下载文件之前,我必须同意此表单。
无法检索csv文件的确切网址。它是一个发送到后端数据库的值,用于获取文件 - 例如PERIOD_ID=2013-0
:
我已尝试urllib2.open()
和urllib2.read()
,但它会导致协议格式的html内容,而不是文件内容。
如何编写处理此重定向的python代码,然后将CSV文件提取给我并让我保存在磁盘上?
答案 0 :(得分:2)
您需要设置ASP.NET_SessionId
Cookie。您可以在上下文菜单中使用Chrome的 Inspect element 选项,或使用Firefox和Firebug扩展名来查找。
使用Chrome:
ASP.NET_SessionId
元素使用Firebug:
ASP.NET_SessionId
元素在我的情况下,我得到ihbjzynwfcfvq4nzkncbviou
- 它可能适合你,如果不是你需要执行上述程序。
将Cookie添加到您的请求中,并使用requests
模块下载文件(基于answer eladc):
import requests
cookies = {'ASP.NET_SessionId': 'ihbjzynwfcfvq4nzkncbviou'}
r = requests.get(
url=('https://www.paoilandgasreporting.state.pa.us/publicreports/Modules/'
'DataExports/ExportProductionData.aspx?PERIOD_ID=2013-0'),
cookies=cookies
)
with open('2013-0.csv', 'wb') as ofile:
for chunk in r.iter_content(chunk_size=1024):
ofile.write(chunk)
ofile.flush()
答案 1 :(得分:1)
这是我的建议,用于自动应用服务器cookie并基本上模仿标准客户端会话行为。
(由@ pope的答案554580无耻地启发。)
import urllib2
import urllib
from lxml import etree
_TARGET_URL = 'https://www.paoilandgasreporting.state.pa.us/publicreports/Modules/DataExports/ExportProductionData.aspx?PERIOD_ID=2013-0'
_AGREEMENT_URL = 'https://www.paoilandgasreporting.state.pa.us/publicreports/Modules/Welcome/Agreement.aspx'
_CSV_OUTPUT = 'urllib2_ProdExport2013-0.csv'
class _MyHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
def http_error_302(self, req, fp, code, msg, headers):
print 'Follow redirect...' # Any cookie manipulation in-between redirects should be implemented here.
return urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)
http_error_301 = http_error_303 = http_error_307 = http_error_302
cookie_processor = urllib2.HTTPCookieProcessor()
opener = urllib2.build_opener(_MyHTTPRedirectHandler, cookie_processor)
urllib2.install_opener(opener)
response_html = urllib2.urlopen(_TARGET_URL).read()
print 'Cookies collected:', cookie_processor.cookiejar
page_node, submit_form = etree.HTML(response_html), {} # ElementTree node + dict for storing hidden input fields.
for input_name in ['ctl00$MainContent$AgreeButton', '__EVENTVALIDATION', '__VIEWSTATE']: # Form `input` fields used on the ``Agreement.aspx`` page.
submit_form[input_name] = page_node.xpath('//input[@name="%s"][1]' % input_name)[0].attrib['value']
print 'Form input \'%s\' found (value: \'%s\')' % (input_name, submit_form[input_name])
# Submits the agreement form back to ``_AGREEMENT_URL``, which redirects to the CSV download at ``_TARGET_URL``.
csv_output = opener.open(_AGREEMENT_URL, data=urllib.urlencode(submit_form)).read()
print csv_output
with file(_CSV_OUTPUT, 'wb') as f: # Dumps the CSV output to ``_CSV_OUTPUT``.
f.write(csv_output)
f.close()
祝你好运!
关于为什么的事情,我认为@Steinar Lima在要求会话cookie方面是正确的。虽然除非您已经访问了Agreement.aspx
页面并通过提供商的网站提交了回复,否则您从浏览器的网络检查员处复制的cookie只会导致另一个重定向到欢迎使用PA DEP Oil& ;气体报告网站欢迎页面。这当然消除了让Python脚本为您完成工作的重点。