我目前正试图抓一个网站,这给了我一些麻烦。 webscraper正在跳过网页中的特定下拉菜单。
网页是使用asp.net生成的。我可以使用url加载第一页,然后我需要使用带有url的cookie来加载其他页面。然后将页面保存为.html文件。我加载的第二个网址缺少数据。
一旦我有.html文件,我用HTMLAgilityPack解析它们。
这是抓取网站的代码。
static void saveWebPage(int ID)
{
//The first page can be loaded via the url.
//The rest need an url and a cookie to be loaded.
//1st page
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(webPage + ID.ToString());
request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3";
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
CookieContainer aCookie = new CookieContainer();
request.CookieContainer = aCookie;
WebResponse pageResponse = request.GetResponse();
Stream responseStream = pageResponse.GetResponseStream();
TextWriter textDoc = new StreamWriter(ID.ToString() + "Page1.html");
string html = string.Empty;
using (StreamReader streamRead = new StreamReader(responseStream))
{
html = streamRead.ReadToEnd();
}
textDoc.Write(html);
textDoc.Close();
//2nd page
HttpWebRequest request2 = (HttpWebRequest)WebRequest.Create(webPage2 + ID.ToString());
request2.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3";
request2.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
request2.CookieContainer = request.CookieContainer;
pageResponse = request2.GetResponse();
responseStream = pageResponse.GetResponseStream();
textDoc = new StreamWriter(ID.ToString() + "Page2.html");
html = string.Empty;
using (StreamReader streamRead = new StreamReader(responseStream))
{
html = streamRead.ReadToEnd();
}
textDoc.Write(html);
textDoc.Close();
//........ More code in the same style.
}
该网页有几个下拉菜单。我可以获得所有这些数据,除了一个特定的数据。我可以抓取的菜单的HTML代码可能如下所示:
<td ><select name="menuName" id="menuID" disabled="disabled" style="menuStyle">
<option selected="selected" value="-1">Title</option>
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
<option value="4">D</option>
//....... More options.
我可以解析这些数据。问题菜单在网站上如下所示:
<td ><select name="menuName" onchange="javascript:setTimeout('__doPostBack(\'menuName\',\'\')', 0)" id=*menuID disabled="disabled" style="width:menuWidth; position:static">
<option value="-1">Title</option>
<option value="1">A</option>
<option selected="selected" value="2">B</option>
<option value="3">C</option>
//..... More options.
我的刮刀创建的.html文件如下所示:
<td ><select name="menuName" onchange="javascript:setTimeout('__doPostBack(\'menuName\',\'\')', 0)" id="menuID" disabled="disabled" style="width:menuWidth; position:static">
<option selected="selected" value="-1">Title</option>
我已经尝试过使用和不使用用户代理选项的刮刀,但它没有任何区别。我还检查了网站,我可以抓住其他运行javascript的菜单:setTimeout on change。那么我的刮刀是否有任何理由跳过菜单数据并将菜单标题作为选定值?
编辑:
用Fiddler重新加载页面会带来六个结果。
请求标题都看起来像这样:
CONNECT site.site.site:443 HTTP / 1.1
客户端用户代理:Mozilla / 5.0(Windows NT 6.1; WOW64)AppleWebKit / 537.36(KHTML,与Gecko一样)Chrome / 31.0.1650.63 Safari / 537.36
交通:
连接:保持活力
主持人:site.site.site
编辑2:Fiddler中响应的原始视图中的信息。
<td ><select name="menuName" onchange="javascript:setTimeout('__doPostBack(\'menuName\',\'\')', 0)" id="menuID" disabled="disabled" style="width:menuWidth; position:static">
<option value="-1">Title</option>
<option value="1">A</option>
<option selected="selected" value="2">B</option>
<option value="3">C</option>
//..... More options.
标题看起来与我在刮刀中发送的内容略有不同,网站是https,而不是http。
GET https://site.site.site/ ** asp.x?page2 HTTP / 1.1
主持人:site.site.site
连接:保持活力
缓存控制:max-age = 0
接受:text / html,application / xhtml + xml,application / xml; q = 0.9,image / webp, / ; q = 0.8
User-Agent:Mozilla / 5.0(Windows NT 6.1; WOW64)AppleWebKit / 537.36(KHTML,与Gecko一样) Chrome / 32.0.1700.76 Safari / 537.36
Referer:https://site.site.site/ * asp.x?page1
Accept-Encoding:gzip,deflate,sdch
接受语言:en-US,en; q = 0.8
Cookie:ASP.NET_SessionId = *** SessionID