使用Async,HtmlAgilityPack和XPath进行解析

时间:2014-06-11 21:10:33

标签: c# xpath asynchronous web-scraping html-agility-pack

我遇到了一个相当奇怪的问题。这很难解释所以请耐心等待,但基本上这里有一个简短的介绍:

  • 我是Async编程的新手,但无法在我的代码中找到问题
  • 之前我使用过HtmlAgilityPack,但从未使用过.NET 4.5版本。
  • 这是一个学习项目,我不是想要刮掉这样的东西。

基本上,正在发生的事情是这样的:我正在从互联网上检索一个页面,通过流将其加载到HtmlDocument,然后使用HtmlNodes表达式从中检索某个XPath。这是一段简化的代码:

            myStream = await httpClient.GetStreamAsync(string.Format("{0}{1}", SomeString, AnotherString);

            using (myStream)
            {
                myDocument.Load(myStream);
            }

HTML正在被正确地检索,但是XPath提取的HtmlNodes正在破坏他们的HTML。以下是我在Fiddler的回复中得到的一段HTML示例:

                    <div id="menu">
   <div id="splash">
      <div id="menuItem_1" class="ScreenTitle"  >Horse Racing</div>
      <div id="menuItem_2" class="Title"  >Wednesday Racing</div>
      <div id="subMenu_2">
         <div id="menuItem_3" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361707-2-20181217-0-0-1-0-0-4020-0-36200255-1-0-0-0-0">21.51 Britannia Way</a></div>
         <div id="menuItem_4" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361710-2-20181217-0-0-1-0-0-4020-0-36200258-1-0-0-0-0">21.54 Britannia Way</a></div>
         <div id="menuItem_5" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361713-2-20181217-0-0-1-0-0-4020-0-36200261-1-0-0-0-0">21.57 Britannia Way</a></div>
         <div id="menuItem_6" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361716-2-20181217-0-0-1-0-0-4020-0-36200264-1-0-0-0-0">22.00 Britannia Way</a></div>
         <div id="menuItem_7" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361719-2-20181217-0-0-1-0-0-4020-0-36200267-1-0-0-0-0">22.03 Britannia Way</a></div>
         <div id="menuItem_8" class="Level2"  >&#187;  <a href="../coupon/?ptid=4020&amp;key=2-70-70-22361722-2-20181217-0-0-1-0-0-4020-0-36200270-1-0-0-0-0">22.06 Britannia Way</a></div>
      </div>
   </div>
</div>

我使用的XPath是100%正确的,因为它在同一页面上的浏览器中工作,但这是一个示例a标记,它从之前显示的页面中进行了检索:

<a href="./coupon/?ptid=4020&amp;key=2-70-70-22361710-2-20181217-0-0-1-0-0-4020-0-36200258-1-0-0-0-0"">1.54 Britannia Way</</a>

这是我为简单起见而从上面复制的原文:

<a href="../coupon/?ptid=4020&amp;key=2-70-70-22361710-2-20181217-0-0-1-0-0-4020-0-36200258-1-0-0-0-0">21.54 Britannia Way</a></div>

正如您所看到的,InnerText发生了很大变化,因此URL也发生了变化。显然我的课程不起作用,但我不知道如何。是什么导致这个?这是HtmlAgilityPack中的错误吗?请指教!谢谢你的阅读!

2 个答案:

答案 0 :(得分:2)

不要假设XPath表达式在您的浏览器中工作(after DOM-conversion,可能使用AJAX加载数据,......)。这似乎是一个提供下注报价的网站,我猜他们会通过一些JavaScript调用来加载数据。

验证您的XPath表达式是否与网页源代码匹配(例如使用wget获取,或者点击&#34;在您的浏览器中查看源代码&#34; - 不要使用Firebug / ...为此!

如果网站使用AJAX加载数据,您可以通过使用Firebug来监控加载页面时获取的资源。通常这些是JSON或XML文件非常容易解析,并且比解析可怕的HTML网站更容易使用它们。

更新:在这种特殊情况下,该网站会将未向Accept-Language标头发送的用户转发到语言选择页面。发送此类标头以接收与浏览器相同的内容。在卷曲中,它看起来像这样:

curl -H "Accept-Language: en-US;q=0.6,en;q=0.4" https://mobile.bet365.com/sport/splash/Default.aspx?Sport

答案 1 :(得分:0)

经过数小时的猜测和调试后,问题变成了我重新使用的HtmlDocument。每次我想加载新页面而不是使用相同的页面时,我都会通过创建新的HtmlDocument来解决问题。

我希望这能节省你丢失的时间!