You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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可能已经找不到元素。建议:

  1. 打开OLX历史书籍列表页,右键任意商品标题→检查元素
  2. 查看当前商品链接的真实选择器(比如现在可能是a[data-cy="listing-ad-title"])
  3. 替换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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:04:48