首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从div中的某些元素中选择文本,忽略其他元素。HTML敏捷包

从div中的某些元素中选择文本,忽略其他元素。HTML敏捷包
EN

Stack Overflow用户
提问于 2020-03-09 01:31:33
回答 2查看 362关注 0票数 0

我正试图为一个新闻网站建立一个网络抓取工具。由于文本被划分为多个不同的元素,所以我在选择相关文本时遇到了问题。我正在使用HTML敏捷包,我尝试从主div中选择text ( // text () ),但是当我这样做时,我得到了很多我不想要的垃圾文本,比如javascript代码。如何从一些嵌套元素中选择文本而忽略其他元素?

代码语言: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来排除我不想要的标记,但是我仍然从结果中的那些标记中获得文本节点。

代码语言:javascript
复制
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是从工具复制的。

代码语言:javascript
复制
var Twitter_Node = htmlDoc.DocumentNode.SelectSingleNode("//*[@id='twitter - widget - 0']");

这将作为null返回。这怎麽可能?XPath是从Chrome复制的。

EN

回答 2

Stack Overflow用户

发布于 2020-03-09 02:30:05

您可以尝试从特定的标记中排除文本:

代码语言:javascript
复制
//body//text()[not(parent::aside)][not(parent::div[@class="inContent"])][not(parent::twitter-widget)]

您可以使用concat,但它更复杂,因为您必须知道“链”中每个标记的数字和位置:

代码语言:javascript
复制
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())
票数 0
EN

Stack Overflow用户

发布于 2020-03-09 10:55:32

我使用的是ScrapySharp nuget,它添加了下面的示例(可能HtmlAgilityPack提供了构建它的相同功能,我只是多年前就习惯了ScrapySharp )。

您可以只需准时提取所有不想要的文本,然后用空字符串替换它们在主div文本中的出现,从最终结果中删除它们。

代码语言:javascript
复制
    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);

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60593713

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档