【问题标题】:Inner node data with HtmlAgilityPack C#使用 HtmlAgilityPack C# 的内部节点数据
【发布时间】:2013-06-20 11:16:00
【问题描述】:

我正在使用 HtmlAgilityPack 从网页中读取数据/字符串。

我的 html 在这里摆弄

http://jsfiddle.net/7DWfa/1/

这是我的代码

HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.OptionFixNestedTags = true;
HtmlNode.ElementsFlags.Remove("option");
htmlDoc.LoadHtml(s);
if (htmlDoc.DocumentNode != null){
HtmlAgilityPack.HtmlNode bodyNode = htmlDoc.DocumentNode.SelectSingleNode("//body");
if (bodyNode != null)
{//what to do here to get title and href?
var inputs = from input in htmlDoc.DocumentNode.Descendants("div")
                     where input.Attributes["class"].Value == "results-data-price-btn"
                     select input;

}
}

请指导我如何通过类获取 div 值

【问题讨论】:

  • 什么的标题和引用?
  • 如果你只是查看jsfiddle.net/7DWfa/2 有价格标题和图像src 等信息,我想得到这些
  • @Arran:我更新了我的问题..我尝试了很多方法但没有运气...
  • 使用 xpath //body/div[class=xyz] 会更容易

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


【解决方案1】:

注意:以下内容未经测试,我只是快速查看了页面的 HTML 并试图了解它是如何“组合”在一起的。

每辆车的“结果”都有一个div,类为search-results-box。所以....

var rootNode = htmlDoc.DocumentNode;
var allCarResults = rootNode.SelectNodes("//div[normalize-space(@class)='search-results-box']");
foreach (var carResult in allCarResults)
{

}

您拥有每个“汽车结果”(例如,现在每个项目都是代表其中一辆汽车的整个部分......所以深入挖掘......

在每一个中,汽车的数据都在另一个div中,类为search-results-data...so....

var dataNode = carResult.SelectSingleNode(".//div[@class='search-results-data']");

this 中,您现在将更深入地挖掘。汽车的标题在另一个元素中,特别是在一个孩子h2...

var carNameNode = dataNode.SelectSingleNode(".//h2/a");
string carName = carNameNode.InnerText.Trim();

由于 HTML 中可怕的标记,汽车的价格是最困难的。

它位于一个 font 元素内,而该元素又位于另一个 div...

var carPriceNode = dataNode.SelectSingleNode(".//div[@class='results-data-price-btn']/font");
string carPrice = carPriceNode.InnerText.Trim(); // this will give you AED 24,500. Perform some logic to split that up so you just have the number...a

问题是价格在一个元素中被粘在一起为“AED 24,500”。因此,您可以轻松获取元素,但如果您只想要数字,那是您需要自己弄清楚的逻辑。

图像本身很好。这是标记的一个级别,在carResult 下作为一个孩子备份,所以我们继续前进......:

var carImageNode = carResult.SelectSingleNode(".//div[@class='search-results-img']/descendant::img");
string carImageSource = carImageNode.GetAttributeValue("src", string.Empty);

重新编辑

所有“关于这辆二手车的更多详细信息”信息都集中在一个地方,因此以下内容适用于您的示例,但可能不适用于所有示例:

var descriptionNode = rootNode.SelectSingleNode("//div[@id='description']");

var entireDescription = descriptionNode.InnerText.Trim();

var splitUpDescriptionParts =
    entireDescription.Split(
        new[]
            {
                "More Details about this Used Car:", "Body Condition:", "Mechanical Condition:", "Doors:", "Cylinders:", "Body Style:",
                "Drive Type:", "Warrenty:", "Description:"
            },
        StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).Where(s => !string.IsNullOrWhiteSpace(s));

string bodyCondition = splitUp.First();
string mechancialCondition = splitUp.ElementAt(1);
string amountOfDoors = splitUp.ElementAt(2);
string amountOfCylinders = splitUp.ElementAt(3);
string bodyStyle = splitUp.ElementAt(4);
string driveType = splitUp.ElementAt(5);
string warranty = splitUp.ElementAt(6);
string description = splitUp.Last();

【讨论】:

  • 这给了我“对象引用未设置为对象的实例。”在 foreach 循环中
  • 查看我的编辑,周围 div 上的类名实际上在末尾有一个空格,因此它找不到任何东西,所以我更改了顶部的 XPath 以强制它剥离首先是类名的空格。
  • 您的意思是获取“查看详细信息”链接并在浏览器中打开该链接还是仅获取该链接?
  • 我想从“查看详细信息”链接中读取信息,就像我在此页面中所做的那样......这里是 html jsfiddle.net/wQrn9
  • 您需要页面中的哪些确切详细信息?让我知道,我也会更新我的答案。
猜你喜欢
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 2013-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多