Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 442|回复: 1

xpath 选择某元素之前的所有元素

[复制链接]

19

主题

11

回帖

255

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
255
发表于 2024-6-16 20:17:46 | 显示全部楼层 |阅读模式
需要选择 div 节点下的 p 节点,并且 p 节点需要在 h2 节点之前:
  1. from parsel import Selector

  2. # 假设html_content是你的HTML内容字符串
  3. html_content = '''
  4. <div>
  5.     <p>应被选择的p1</p>
  6.     <p>应被选择的p2</p>
  7.     <h2>标题</h2>
  8.     <p>不应被选择的p3</p>
  9.     <p>不应被选择的p4</p>
  10.     <h2>另一个标题</h2>
  11.     <p>不应被选择的p5</p>
  12.     <p>应被选择的p6</p>
  13. </div>
  14. '''

  15. selector = Selector(text=html_content)

  16. # 使用XPath表达式直接选取符合条件的p标签
  17. selected_p_texts = selector.xpath('//div/p[not(preceding-sibling::h2)]/text()').getall()

  18. # 输出符合条件的p标签文本
  19. for text in selected_p_texts:
  20.     print(text)
复制代码
这段代码中,XPath表达式//div/p[not(preceding-sibling::h2)]/text()的作用是选取所有div下的p元素,这些p元素之前不能有h2元素作为兄弟节点,然后提取这些p元素的文本内容。这样就直接通过XPath实现了你的需求,而无需额外的循环和条件判断。——通义千问
回复

使用道具 举报

19

主题

11

回帖

255

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
255
 楼主| 发表于 2024-6-16 20:25:05 | 显示全部楼层
上面这种方法普适性可能不是很好,有些节点文本的选择不是很方便,最终采用下面的方式:
  1.     @staticmethod
  2.     def parse_re_desc_before_h2(job_resp: requests.Response) -> str:
  3.         """
  4.         解析位于 id=readingAidText 标签下所有的文本
  5.         如果存在 <h2> 标签选择 <h2> 标签前面的元素文本
  6.         采用正则的方式提取 h2 前面元素并重新构建 selector
  7.         """
  8.         reading_aid_text = re.findall('<div.*?id="readingAidText".*?>(.*?)<h2>', job_resp.text, re.S)
  9.         reading_aid_text = reading_aid_text[0] if reading_aid_text else '<div></div>'

  10.         selector = Selector(text=reading_aid_text)

  11.         desc = selector.xpath('//text()').getall()

  12.         return ' '.join(desc).strip()
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|DiscuzX

GMT+8, 2024-10-6 23:28 , Processed in 0.031000 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表