Scrapy结合Splash爬取OLX数据生成JSON为空问题求助
问题排查与解决方案
看起来你的爬虫能正常请求分页页面,但始终没生成任何Item,导致JSON文件为空——核心问题出在列表页处理逻辑、选择器失效以及链接处理这几个环节,下面一步步帮你解决:
1. 修复CrawlSpider的Rule配置,确保所有列表页都被处理
你的当前Rule只把分页链接的回调设为parse_item,但初始的第一页(start_urls对应的页面)并没有被parse_item处理,直接跳过了第一页的商品提取;同时Rule的逻辑也搞反了,分页链接只需要跟进,不需要绑定回调,列表页的商品提取逻辑应该统一处理所有列表页面。
修改livros.py里的Rule和初始请求逻辑:
from scrapy.spiders import CrawlSpider, Rule from scrapy.linkextractors import LinkExtractor from olx.items import OlxItem from scrapy_splash import SplashRequest class LivrosSpider(CrawlSpider): name = 'livros' allowed_domains = ['www.olx.pt'] start_urls = ['https://www.olx.pt/lazer/livros-revistas/historia/'] rules = ( # 提取分页链接,仅跟进,不绑定回调 Rule(LinkExtractor(allow=(), restrict_css=('.pageNextPrev',)), follow=True), # 提取商品详情页链接,交给parse_detail_page处理 Rule(LinkExtractor(allow=(), restrict_css=('.large > .detailsLink',)), callback="parse_detail_page"), ) # 重写start_requests,让初始页面也通过Splash渲染并交给parse_item处理 def start_requests(self): for url in self.start_urls: yield SplashRequest(url, callback=self.parse_item) def parse_item(self, response): # 提取当前列表页的所有商品链接 item_links = response.css('.large > .detailsLink::attr(href)').extract() # 新增日志,确认是否提取到链接 self.logger.info(f"在页面 {response.url} 找到 {len(item_links)} 个商品链接") for a in item_links: # 把相对链接转为绝对链接,否则Splash无法正确请求 absolute_url = response.urljoin(a) yield SplashRequest(absolute_url, callback=self.parse_detail_page, args={'wait': 1.5})
2. 验证并更新CSS选择器
OLX的页面结构大概率已经更新,你用的.large > .detailsLink可能已经找不到元素。建议:
- 打开OLX历史书籍列表页,右键任意商品标题→检查元素
- 查看当前商品链接的真实选择器(比如现在可能是
a[data-cy="listing-ad-title"]) - 替换
parse_item里的选择器,比如:
item_links = response.css('a[data-cy="listing-ad-title"]::attr(href)').extract()
3. 提升详情页解析的健壮性
原代码里用extract()[0]如果找不到元素会直接抛出错误,导致Item无法生成,建议改用extract_first()并添加容错判断:
def parse_detail_page(self, response): title = response.css('h1::text').extract_first() price = response.css('.pricelabel > strong::text').extract_first() # 如果标题或价格不存在,直接跳过该Item if not title or not price: self.logger.warning(f"页面 {response.url} 未找到标题或价格,跳过") return item = OlxItem() item['title'] = title.strip() item['price'] = price.strip() item['url'] = response.url yield item
4. 验证Splash渲染效果
可以打开Splash的web界面(http://localhost:8050),输入OLX列表页URL,查看渲染后的页面是否能看到商品链接。如果渲染后还是看不到内容,需要给SplashRequest增加等待时间,确保JS加载完成:
yield SplashRequest(absolute_url, callback=self.parse_detail_page, args={'wait': 2})
测试建议
修改后运行爬虫时,加上日志等级参数:
scrapy crawl livros -s LOG_LEVEL=DEBUG
如果看到DEBUG: Scraped from <200>的日志,说明Item已经正常生成,JSON文件就不会为空了。如果还是没效果,查看日志里的商品链接数量日志,就能快速定位是选择器问题还是渲染问题。
内容的提问来源于stack exchange,提问作者Azzine
相关产品推荐
相关产品推荐

