c# - HtmlAgilityPack 的可见区域有多深?
问题描述
我需要从博客中获取一些帖子。一切顺利,直到我想获得帖子创建日期。它的 DOM 树是:
div class="stories-feed__container"
-> article
-> div class="story__main"
-> div class="story__footer"
-> div class="story__user user"
-> div class="user__info-item"
-> time datetime="date and time in UTC format".
所以我写了代码:
HtmlWeb web = new HtmlWeb();
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc = web.Load("https://pikabu.ru/@serhiy1994");
string postDate = doc.DocumentNode.SelectSingleNode("//div[contains(@class, 'stories-feed__container')]/article[2]/div[contains(@class, 'story__main')]/div[contains(@class, 'story__footer')]/div[contains(@class, 'story__user user')]/div[contains(@class, 'user__info-item')]/time").GetAttributeValue("datetime", "NULL"); // e.g. for the 2nd article on the page
它返回NullReferenceException
. 但是如果你停在“div class="story__user"”级别(例如,
string postDate = doc.DocumentNode.SelectSingleNode("//div[contains(@class, 'stories-feed__container')]/article[2]/div[contains(@class, 'story__main')]/div[contains(@class, 'story__footer')]/div[contains(@class, 'story__user user')]").InnerHtml;
它可以正常工作并返回内部 HTML 代码。所以我认为 HtmlAgilityPack 有类似“最大可见性级别”的东西,你将无法使用更深的降价进行操作。
我是对的还是我编码错了?
原始页面代码在这里:https ://pastebin.com/jFC0XD9C
解决方案
HtmlAgility 将抓取整个网站,无论您想去多深。您可以使用它来找到您正在寻找的项目,因为您不必提供整个路径。
这将搜索整个站点并查找<div>
具有类名的第一个标签user__info-item
。如果有多个标签,您还可以更改SelectSingleNode
为SelectNodes
,然后遍历它们以获取日期。
HtmlWeb web = new HtmlWeb();
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc = web.Load("https://pikabu.ru/@serhiy1994");
var postDate = doc.DocumentNode.SelectSingleNode("//div[@class='user__info-item']/time");
Console.WriteLine(postDate.InnerText);
你的代码有什么问题?
您上面的代码不起作用的原因是因为您缺少另一个 div ' <div class="user__info user__info_left">
'。
如果你这样写你的代码,它就可以工作。
var nodes = doc.DocumentNode.SelectSingleNode("//div[@class='story__main']/div[@class='story__footer']/div[@class='story__user user']/div[@class='user__info user__info_left']/div[@class='user__info-item']/time");
Console.WriteLine(nodes.InnerText);
另一种方式
另一种方法是搜索父 div。找到父标签后,在该标签下搜索以找到您要查找的内容。
var nodes = doc.DocumentNode.SelectNodes("//div[@class='story__user user']");
foreach (HtmlNode node in nodes)
{
// Search within each node using .// notation
var timeNodes = node.SelectSingleNode(".//div[@class='user__info-item']/time");
Console.WriteLine(timeNodes.InnerText);
}
推荐阅读
- webpack - 无法解析项目中的“css-loader”
- javascript - 如何将数据添加到 json-server 数据库中
- python - 是否可以从 image_dataset_from_directory 获取图像名称?
- python - Beautifulsoup:全部替换具有 aria 级别的属性
同级标签 - python - 添加具有其扇区平均值的列
- javascript - 如何下载存储在 express.js 内存中的缓冲区文件?
- javascript - 如何在 Vue CDN 和 Vue-router CDN 中使用 html 模板?
- linux - Linux CentOS - src/app/app.module.ts:18:42 中的错误 - 错误 TS2307: 找不到模块'@app/modules/
- yii2 - 将 TCPDF 与 Yii2 一起使用时,HeadersAlready 已发送错误
- java - 在以 jar/war 运行的 Spring Boot 应用程序中,JAXB 解组非常慢