如何在国防部警告屏幕后面刮一页



我想从政府网站获取公共数据,但没有API可以直接公开这些信息。尝试将IMPORTXML与XPath一起使用会遇到一个警告横幅,如果您没有活动的会话cookie,则会出现该横幅,并且不会返回任何数据。

请求的页面:https://www.dibbs.bsm.dla.mil/rfq/rfqrecs.aspx?category=nsn&值=7110-00-001-2667

收到的页面:https://www.dibbs.bsm.dla.mil/dodwarning.aspx?goto=/rfq/rfqrecs.aspx?category=nsn&值=7110-00-001-2667

这是所有可公开访问的信息,不需要登录凭据。有没有一种方法可以"点击"警告页面上的"确定"按钮,以便IMPORTXML访问正确的页面?

根据David上面的评论,我用这个问题作为使用谷歌应用程序脚本显示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;路径=/;保护HttpOnly

我在下面的HTTP请求中传回了这个cookie,希望能更进一步。但我还是没能绕过警告页面。在故障排除过程中,我习惯了进入我的Chrome设置并清除该网站的cookie,但后来注意到这个特定网站设置了三个不同的cookie,而不是一个,其中一个名为"DIBBSDoDWarning",其内容只是字符串"AGREE"。嗯,这能做点什么吗?

经过一点实验,我发现我可以简单地从一开始就在一个请求中发送这一个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();

谷歌应用程序脚本中没有IMPORTXML支持,无法使用Xpath轻松抓取网页,因此仍需解决的问题是如何比我现在更优雅地完成这项工作。我尝试使用XmlService.parse()返回Document,但当脚本达到这一点时,它总是失败(不确定这个页面是否格式错误),所以我的回退是一个简单的字符串搜索,试图简单地获取返回的结果数:

var pos = content.search('id="ctl00_cph1_lblRecCount"')
var recordCount = content.substr(pos+40,22).match(/d+/).join();

如果我找到一个好的通用Xpath解决方案,就会更新。

最新更新