Python中scrapy如何对接selenium进行动态网页爬取?

单纯用 selenium 爬取数据,效率 真的是慢。但是逆向 js 又搞不定,就想着用 scrapy+selenium+redis,做成分布式,提高爬取效率。请问大佬们,有实现方式吗?或者, 有没有项目可以参考看下。
万分感谢
Python中scrapy如何对接selenium进行动态网页爬取?

13 回复

selenium 会破坏 scrapy 的异步性吧?感觉快不了多少。如果真的要配合 selenium 的话,可以在下载中间件中用,返回 response 对象,绕开默认下载器


在Scrapy里整合Selenium来处理动态加载页面,核心思路是用Selenium的WebDriver替换Scrapy默认的下载器中间件。下面是一个可以直接跑的方案:

首先装好依赖:

pip install scrapy selenium

然后创建middlewares.py,写个自定义中间件:

from scrapy.http import HtmlResponse
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time

class SeleniumMiddleware:
    def __init__(self):
        chrome_options = Options()
        chrome_options.add_argument('--headless')  # 无头模式
        chrome_options.add_argument('--no-sandbox')
        self.driver = webdriver.Chrome(options=chrome_options)
    
    def process_request(self, request, spider):
        if request.meta.get('selenium'):
            self.driver.get(request.url)
            time.sleep(2)  # 等JS加载
            html = self.driver.page_source
            return HtmlResponse(url=request.url, body=html, encoding='utf-8', request=request)

settings.py里启用这个中间件,并调整下载延迟:

DOWNLOADER_MIDDLEWARES = {
    'your_project.middlewares.SeleniumMiddleware': 543,
}
DOWNLOAD_DELAY = 2

最后在爬虫里标记需要Selenium处理的请求:

class MySpider(scrapy.Spider):
    name = 'dynamic_spider'
    
    def start_requests(self):
        yield scrapy.Request(
            url='https://example.com',
            meta={'selenium': True},  # 触发Selenium处理
            callback=self.parse
        )
    
    def parse(self, response):
        # 现在response包含JS渲染后的完整HTML
        yield {'html': response.text}

记得在爬虫关闭时关掉WebDriver,可以在爬虫里加:

def close(self, reason):
    self.crawler.engine.downloader.middleware.driver.quit()

这样就能用Scrapy+Selenium抓动态内容了。简单说就是让Selenium渲染页面,再把HTML塞回Scrapy的响应流里继续处理。

和 scrapy 配合使用的好像都是 splash

我的经验是尽可能逆向 js,直接抓最根本的请求,效率巨高
或者用 js 渲染库,scapy 不清楚,requests 和 js 有渲染库的

其实逆向 js 很简单的,js 要么 xhr,要么内置 url 都很好找的

middle 里面换掉

试过了,因为需要翻页,splash 无法解决

逆向 js 后的效率,的确会高很多。但是我对 js 语言不是很熟悉,一看到长串的 js,就感觉没头绪。。。

效率上应该不会快太多。我是想做成分布式,开 2-4 个 driver 来做,这样比单纯的 selenium 要快一些

试一下了。。

翻页直接抓包啊,八成是 xhr 实现的

可以直接把 JS 下载回来。python 载入然后解密呀。这样你只需要找到 js 的加解密函数就可以了呀。

selenium 保存 cookies 后传给 scrapy,等再需要 selenium 上场时 scrapy 再把 cookies 传回来。

回到顶部