我想从政府网站提取公共数据,但没有API直接公开这些信息。尝试将IMPORTXML
与XPath一起使用时会出现警告标语,如果您没有活动的会话Cookie,则会显示警告标语,并且不会返回任何数据。
请求的页面:https://www.dibbs.bsm.dla.mil/rfq/rfqrecs.aspx?category=nsn&value=7110-00-001-2667
这是所有可公开访问的信息,不需要登录凭据。有没有办法可以点击"警告页面上的“确定”按钮,以便IMPORTXML
访问正确的页面?
答案 0 :(得分:0)
从上面David的comment获取提示,我使用this question作为使用Google Apps脚本显示Cookie的基础:
var _URL = "https://www.dibbs.bsm.dla.mil/Rfq/RFQRecs.aspx?TypeSrch=cq&category=nsn&value=7110-00-001-2667";
function getData(_URL) {
var opt = {
"method" : "post",
"User-Agent" : "Mozilla/5.0",
"Accept" : "text/html,application/xhtml+xml,application/xml",
"Accept-Language" : "en-US,en;q=0.5",
"followRedirects" : true
};
var response = UrlFetchApp.fetch(url,opt);
var headers = response.getAllHeaders();
var sessioncookie = headers['Set-Cookie'];
Logger.log(sessioncookie);
opt = {
"method" : "get",
"User-Agent" : "Mozilla/5.0",
"Accept" : "text/html,application/xhtml+xml,application/xml",
"Accept-Language" : "en-US,en;q=0.5",
"headers" : {
"Cookie" : sessioncookie
},
"followRedirects" : true
};
var content = UrlFetchApp.fetch(url, opt).getContentText();
Logger.log("File size: " + content.length);
...
}
这返回了一个名为“ASP.NET_SessionId”的cookie,如下所示:
ASP.NET_SessionId=y0p5fp1cjl040p1ncr20h2gc; path=/; secure; HttpOnly
我在以下HTTP请求中传回了这个cookie,希望能够进一步发展。但我仍然无法绕过警告页面。在故障排除过程中,我习惯进入我的Chrome设置并清除此网站的Cookie,但后来注意到这个特定网站没有设置三个不同的Cookie,包括一个名为“DIBBSDoDWarning”的Cookie,其内容只是字符串“同意”。嗯,能做点什么吗?
尝试了一下,我发现我可以在一次请求中从一开始只发送这一个cookie来获取我想要的页面。
var opt = {
"method" : "get",
"User-Agent" : "Mozilla/5.0",
"Accept" : "text/html,application/xhtml+xml,application/xml",
"Accept-Language" : "en-US,en;q=0.5",
"headers" : {
"Cookie" : "DIBBSDoDWarning=AGREE; path=/; secure; HttpOnly"
},
"followRedirects" : true
};
var content = UrlFetchApp.fetch(url, opt).getContentText();
Google Apps脚本中没有IMPORTXML
支持使用Xpath轻松抓取网页,所以仍有待完成的工作是弄清楚这比我现在做的更优雅。我尝试使用XmlService.parse()
返回Document
,但是当脚本到达此点时始终失败(不确定此页面是否格式不正确),所以我的后备是一个简单的字符串搜索,试图简单地获取返回的结果数量:
var pos = content.search('id="ctl00_cph1_lblRecCount"')
var recordCount = content.substr(pos+40,22).match(/\d+/).join();
如果我找到一个很好的通用Xpath导向解决方案,将会更新。