如何让Scrapy输出所有Item而非仅最后一个?多版代码问题排查
解决Scrapy爬虫导出CSV为空/格式混乱的问题
让我们一步步拆解你遇到的问题,然后给出针对性的修正方案:
你前几次尝试的问题分析
第一次代码的问题
你没有在循环内部初始化item实例,而且在嵌套循环里反复给同一个item的name和photo字段赋值,最终只会保留最后一次循环的结果,所以CSV文件只显示最后一条数据。
第二次代码的问题
你把所有用户名和照片数都用分号拼接成了单个字符串,导致所有会员数据挤在一行里,完全不符合“每条会员一行数据”的预期,自然格式混乱。
第三次代码的核心问题
这一次的问题是多个因素叠加导致的:
- 字段名不匹配:你的
items.py里定义的是photo字段,但代码里误用了item['photos'](多了个s),Scrapy会忽略未在Item类中定义的字段,直接导致导出的CSV为空。 - XPath定位可能偏差:
position() > 1的写法不够可靠,如果网站表头行的结构有变化,就会抓取到错误的内容。 - 反爬拦截:没有设置有效的
USER_AGENT,网站可能返回空内容或者拒绝你的请求,导致爬虫抓不到数据。 - Settings配置缺失:没有正确配置CSV导出的相关参数,Scrapy不知道该如何输出数据。
修正后的完整解决方案
1. 确保items.py字段定义正确
保持你原来的items.py不变,字段名要和后续爬虫代码严格一致:
import scrapy class FinalItem(scrapy.Item): name = scrapy.Field() photo = scrapy.Field()
2. 修正爬虫代码
import scrapy from final.items import FinalItem class ScrapeMembersSpider(scrapy.Spider): name = 'final2' start_urls = ['https://www.trekearth.com/members/'] # 添加模拟浏览器的USER_AGENT,避免被网站反爬拦截 custom_settings = { 'USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } def parse(self, response): # 遍历表格中除表头外的每一行(用表头的class精准跳过,比position更可靠) for row in response.xpath('//table[@class="member-table"]//tr[not(@class="header")]'): item = FinalItem() # 定位用户名:提取td[2]下a标签的文本,去除多余空白 item['name'] = row.xpath('./td[2]//a/text()').extract_first(default='').strip() # 定位照片数:提取td[6]的纯文本,去除空白后只保留数字 raw_photo_count = row.xpath('string(./td[6])').extract_first(default='').strip() item['photo'] = ''.join([c for c in raw_photo_count if c.isdigit()]) if raw_photo_count else '0' # 只输出有有效用户名的数据,避免空行 if item['name']: yield item
3. 配置settings.py的CSV导出
在settings.py中添加或修改以下配置(适用于Scrapy 2.0及以上版本,推荐用FEEDS替代旧的导出方式):
# 配置CSV导出参数 FEEDS = { 'members.csv': { 'format': 'csv', 'encoding': 'utf-8', 'overwrite': True, 'fields': ['name', 'photo'] # 指定要导出的字段,必须和items.py一致 } } # 确保Item Pipeline启用(默认可能是注释状态,取消注释或设置如下) ITEM_PIPELINES = { 'final.pipelines.FinalPipeline': 300, }
关键修正点说明
- 字段名严格统一:爬虫代码中的
item['photo']和items.py的字段名完全匹配,避免Scrapy忽略未定义字段。 - 反爬防护:通过
custom_settings添加真实的浏览器USER_AGENT,模拟正常用户访问,防止网站拒绝请求。 - XPath优化:用
not(@class="header")精准跳过表头行,比position()>1更稳定,适配网站结构的小变化。 - 数据清洗:对抓取到的文本做
strip()处理,去除多余空格和换行;照片数只保留数字部分,避免无效字符干扰。 - 有效数据过滤:只输出有用户名的item,避免生成空数据行。
最后运行爬虫命令:
scrapy crawl final2
你就能得到格式正确的CSV文件,每条会员占一行,包含用户名和对应的照片数量。
内容的提问来源于stack exchange,提问作者Mrowkacala
相关产品推荐
相关产品推荐

