You need to enable JavaScript to run this app. Kimurai搭配selenium_chrome爬取Loblaws搜索页结果异常
优惠活动
大模型
产品
解决方案
定价
更多

Kimurai搭配selenium_chrome爬取Loblaws搜索页结果异常

Loblaws站点抓取稳定性异常修复方案

核心异常根因定位

  • 硬编码sleep等待完全不匹配动态渲染的实际节奏
    你当前使用固定sleep 30的逻辑,本质是不管页面是否完成商品列表渲染,到时间就开始提取DOM。但Loblaws搜索页是React驱动的异步渲染结构:主框架HTML返回后,商品列表数据是后续通过接口异步拉取、再动态渲染到DOM的,这个渲染过程的耗时受IP信誉、站点风控策略、网络波动影响极大,固定等待完全覆盖不了这种不确定性。从你贴的日志看,页面get请求在19:40:20就完成了,后续30秒等待的时间里,站点很可能返回的是不带商品数据的风控空壳页,这种情况下哪怕等300秒也取不到目标节点。
  • XPath选择器写法存在根本性错误
    你当前写的选择器都是全局绝对路径写法,哪怕节点正常加载出来也会取值错误:
    • 循环块内取商品名的逻辑,没有在当前循环的result节点下做相对查找,直接用全局路径//span[@class='product-name product-name--product-tile'],哪怕进了循环,取的也是全页面第一个商品的名字,不是当前循环项的内容
    • 价格选择器写死了节点位置li[1],不管循环到第几个商品,取的永远是页面第一个列表项里的价格
  • 基础反爬绕过能力不足
    当前配置的UA是2018年的老版本Firefox标识,加上原生headless Chrome的默认特征暴露,站点很容易把请求判定为机器人访问,直接返回不带商品数据的空壳页——这也是为什么只有10%的请求能拿到正常数据,剩下90%都是被风控拦截后的空响应。

代码修复具体操作

用显式等待替代硬编码sleep

不要用无意义的固定等待,替换成Selenium原生的显式等待,等到商品列表节点真的出现在DOM里再开始解析,既缩短整体请求耗时,又能保证节点加载完成:

def parse(response, url:, data: {})
  # 最多等待20秒,每隔0.5秒检查一次目标节点是否加载完成
  wait = Selenium::WebDriver::Wait.new(timeout: 20, interval: 0.5)
  wait.until { 
    browser.find_elements(:xpath, "//li[@class='product-tile-group__list__item']").any?
  }

  # 检查节点是否真的加载完成,空结果直接抛出错误
  product_nodes = browser.find_elements(:xpath, "//li[@class='product-tile-group__list__item']")
  if product_nodes.empty?
    # 保存当前页面源码用于排查风控问题
    save_to "debug/loblaws_#{Time.now.to_i}.html", browser.page_source
    raise "未检测到商品列表节点,疑似触发站点风控"
  end

  product_nodes.each do |result|
    item = {}
    # 改为当前循环节点下的相对XPath,避免取错值
    item[:name] = result.find(:xpath, ".//span[@class='product-name product-name--product-tile']")&.text&.squish
    item[:price] = result.find(:xpath, ".//span[contains(@class, 'price__value')]")&.text&.squish
    # 正常存储item数据
    save_to data[:items] ||= [], item
  end
end

调整Kimurai配置降低风控触发概率

替换原有简陋的配置,补全反爬特征隐藏设置:

class FoodsearchSpider < Kimurai::Base 
  @name = 'foodsearch_spider'
  @engine = :selenium_chrome
  @config = {
    # 替换为当前主流版本的Chrome真实UA
    user_agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
    headless_mode: true,
    window_size: [1920, 1080],
    browser: {
      args: [
        '--disable-blink-features=AutomationControlled',
        '--disable-infobars',
        '--start-maximized'
      ]
    }
  }
end

避坑提醒

  • 不要为了提升稳定性无限制加大sleep时长:如果请求被风控拦截,等待再久也拿不到数据,反而会把整体请求耗时拉到超时阈值
  • 绝对不要使用写死层级的绝对XPath(比如从html根节点逐层数到目标div的路径),站点稍微调整页面结构就会直接失效,还容易取错值
  • 遇到拿不到节点的情况,第一时间保存当前页面源码排查:先确认是站点没有返回商品数据,还是自己的选择器写错了,不要盲目调整等待时长

内容的提问来源于stack exchange,提问作者kab0b

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 13:15:01