我正试图为一个新闻网站建立一个网络抓取工具。由于文本被划分为多个不同的元素,所以我在选择相关文本时遇到了问题。我正在使用HTML敏捷包,我尝试从主div中选择text ( // 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)]");我认为这段代码不起作用,因为在标记上,我不想包含文本父节点不是“主”标记,因为它在许多嵌套标记中。
编辑
经过一些思考和研究,我通过使用祖先::来解决前面的问题,而不是使用父母::和我去掉了一些预期的文本。但是,我仍然无法摆脱twitter-widget文本,因为它总是返回一个空节点,即使XPath是从工具复制的。
var Twitter_Node = htmlDoc.DocumentNode.SelectSingleNode("//*[@id='twitter - widget - 0']");这将作为null返回。这怎麽可能?XPath是从Chrome复制的。
发布于 2020-03-09 02:30:05
您可以尝试从特定的标记中排除文本:
//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())发布于 2020-03-09 10:55:32
我使用的是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);

https://stackoverflow.com/questions/60593713
复制相似问题