Html 个节点问题 HtmlAgility Pack
Html nodes issue with HtmlAgilityPack
我在尝试使用 HtmlAgilityPack
库解析这些 html 内容时遇到了很大的麻烦。
在这段代码中,我只想检索引用 uploaded.net[ 的 url (href),但我无法确定 url 是否引用它。
<div class='downloads' id='download_block'>
<h5 style='text-align:center'>FREE DOWNLOAD LINKS</h5>
<h4>uploadable.ch</h4>
<ul class='parts'>
<li>
<a href="http://url/..." target="_blank"> text here</a>
</li>
</ul>
<h4>uploaded.net</h4>
<ul class='parts'>
<li>
<a href="http://url/..." target="_blank"> text here</a>
</li>
</ul>
<h4>novafile.com</h4>
<ul class='parts'>
<li>
<a href="http://url/..." target="_blank"> text here</a>
</li>
</ul>
</div>
这是网页上的样子
这就是我所拥有的:
nodes = myHrmlDoc.DocumentNode.SelectNodes(".//div[@class='downloads']/ul[@class='parts']")
我不能只使用数组索引来确定位置,例如:
nodes(0) = uploadable.ch node
nodes(1) = uploaded.net node
nodes(2) = novafile.com node
...因为他们可以更改节点数量及其托管位置。
请注意,urls 也不会包含主机名称,重定向如下:
http://xxxxxx/r/YEHUgL44xONfQAnCNUVw_aYfY5JYAy0DT-i--
我可以用 C# 或其他方式做什么 VB.Net?
我看到这个工作的唯一方法是 2 倍方法。抱歉,我手头没有 HtmlAgilityPack,但这里有一个使用标准 XmlDocument
的示例。即使你说你不能使用数组索引来访问,这个过程应该允许你通过专门动态地抓取正确的索引来做到这一点。
void Main()
{
var xml = @"
<div class=""downloads"" id=""download_block"">
<h5 style=""text-align:center"">FREE DOWNLOAD LINKS</h5>
<h4>uploadable.ch</h4>
<ul class=""parts"">
<li>
<a href=""http://url/..."" target=""_blank""> text here</a>
</li>
</ul>
<h4>uploaded.net</h4>
<ul class=""parts"">
<li>
<a href=""http://upload.net/..."" target=""_blank""> text here</a>
</li>
</ul>
<h4>novafile.com</h4>
<ul class=""parts"">
<li>
<a href=""http://url/..."" target=""_blank""> text here</a>
</li>
</ul>
</div>";
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
var nav = xmlDocument.CreateNavigator();
var index = nav.Evaluate("count(//h4[text()='uploaded.net']/preceding-sibling::h4)+1").ToString();
var text = xmlDocument.SelectSingleNode("//ul["+index +"]//a/@href").InnerText;
Console.WriteLine(text);
}
基本上,它获取 uploaded.net h4
的索引,然后使用该索引 select 正确的 ul
标签并从底层锚标签中获取 URL。
对于不太干净且容易出错的代码,我们深表歉意,但它应该能让您朝着正确的方向前进。
提供您提供的代码段,这将帮助您入门。
var page = "<div class=\"downloads\" id=\"download_block\"> <h5 style=\"text-align:center\">FREE DOWNLOAD LINKS</h5> <h4>uploadable.ch</h4> <ul class=\"parts\"> <li> <a href=\"http://url/...\" target=\"_blank\"> text here</a> </li> </ul> <h4>uploaded.net</h4> <ul class=\"parts\"> <li> <a href=\"http://url/...\" target=\"_blank\"> text here</a> </li> </ul> <h4>novafile.com</h4> <ul class=\"parts\"> <li> <a href=\"http://url/...\" target=\"_blank\"> text here</a> </li> </ul></div>";
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(page);
var nodes = doc.DocumentNode.Descendants("h4").Where(n => n.InnerText.Contains("uploadable"));
foreach (var node in nodes)
{
var attr = node.NextSibling.NextSibling.Descendants().Where(x=> x.Name == "a").FirstOrDefault().Attributes["href"];
attr.Value.Dump();
}
这应该可以,但未经测试:
doc.DocumentNode.SelectSingleNode("//h4[contains(text(),'uploaded.net')]/following-sibling::ul//a").Attributes["href"].Value
也使用包含,因为您永远不知道文本是否包含空格。
我在尝试使用 HtmlAgilityPack
库解析这些 html 内容时遇到了很大的麻烦。
在这段代码中,我只想检索引用 uploaded.net[ 的 url (href),但我无法确定 url 是否引用它。
<div class='downloads' id='download_block'>
<h5 style='text-align:center'>FREE DOWNLOAD LINKS</h5>
<h4>uploadable.ch</h4>
<ul class='parts'>
<li>
<a href="http://url/..." target="_blank"> text here</a>
</li>
</ul>
<h4>uploaded.net</h4>
<ul class='parts'>
<li>
<a href="http://url/..." target="_blank"> text here</a>
</li>
</ul>
<h4>novafile.com</h4>
<ul class='parts'>
<li>
<a href="http://url/..." target="_blank"> text here</a>
</li>
</ul>
</div>
这是网页上的样子
这就是我所拥有的:
nodes = myHrmlDoc.DocumentNode.SelectNodes(".//div[@class='downloads']/ul[@class='parts']")
我不能只使用数组索引来确定位置,例如:
nodes(0) = uploadable.ch node
nodes(1) = uploaded.net node
nodes(2) = novafile.com node
...因为他们可以更改节点数量及其托管位置。
请注意,urls 也不会包含主机名称,重定向如下:
http://xxxxxx/r/YEHUgL44xONfQAnCNUVw_aYfY5JYAy0DT-i--
我可以用 C# 或其他方式做什么 VB.Net?
我看到这个工作的唯一方法是 2 倍方法。抱歉,我手头没有 HtmlAgilityPack,但这里有一个使用标准 XmlDocument
的示例。即使你说你不能使用数组索引来访问,这个过程应该允许你通过专门动态地抓取正确的索引来做到这一点。
void Main()
{
var xml = @"
<div class=""downloads"" id=""download_block"">
<h5 style=""text-align:center"">FREE DOWNLOAD LINKS</h5>
<h4>uploadable.ch</h4>
<ul class=""parts"">
<li>
<a href=""http://url/..."" target=""_blank""> text here</a>
</li>
</ul>
<h4>uploaded.net</h4>
<ul class=""parts"">
<li>
<a href=""http://upload.net/..."" target=""_blank""> text here</a>
</li>
</ul>
<h4>novafile.com</h4>
<ul class=""parts"">
<li>
<a href=""http://url/..."" target=""_blank""> text here</a>
</li>
</ul>
</div>";
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
var nav = xmlDocument.CreateNavigator();
var index = nav.Evaluate("count(//h4[text()='uploaded.net']/preceding-sibling::h4)+1").ToString();
var text = xmlDocument.SelectSingleNode("//ul["+index +"]//a/@href").InnerText;
Console.WriteLine(text);
}
基本上,它获取 uploaded.net h4
的索引,然后使用该索引 select 正确的 ul
标签并从底层锚标签中获取 URL。
对于不太干净且容易出错的代码,我们深表歉意,但它应该能让您朝着正确的方向前进。
提供您提供的代码段,这将帮助您入门。
var page = "<div class=\"downloads\" id=\"download_block\"> <h5 style=\"text-align:center\">FREE DOWNLOAD LINKS</h5> <h4>uploadable.ch</h4> <ul class=\"parts\"> <li> <a href=\"http://url/...\" target=\"_blank\"> text here</a> </li> </ul> <h4>uploaded.net</h4> <ul class=\"parts\"> <li> <a href=\"http://url/...\" target=\"_blank\"> text here</a> </li> </ul> <h4>novafile.com</h4> <ul class=\"parts\"> <li> <a href=\"http://url/...\" target=\"_blank\"> text here</a> </li> </ul></div>";
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(page);
var nodes = doc.DocumentNode.Descendants("h4").Where(n => n.InnerText.Contains("uploadable"));
foreach (var node in nodes)
{
var attr = node.NextSibling.NextSibling.Descendants().Where(x=> x.Name == "a").FirstOrDefault().Attributes["href"];
attr.Value.Dump();
}
这应该可以,但未经测试:
doc.DocumentNode.SelectSingleNode("//h4[contains(text(),'uploaded.net')]/following-sibling::ul//a").Attributes["href"].Value
也使用包含,因为您永远不知道文本是否包含空格。