如何用Scrapy提取指定Div下数量不定的<p>标签并保存到CSV
Scrapy爬取不定数量
标签并完整保存到CSV
问题场景
使用Scrapy爬取网页时,需要提取指定class的<div>下数量不定的<p>标签内容(1个到10+个不等),希望将所有<p>内容存入一个变量,和其他数据一起保存到CSV,但当前代码仅能保存最后一个<p>的内容。
当前代码存在的问题:
divs = response.xpath('/html/body/div[6]/div/section[2]/article/div/div/div') for p in divs.xpath('.//p'): # extracts all <p> inside print(p.get()) story = p yield { 'story': story }
循环中每次将p赋值给story,循环结束后story仅保留最后一个<p>对象,导致CSV只写入最后一条内容。
解决方法
1. 核心思路
- 先收集所有有效
<p>的内容,而非逐个覆盖变量 - 优化XPath定位方式,避免脆弱的绝对路径
- 将收集到的内容合并为单个字符串(或列表)后再yield
2. 修改后的代码
# 用class定位目标div,比绝对路径更稳定可靠 target_div = response.xpath('//div[@class="div_name"]') if target_div: # 初始化列表存储有效段落 story_content = [] for p in target_div.xpath('.//p'): # 提取p标签的文本,自动去除前后空白、合并内部空格 paragraph_text = p.xpath('normalize-space(.)').get() # 过滤空内容(包括 转成的\xa0) if paragraph_text and paragraph_text != '\xa0': story_content.append(paragraph_text) # 用换行符拼接所有有效段落,形成完整内容 full_story = '\n'.join(story_content) else: # 没有找到目标div时赋值为空字符串 full_story = '' # 输出到CSV,可同时添加其他字段 yield { 'story': full_story, 'title': target_div.xpath('.//h2[@class="h5"]/text()').get(default='') }
3. 代码细节说明
normalize-space(.):Scrapy XPath内置函数,处理文本时会自动去除前后空白字符,合并内部的多个空格/换行,同时将 转换为Unicode的\xa0,方便后续过滤。- 空内容过滤:避免将无意义的空行(比如仅含
或<br>的段落)存入CSV,保证数据整洁。 - 换行符拼接:CSV单元格支持换行,用
\n拼接后,在Excel等工具中打开时可自动换行显示;如果需要其他分隔符,可替换为' '(空格)或'|'等。
4. 保留原始HTML格式的可选方案
如果需要保留<p>标签的原始HTML结构(比如<br>换行),可以直接拼接每个<p>的HTML代码:
target_div = response.xpath('//div[@class="div_name"]') story_html = ''.join(p.get() for p in target_div.xpath('.//p')) if target_div else '' yield { 'story': story_html, 'title': target_div.xpath('.//h2/text()').get(default='') }
内容的提问来源于stack exchange,提问作者NoobDev
相关产品推荐
相关产品推荐

