【发布时间】:2019-07-22 11:14:31
【问题描述】:
我正在尝试抓取:https://apps.neb-one.gc.ca/CommodityStatistics/Statistics.aspx,这在纸上似乎是一项简单的任务,并且有很多来自其他 SO 问题的资源。尽管如此,无论我如何更改我的请求,我都会遇到同样的错误。
我尝试了以下方法:
import requests
from bs4 import BeautifulSoup
url = "https://apps.neb-one.gc.ca/CommodityStatistics/Statistics.aspx"
with requests.Session() as s:
s.headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36'}
response = s.get(url)
soup = BeautifulSoup(response.content)
data = {
"ctl00$MainContent$rdoCommoditySystem": "ELEC",
"ctl00$MainContent$lbReportName": "171",
"ctl00$MainContent$ddlFrom": "01/11/2018 12:00:00 AM",
"ctl00$MainContent$rdoReportFormat": "Excel",
"ctl00$MainContent$btnView": "View",
"__EVENTVALIDATION": soup.find('input', {'name':'__EVENTVALIDATION'}).get('value',''),
"__VIEWSTATE": soup.find('input', {'name': '__VIEWSTATE'}).get('value', ''),
"__VIEWSTATEGENERATOR": soup.find('input', {'name': '__VIEWSTATEGENERATOR'}).get('value', '')
}
response = requests.post(url, data=data)
当我打印 response.contents 对象时,我收到了这条消息(tl;dr,它说 “发生系统错误。系统将提醒技术支持该问题”): p>
b'\r\n\r\n<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r\n\r\n<html xmlns="http://www.w3.org/1999/xhtml" >\r\n<head><title>\r\n\r\n</title></head>\r\n<body>\r\n <form name="form1" method="post" action="Error.aspx?ErrorID=86e0c980-7832-4fc5-b5a8-a8254dd8ad69" id="form1">\r\n<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTg3NjI4NzkzNmRkaCA5IA9393/t2iMAptLYU1QiPc8=" />\r\n\r\n<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="9D6BDE45" />\r\n <div>\r\n <h4>\r\n <span id="lblError">Error</span>\r\n </h4>\r\n <span id="lblMessage" class="Validator"><font color="Black">System error occurred. The system will alert technical support of the problem.</font></span>\r\n </div>\r\n </form>\r\n</body>\r\n</html>\r\n'
我使用了其他选项,例如更改__EVENTTARGET 参数,如建议的here 那样,还将cookie 从第一个请求传递到POST 请求。检查页面的来源,我注意到表单有一个“查询”功能,需要__EVENTTARGET 和__EVENTARGUMENT 才能工作:
//<![CDATA[
var theForm = document.forms['aspnetForm'];
if (!theForm) {
theForm = document.aspnetForm;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
但在 POST 响应的正文中,两个参数都是空的(可以在 Chrome 开发人员检查器中检查)。另一个问题是我需要下载任何格式(PDF 或 Excel)的文件,或者获取 HTML 版本,但是 .ASPX 表单不会在同一页面中呈现信息,它会打开一个新的 url:@ 987654323@ 用信息代替。
我有点迷路了,我错过了什么?
【问题讨论】:
标签: python html web-scraping beautifulsoup python-requests