我需要从JSF网站以编程方式获取数据。
以下是一个例子: https://dataminer.pjm.com/dataminerui/pages/public/lmp.jsf
要获取数据,请输入任何开始日期和结束日期,然后单击右上角的导出CSV。 (它会生成相当数量的数据,因此请选择1天的范围。)
在Chrome的“网络”标签中,我看到以下请求标头和表单数据:
Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8,ko;q=0.6,zh;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:425
Content-Type:application/x-www-form-urlencoded
Cookie:JSESSIONID=gixQBXBESRofyqLpiH2hlYg8; dataminer=1369707692.36895.0000; __utma=109610308.1662709339.1456530705.1456530705.1456530705.1; __utmc=109610308; __utmz=109610308.1456530705.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); JSESSIONID=8sx6CTIQhpPAAO5+4xcGGGlb; WT_FPC=id=xxx.xxx.xxx.xx-3069233008.30503152:lv=1456533141859:ss=1456530705581
Host:dataminer.pjm.com
Origin:https://dataminer.pjm.com
Referer:https://dataminer.pjm.com/dataminerui/pages/public/lmp.jsf
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
Form Data
frmCriteria:frmCriteria
frmCriteria:calStartDate_input:01/01/2016
frmCriteria:calStopDate_input:01/02/2016
frmCriteria:mnuMarket_input:REALTIME
frmCriteria:mnuMarket_focus:
frmCriteria:mnuFreq_input:Daily
frmCriteria:mnuFreq_focus:
frmCriteria:mnuPnodes_input:All
frmCriteria:mnuPnodes_focus:
javax.faces.ViewState:8578362602192686517:-1021667131748875106
frmCriteria:j_idt78:frmCriteria:j_idt78
我在此请求中看到了所有表单数据。看来我应该能够通过提交正确的请求(使用Python的请求库)以编程方式下载此CSV。
我已经尝试了很多方法来重新生成此标题和表单数据,但似乎无法生成CSV下载。
修改:我已尝试过以下操作。我对HTTP请求和响应以及cookie的结构知之甚少,所以这可能很糟糕。我在POST上获得了500分。
import requests
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'en-US,en;q=0.8,ko;q=0.6,zh;q=0.4',
'Cache-Control': 'max-age=0',
'Connection': 'keep-alive',
'Content-Length': 425,
'Content-Type': 'application/x-www-form-urlencoded',
'Host': 'dataminer.pjm.com',
'Origin': 'https://dataminer.pjm.com',
'Referer': 'https://dataminer.pjm.com/dataminerui/pages/public/lmp.jsf',
'Upgrade-Insecure-Requests': 1,
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36'
}
data = {
'frmCriteria': 'frmCriteria',
'frmCriteria': 'calStartDate_input:01/01/2016',
'frmCriteria': 'calStopDate_input:01/02/2016',
'frmCriteria': 'mnuMarket_input:REALTIME',
'frmCriteria': 'mnuMarket_focus:',
'frmCriteria': 'mnuFreq_input:Daily',
'frmCriteria': 'mnuFreq_focus:',
'frmCriteria': 'mnuPnodes_input:All',
'frmCriteria': 'mnuPnodes_focus:',
'javax.faces.ViewState': '8578362602192686517:-1021667131748875106',
'frmCriteria:j_idt78': 'frmCriteria:j_idt78'
}
url = 'https://dataminer.pjm.com/dataminerui/pages/public/lmp.jsf'
with requests.Session() as s:
get_response = s.get(url)
post_response = s.post(url, headers=headers, data=data)
如何使用请求库来获取CSV?
答案 0 :(得分:1)
除非您浏览通往相关网页的所有内容,否则您可能无法使用。 JSF页面倾向于在Web会话中存储大量状态,因此您可以简单地发布一些静态有效负载(就像您正在做的那样)并期望它能够正常工作。
一个完美的例子就是ViewState参数。该值可能每次都会发生很大变化,因此您使用的值可能完全无效。
所以,你可能不得不“直接找到那些让你在那里的页面”。
跟踪到达目的地所需的所有请求,查看从一步到另一步以及会话到会话的更改,并查看是否可以计算出最小步数(理想情况下只有1或2)以将其关闭。