Scrapy爬虫代码组织问题:同时处理详情页请求与翻页
问题解决方案
一、用Scrapy原生请求的思路完全合理
这才是Scrapy的标准用法,绝对比用requests.get()靠谱。用requests会脱离Scrapy的异步调度框架,浪费它自带的自动去重、失败重试、中间件拦截等核心功能,完全没必要舍本逐末。
二、同时实现Item入库与翻页的代码调整方法
Scrapy的parse方法可以同时yield Item对象和Request对象,框架会自动处理:碰到Item就交给Pipeline,碰到Request就加入调度队列等待执行。直接看具体实现:
1. 标准代码示例
import scrapy from your_project.items import NewsItem class NewsSpider(scrapy.Spider): name = 'news_spider' start_urls = ['https://example.com/news/list'] # 替换成你的起始列表页 def parse(self, response): # 第一步:解析当前列表页的新闻详情链接,生成详情页请求 news_links = response.css('div.news-item a::attr(href)').getall() for link in news_links: # 处理相对URL,指定详情页解析的回调函数 yield scrapy.Request( url=response.urljoin(link), callback=self.parse_detail ) # 第二步:解析下一页链接,生成翻页请求 next_page = response.css('a.next-page::attr(href)').get() if next_page: yield scrapy.Request( url=response.urljoin(next_page), callback=self.parse # 翻页后还是调用parse解析新的列表页 ) def parse_detail(self, response): # 解析详情页数据,生成Item并yield,自动进入Pipeline item = NewsItem() item['title'] = response.css('h1.news-title::text').get().strip() item['content'] = ''.join(response.css('div.news-content p::text').getall()).strip() item['publish_time'] = response.css('span.publish-time::text').get().strip() # 其他字段按需添加 yield item
2. 确保Pipeline生效的关键配置
- 在
settings.py中开启Pipeline(不要注释掉):
ITEM_PIPELINES = { 'your_project.pipelines.NewsPipeline': 300, # 数字是执行优先级,越小越先跑 }
- 确认
items.py中的Item类定义正确:
import scrapy class NewsItem(scrapy.Item): title = scrapy.Field() content = scrapy.Field() publish_time = scrapy.Field() # 其他需要的字段
3. 常见问题排查
- Item没进Pipeline:检查
ITEM_PIPELINES配置是否正确,Item是否正确实例化并yield,有没有中间件拦截了Item。 - 翻页失效:检查下一页的CSS/XPath选择器是否精准,是否用
response.urljoin()处理了相对URL,确认目标网站最后一页确实有下一页按钮。
内容的提问来源于stack exchange,提问作者kingswanwho
相关产品推荐
相关产品推荐

