XPath 在 HtmlAgilityPack C# 中不起作用
XPath not working in HtmlAgilityPack C#
我正在尝试解析此网页 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 问题吗?谁能帮忙,我现在已经为此苦苦挣扎了三天...
注意:我针对 http://www.aliexpress.com/wholesale?site=glo&SearchText=watch&page=1
进行了测试
这不是与 HTMLAgility 包或 XPath 相关的问题。这里的问题是这个网站正在使用一种叫做 handlebar 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
对象中加载 Raw HTML 时,它会将 <script>
元素中的内容视为 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);
}
我们在变通方法中所做的是获取脚本块,并将其视为新文档,然后抓取剩余的产品链接。
Yahoo 有新的格式,在使用 HAP XPath 时会导致错误。
例如,HAP 无法解析来自统计选项卡的数据。
试试这个 link:http://finance.yahoo.com/quote/IBM/key-statistics
获取 Price/Book (mrq) 数据。 HAP 无法解析 ..section 数据。
我正在尝试解析此网页 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 问题吗?谁能帮忙,我现在已经为此苦苦挣扎了三天...
注意:我针对 http://www.aliexpress.com/wholesale?site=glo&SearchText=watch&page=1
进行了测试这不是与 HTMLAgility 包或 XPath 相关的问题。这里的问题是这个网站正在使用一种叫做 handlebar 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
对象中加载 Raw HTML 时,它会将 <script>
元素中的内容视为 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);
}
我们在变通方法中所做的是获取脚本块,并将其视为新文档,然后抓取剩余的产品链接。
Yahoo 有新的格式,在使用 HAP XPath 时会导致错误。 例如,HAP 无法解析来自统计选项卡的数据。 试试这个 link:http://finance.yahoo.com/quote/IBM/key-statistics 获取 Price/Book (mrq) 数据。 HAP 无法解析 ..section 数据。