导读:本期聚焦于小伙伴创作的《如何使用Scrapy和XPath高效抓取div中可变数量的p标签并合并存储》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何使用Scrapy和XPath高效抓取div中可变数量的p标签并合并存储》有用,将其分享出去将是对创作者最好的鼓励。

在Scrapy爬虫开发中,经常会遇到目标数据分散在同一个div标签下的多个p标签中,且p标签的数量会根据页面内容动态变化的情况。如果使用固定索引的方式提取p标签内容,当页面p标签数量变化时就会出现提取不全或者报错的问题,结合XPath的批量提取能力可以很好地解决这个问题。

如何使用Scrapy和XPath高效抓取div中可变数量的p标签并合并存储

场景说明

假设我们要抓取的页面结构如下,div的类名为content-wrap,内部包含数量不定的p标签,每个p标签存放一段文本,我们需要把所有p标签的文本合并成一个完整的段落存储:

<div class="content-wrap">
    <p>第一段文本内容</p>
    <p>第二段文本内容</p>
    <p>第三段文本内容</p>
    <!-- 可能还有更多p标签 -->
</div>

XPath提取所有p标签的核心语法

XPath提供了通配符和后代节点选择的能力,我们可以通过以下路径快速选中目标div下的所有p标签:

  • 首先定位到类名为content-wrap的div节点://div[@class="content-wrap"]
  • 再选择该div下的所有p标签后代节点://div[@class="content-wrap"]//p
  • 提取所有p标签的文本内容://div[@class="content-wrap"]//p/text()

这个XPath表达式不需要关心p标签的数量,不管div下有多少个p标签,都会返回所有p标签的文本组成的列表。

Scrapy中的实现步骤

1. 编写Spider提取逻辑

在Scrapy的Spider文件中,我们可以通过response对象的xpath方法执行上述XPath表达式,然后处理返回的列表:

import scrapy

class ContentSpider(scrapy.Spider):
    name = "content_spider"
    start_urls = ["http://ipipp.com/sample_page"]  # 替换为实际目标页面地址

    def parse(self, response):
        # 提取所有p标签的文本内容,返回的是包含多个字符串的SelectorList
        p_text_list = response.xpath('//div[@class="content-wrap"]//p/text()').getall()
        # 过滤空字符串,避免无意义的空白内容
        valid_text_list = [text.strip() for text in p_text_list if text.strip()]
        # 合并所有文本,用换行符分隔
        merged_content = "n".join(valid_text_list)
        # 构造返回的数据字典
        yield {
            "page_url": response.url,
            "merged_content": merged_content
        }

2. 代码逻辑说明

上述代码的核心逻辑分为三步:

  • 使用getall()方法获取XPath匹配到的所有文本内容,得到一个字符串列表,不管p标签数量多少都会全部返回
  • 对列表中的每个文本做去空白处理,过滤掉只有空格或者换行的无效内容
  • 使用join()方法把过滤后的文本列表合并成一个字符串,这里用换行符分隔,也可以根据需求换成其他分隔符比如空格

3. 数据存储配置

如果需要把合并后的数据存储到文件或者数据库,只需要在Scrapy的Pipeline中处理即可,以下是存储到JSON文件的简单示例:

import json

class JsonPipeline:
    def open_spider(self, spider):
        # 打开文件准备写入
        self.file = open("result.json", "w", encoding="utf-8")

    def process_item(self, item, spider):
        # 把item转成json字符串写入文件
        line = json.dumps(dict(item), ensure_ascii=False) + "n"
        self.file.write(line)
        return item

    def close_spider(self, spider):
        self.file.close()

然后在settings.py中启用这个Pipeline:

ITEM_PIPELINES = {
    "your_project_name.pipelines.JsonPipeline": 300,
}

注意事项

  • 如果目标div的类名可能有多个,比如class="content-wrap other-class",可以使用contains()函数修改XPath://div[contains(@class, "content-wrap")]//p/text()
  • 如果p标签内部还有子标签比如span,直接提取text()可能只会拿到部分文本,这时可以改用//div[@class="content-wrap"]//p//text()提取p标签下所有后代节点的文本
  • 合并文本的分隔符可以根据实际需求调整,比如需要拼接成连贯段落就使用空格分隔,需要保留段落结构就用换行符分隔
这种方案不需要提前知道p标签的数量,适配所有动态变化的场景,比逐个索引提取的方式更健壮,也能减少很多冗余的判断代码。

ScrapyXPathdiv_p标签抓取p标签合并爬虫数据存储修改时间:2026-06-21 10:24:28

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。