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

Scrapy集成Selenium时_init_方法未执行报错如何解决

问题根因

你遇到的问题来自几个明确的代码错误,按影响优先级排序:

  • 最核心的错误是Python构造方法名写错了。Python类的构造方法固定为__init__,方法名前后各需要两个下划线,你写的_init_前后只有一个下划线,本质是个完全不会被自动调用的普通方法。Scrapy实例化爬虫类时只会调用官方定义的构造方法,你写在_init_里的Selenium初始化、页面渲染代码从头到尾没执行,self.html属性根本没被赋值,自然会抛出属性不存在的错误,你加的两条print语句也当然不会输出。
  • 就算改对构造方法名,你现在的写法也会出问题:重写Scrapy Spider子类的构造方法时,必须先调用父类的构造方法,否则Scrapy内置的初始化逻辑(比如配置加载、信号注册、start_urls初始化)会全部失效。
  • 你代码里的部分Selenium API已经在高版本中移除:set_window实际应为set_window_size,find_elements_by_class_name这种旧版定位方法已经被废弃,运行时会直接抛方法不存在的异常。
  • 逻辑层面的小问题:你把Selenium渲染逻辑全写在构造方法里,Scrapy自带的下载器还是会按start_urls发送一次普通HTTP请求,属于无效重复请求;如果后续要爬取多个JS渲染页面,构造方法只会在爬虫启动时执行一次,逻辑完全无法复用。
修复方案
  1. 把构造方法名从_init_修正为__init__,添加可变参数*args, **kwargs,方法第一行调用父类构造方法super().__init__(*args, **kwargs),保证Scrapy自身的初始化逻辑正常执行。
  2. 修正Selenium的废弃API调用,补充必要的页面加载等待,避免元素未加载就点击引发的异常。
  3. 如果只是做简单单页测试,改完上面两点就能正常运行;如果要做批量爬取,建议把Selenium渲染逻辑抽到下载器中间件中,对接Scrapy原生的调度、重试、并发体系,不要硬塞在构造方法里。
修复后可运行代码
import scrapy
from scrapy.selector import Selector
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time

class test_2(scrapy.Spider):
    name = 'test_2'
    start_urls = [
        'https://www.jackjones.in/st-search?q=shoes'
    ]
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        print("test-1")
        chrome_options = Options()
        # 新版Chrome推荐用--headless=new参数启动无头模式
        chrome_options.add_argument("--headless=new")
        # 如果已经把chromedriver配置到系统环境变量,不需要硬写路径
        driver = webdriver.Chrome(options=chrome_options)
        # 修正窗口大小设置方法
        driver.set_window_size(1920, 1080)
        driver.get("https://www.jackjones.in/st-search?q=shoes")
        # 等待列表页商品项加载完成,固定等待仅做演示,生产环境建议用显式等待
        time.sleep(3)
        # 替换为新版Selenium的元素定位写法
        tab = driver.find_elements(By.CLASS_NAME, "st-single-product")
        tab[4].click()
        # 等待点击后的商品详情页渲染完成
        time.sleep(2)

        self.html = driver.page_source
        print("test-2")
        driver.quit()
    
    def parse(self, response):
        print("test-3")
        resp = Selector(text=self.html)
        yield {
            'title': resp.xpath("//h1/text()").get()
        }

补充说明:代码里的time.sleep()是最简单的等待实现,稳定性差且效率低,正式使用建议替换为Selenium的WebDriverWait显式等待,按元素加载状态判断等待时机。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 00:36:17