【问题标题】:accessing li and ul elements in html在 html 中访问 li 和 ul 元素
【发布时间】:2022-08-17 00:20:02
【问题描述】:

我想从下面的结构中提取文本。

selector = scrapy.Selector(text=\"\"\"
<li>Text1
  <ul>
    <li>Text2</li>
    <li>Text3</li>
    <li><class=\"a\">
      <i>Text4</i>
        Text5 
        <a href=\"href1\" title=\"Title1\"> Text6</a>.
      </cite>
      <span class=\"b\" title=\"Title2\">
        <span style=\"Style1\"></span>
      </span>
    </li>
    <li>
      Text7 
      <cite style=\"Style2\" class=\"a\">
        <i>Text8</i>
        Text9
        <a href=\"href2\" title=\"Title2\">Text10</a>.
      </cite>
      <span class=\"b\" title=\"Title3\">
        <span style=\"Style3\"></span>
      </span>
    </li>
  </ul>
</li>
\"\"\")

这段代码给了我所有的文本,包括新行,但失去了 html 的所有结构。

selector.xpath(\'/descendant-or-self::*/text()\').extract()  

以下选项仅提供空列表。

selector.xpath(\'/li//text()\').extract() 
selector.xpath(\'/li//text()\').extract()
selector.xpath(\'/li\').extract()
selector.xpath(\'/li/ul/*\').extract()
selector.xpath(\'/li/ul/li\').extract()   

有没有办法通过某种路径访问这些元素?

  • - 哪个元素?
  • 所有文本元素,参见。标题。

标签: python html scrapy


【解决方案1】:

提到的查询会给你空列表,因为当你使用 Selector 时,scrapy 选择器会添加 htmlbody 标签,你有 2 个选项来修复它:

在路径中添加 html 和 body 标签

selector.xpath('/html/body/li//text()').extract() 
selector.xpath('/html/body/li//text()').extract()

或者您可以使用相对 xpath 选择器//

selector.xpath('//li//text()').extract() 
selector.xpath('//li//text()').extract()

【讨论】:

    【解决方案2】:

    由于您的预期输出不清楚,因此假设您要从顶部 li 标记和 ul/li 标记中提取字符串/文本节点。

    以下 xpath 表达式将从顶部 li 标记中选择文本

    el =''.join(selector.xpath('//*[@class="a"]/ancestor::li/text()').extract()).replace('\n','').strip()
    txt = re.sub(r'\s+',' ',el)
    

    sel =' '.join(selector.xpath('//*[@class="a"]/ancestor::ul//li//text()').extract()).replace('\n','').strip()
    
    txt2 = re.sub(r'\s+',' ',sel)
    

    上面的路径表达式将从ul/li标签中选择文本

    P/S:我使用re 模块仅用于删除多余的空格

    通过scrapy shell证明:

    In [1]: from scrapy import Selector
    
       ...:         <span style="Style3"></span>
       ...:       </span>
       ...:     </li>
       ...:   </ul>
       ...: </li>
       ...: """)
       ...: 
       ...: el =''.join(selector.xpath('//*[@class="a"]/ancestor::li/text()').extract()).replace('\n','').strip()       
    
    In [3]: el
    Out[3]: 'Text1        Text7'
    
    In [4]: import re
    
    In [5]: txt = re.sub(r'\s+',' ',el)
    
    In [6]: txt
    Out[6]: 'Text1 Text7'
    
    In [7]: sel =' '.join(selector.xpath('//*[@class="a"]/ancestor::ul//li//text()').extract()).replace('\n','').strip( 
       ...: )
    
    In [8]: sel
    Out[8]: 'Text2 Text3        Text4         Text5                    Text6 .                                         Text7                 Text8         Text9         Text10 .'
    
    In [9]: txt2 = re.sub(r'\s+',' ',sel)
    
    In [10]: txt2
    Out[10]: 'Text2 Text3 Text4 Text5 Text6 . Text7 Text8 Text9 Text10 .'
    

    【讨论】: