【问题标题】:XPath not working in HtmlAgilityPack C#XPath 在 HtmlAgilityPack C# 中不起作用
【发布时间】:2015-10-28 22:57:34
【问题描述】:

我正在尝试解析此网页http://www.aliexpress.com/wholesale?site=glo&SearchText=watch&page=1 并获取所有手表。然而,我用 HTMLAgilityPack 尝试了大约十几个不同的 XPath,我只能抓取 4 个产品链接(应该是 36 个左右)。

    WebClient client = new WebClient();
        client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36";
    var html = client.DownloadString(currentUrl);
    var document = new HtmlDocument();

    document.LoadHtml(html);

     var links = doc.DocumentNode.SelectNodes("//div[@class='item']//a").Select(a => a.Attributes["href"].Value).Distinct();

我尝试了很多不同的 XPath,似乎没有任何效果,有趣的是,即使 "//a[@href]" 无法解析所有产品,但我再次只能看到其中 4 个的链接。

我重新检查了它正在加载的 html,我可以看到更多产品。那么问题是什么?是一些 HtmlAgilityPack 问题吗?任何人都可以帮忙,我已经为此苦苦挣扎了三天......

【问题讨论】:

    标签: c# .net parsing xpath html-agility-pack


    【解决方案1】:

    注意:我针对 http://www.aliexpress.com/wholesale?site=glo&SearchText=watch&page=1 进行了测试

    这不是与 HTMLAgility 包相关的问题,也不是与 XPath 相关的问题。这里的问题是,这个网站正在使用一种叫做车把 js 的东西来实现某种类型的延迟加载。要记住的一件事是WebClient 不是网络浏览器。也就是说,WebClient 检索服务器发送的静态 HTML 响应,并且不执行任何 javascript,而浏览器会。

    如果您检查从服务器获得的原始 HTML 响应,<ul class="util-clearfix son-list util-clearfix" id="hs-below-list-items"> 元素中只有四个项目:

    <ul class="util-clearfix son-list util-clearfix" id="hs-below-list-items">
        <!-- each li here is the ancestor of an anchor tag that you're hoping to scrape -->
        <li qrdata="200214047|32341478696|cn1513149702"  class="list-item list-item-first ">... </li>
        <li qrdata="200214047|32259964358|ali900189121"  class="list-item list-item-first ">...</li>
        <li qrdata="200214021|32388460600|cn1000737283"  class="list-item list-item-first ">..</li>
        <li qrdata="200214007|32400985609|cn1513217672"  class="list-item list-item-first ">...</li>
    </ul>
    

    在那之后,剩下的项目所在的地方有一个脚本块:

    <script type="text/x-handlebars-template" id="lazy-render" class="lazy-render">
        <li qrdata="200214007|32390805633|cn111508265"  class="list-item   ">
        ....
    </script>
    

    当您在HtmlDocument 对象中加载原始HTML 时,它会将&lt;script&gt; 元素中的内容视为NodeType.Text。这就是为什么你没有得到你想要的结果。

    也就是说,这里有一个解决方法:

    var links = document.DocumentNode.SelectNodes("//a[@class='picRind history-item ']|//a[@class='picRind history-item j-p4plog']").Select(a => a.Attributes["href"].Value).Distinct();
    foreach (var link in links)
    {
        Console.WriteLine(link);
    }
    
    var lazyContent = new HtmlDocument();
    lazyContent.LoadHtml(document.DocumentNode.SelectNodes("//script[@id='lazy-render']").First().ChildNodes[0].InnerHtml);
    var lazyLinks = lazyContent.DocumentNode.SelectNodes("//a[@class='picRind history-item ']|//a[@class='picRind history-item j-p4plog']")
                    .Select(a => a.Attributes["href"].Value)
                    .Distinct();
    
    foreach (var link in lazyLinks)
    {
        // Prints the remaining 36 product links
        Console.WriteLine(link);
    }
    

    我们在解决方法中所做的是获取脚本块,并将其视为新文档,然后抓取剩余的产品链接。

    【讨论】:

    • 非常感谢,这行得通!但是,我仍然缺少一个链接,我总共得到 39 个,lazylinks - 35 个,哪里有可能丢失一个?
    • 我仍然总共检索到 40 个。检查您丢失的链接和我们选择的 XPATH 是否存在细微差别(请参阅 XPATH 中的额外尾随空格)。我使用的 XPATH 基于感兴趣的链接之间共享的公共属性。您所依赖的属性可能会在开发人员甚至不打算更改它们的情况下更改。开发人员或其框架移除尾随空格或更改这些“链接”完全呈现的方式并非完全不可能。
    【解决方案2】:

    Yahoo 有新格式,它在使用 HAP XPath 时会导致错误。 例如,HAP 无法解析来自统计选项卡的数据。 试试这个链接:http://finance.yahoo.com/quote/IBM/key-statistics 获取价格/预订 (mrq) 数据。 HAP 无法解析 ..section 数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-19
      • 1970-01-01
      相关资源
      最近更新 更多