[英]Selecting text from some elements inside a div and ignore other elements. HTML Agility Pack
我正在尝试为新闻网站构建一个网络抓取工具。 我在选择相关文本时遇到问题,因为文本被分成多个不同的元素。 我正在使用 HTML Agility Pack 并且我尝试从主 div 中选择文本 ( //text() ),但是当我这样做时,我得到了很多我不想要的垃圾文本,比如 javascript 代码。 如何从某些嵌套元素中选择文本并忽略其他元素?
<div class="texto_container paywall"> Some text I want <a href="https://www.sabado.pt/sabermais/ana-gomes" target="_blank" rel="noopener"> Text I want </a> sample of text I want <em> another text i want </em> <aside class="multimediaEmbed contentRight"> A lot of nested elements here with some text I dont want </aside> <div class="inContent"> A lot of nested elements here with some text I don't want </div> Back to the text I want! <twitter-widget class="twitter-tweet twitter-tweet-rendered" id="twitter-widget-0" > Don't want any of this text located in nested elements! </twitter-widget> <p> Final revelant text i want to collect! </p> </div>
编辑
我尝试使用 XPath 排除我不想要的标签,但我仍然从结果中的这些标签中获取文本节点。
var parse_me = htmlDoc.DocumentNode.SelectNodes("//div[@class='texto_container paywall']//text()[not(parent::aside)][not(parent::div[@class='inContent'])][not(parent::twitter-widget)]");
我认为这段代码不起作用,因为在标签上我不想包含文本父节点不是“主要”标签,因为它在很多嵌套标签内。
编辑
经过一些思考和研究,我通过使用ancestor::而不是parent::解决了之前的问题,并且我摆脱了一些预期的文本。 但是我仍然无法摆脱twitter-widget文本,因为即使使用从 Google Chrome 检查元素工具复制的 XPath,它也总是返回一个空节点。
var Twitter_Node = htmlDoc.DocumentNode.SelectSingleNode("//*[@id='twitter - widget - 0']");
这将返回为 null。 这怎么可能? XPath 是从 Chrome 复制的。
您可以尝试从特定标签中排除文本:
//body//text()[not(parent::aside)][not(parent::div[@class="inContent"])][not(parent::twitter-widget)]
您可以使用 concat 但它更复杂,因为您必须知道“链”中每个标签的数量和位置:
concat(//body//div[@class="texto_container paywall"]/text()[1],//body//a[@href]/text(),//body//div[@class="texto_container paywall"]/text()[2],//body//em/text(),//body//div[@class="texto_container paywall"]/text()[5],//body//p/text())
我正在使用ScrapySharp
nuget,它添加到我下面的示例中,(HtmlAgilityPack 可能提供了相同的功能,我几年前就习惯了 ScrapySharp)
您可以简单地准时提取您不想要的所有文本,然后用空字符串替换它们在主 div 文本中的出现,将它们从最终结果中删除。
var doc = new HtmlDocument();
doc.Load(@"C:\Desktop\z.html"); //I created an html with your sample HTML set as the html body
List<string> textsIWant = new List<string>();
var textsIdoNotWant = new List<string>();
//text I do not want
var aside = doc.DocumentNode.CssSelect(".multimediaEmbed.contentRight").FirstOrDefault();
if (aside != null)
{
textsIdoNotWant.Add(aside.InnerText);
}
var inContent = doc.DocumentNode.CssSelect(".inContent").FirstOrDefault();
if (inContent != null)
{
textsIdoNotWant.Add(inContent.InnerText);
}
var twitterWidget = doc.DocumentNode.CssSelect("#twitter-widget-0").FirstOrDefault();
if (twitterWidget != null)
{
textsIdoNotWant.Add(twitterWidget.InnerText);
}
var div = doc.DocumentNode.CssSelect(".texto_container.paywall").FirstOrDefault();
if (div != null)
{
var text = div.InnerText;
foreach (var textIDoNotWant in textsIdoNotWant)
{
text = text.Replace(textIDoNotWant, string.Empty);
}
textsIWant.Add(text);
}
foreach (var text in textsIWant)
Console.WriteLine(text);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.