You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scrapy Selector在for循环中仅获取首个匹配元素的问题求解

问题原因
  • 外层迭代逻辑有误:sel.xpath('//body')只会匹配到文档中唯一的1个<body>节点,因此for循环总共只会执行1次,不可能逐行输出3个值。
  • 结果提取方法使用错误:在body节点上执行.//li/p[1]/text()确实能匹配到3个目标文本节点(对应内容1、4、7),但.get()方法的设计逻辑就是仅返回匹配结果集的第一个元素,其余结果会被直接忽略,自然拿不到后面的4和7。
解决方法

两种常用实现方案,按需选择即可:

方案1:调整外层循环选择粒度,遍历所有li节点

把外层选择器改成匹配所有<li>节点,每个li节点内部单独取第一个<p>的文本,这样循环会执行3次,每次拿到一个目标值:

from scrapy.selector import Selector

body = '''<html>
<body>
  <li>
    <p>1</p>
    <p>2</p>
    <p>3</p>
  </li>
  <li>
    <p>4</p>
    <p>5</p>
    <p>6</p>
  </li>
  <li>
    <p>7</p>
    <p>8</p>
    <p>9</p>
  </li>
</body>
</html>'''

sel = Selector(text=body, type="html")

# 外层遍历所有li节点
for elem in sel.xpath('//body/li'):
    first = elem.xpath('./p[1]/text()').get()
    print(first)

方案2:保留body层级遍历,用getall()取出所有结果再迭代

如果确实需要在body节点上做提取,把.get()换成.getall()拿到所有匹配的文本列表,再遍历列表打印即可:

from scrapy.selector import Selector

body = '''<html>
<body>
  <li>
    <p>1</p>
    <p>2</p>
    <p>3</p>
  </li>
  <li>
    <p>4</p>
    <p>5</p>
    <p>6</p>
  </li>
  <li>
    <p>7</p>
    <p>8</p>
    <p>9</p>
  </li>
</body>
</html>'''

sel = Selector(text=body, type="html")

for elem in sel.xpath('//body'):
    # getall()返回所有匹配结果组成的列表
    first_p_list = elem.xpath('.//li/p[1]/text()').getall()
    for text in first_p_list:
        print(text)

补充说明:Scrapy Selector中,.get()是.extract_first()的别名,永远只返回匹配到的第一个结果;.getall()是.extract()的别名,会返回全部匹配结果组成的列表,日常编码可根据需求选择。

内容的提问来源于stack exchange,提问作者Rivaille

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 03:54:22