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

如何使用Scrapy爬取Angular/Vue动态网站?解决会话Cookie丢失问题

解决Scrapy+Selenium爬取JS网站时会话Cookie丢失的问题

我之前也碰到过一模一样的困扰!当用Scrapy结合Selenium处理JS加载的网站时,默认每次启动ChromeDriver都是全新的浏览器会话,之前设置的国家、货币偏好对应的Cookie自然就丢失了。下面分享几个我亲测有效的解决方案:

方案一:复用同一个Selenium浏览器实例

这是最直接的解决办法——不要每次请求都新建driver对象,而是在爬虫启动时初始化一次,所有请求都复用这个实例,这样会话会一直保持,Cookie也不会重置。

举个简单的代码示例:

from scrapy import Spider
from selenium import webdriver
from selenium.webdriver.common.by import By

class MySpider(Spider):
    name = "my_spider"
    start_urls = ["https://example.com"]

    def __init__(self):
        # 初始化一次driver,整个爬虫过程复用
        self.driver = webdriver.Chrome()
        # 先完成国家/货币选择的初始化操作
        self.driver.get(self.start_urls[0])
        # 模拟选择操作(示例:找到下拉框并选择目标选项)
        # country_select = self.driver.find_element(By.ID, "country-select")
        # country_select.click()
        # target_option = self.driver.find_element(By.XPATH, "//option[@value='US']")
        # target_option.click()
        # 完成操作后,偏好Cookie已存入当前会话

    def parse(self, response):
        # 用同一个driver访问后续页面,Cookie会自动保留
        self.driver.get("https://example.com/next-page")
        # 提取渲染后的HTML
        rendered_html = self.driver.page_source
        # 用Scrapy Selector处理渲染后的内容
        selector = Selector(text=rendered_html)
        # ... 你的解析逻辑

    def closed(self, reason):
        # 爬虫关闭时记得销毁driver,避免残留进程
        self.driver.quit()

方案二:手动同步Scrapy与Selenium的Cookie

如果因为某些原因必须使用多个driver实例,或者需要Scrapy的请求和Selenium共享Cookie,可以手动同步两边的Cookie:

从Selenium同步到Scrapy

当你用Selenium完成国家/货币设置后,提取当前会话的Cookie,然后在Scrapy的Request中带上这些Cookie:

# 在Selenium操作完成后获取Cookie
selenium_cookies = self.driver.get_cookies()
# 转换成Scrapy能识别的键值对格式
scrapy_cookies = {cookie['name']: cookie['value'] for cookie in selenium_cookies}

# 后续Scrapy请求带上这些Cookie
yield scrapy.Request(
    url="https://example.com/target-page",
    cookies=scrapy_cookies,
    callback=self.parse_target
)

从Scrapy同步到Selenium

如果Scrapy已经有了会话Cookie,也可以把它们添加到Selenium的driver中:

# 假设scrapy_cookies是Scrapy请求中获取的Cookie字典
for name, value in scrapy_cookies.items():
    self.driver.add_cookie({
        'name': name,
        'value': value,
        'domain': '.example.com',  # 注意要设置目标网站的正确域名
        'path': '/'
    })

方案三:自定义Scrapy下载中间件集成Selenium

如果你的爬虫有大量需要JS渲染的请求,推荐写一个自定义的Downloader Middleware,统一处理JS渲染,并且复用同一个driver实例,这样Cookie会自动在整个爬虫会话中保留。

大致的中间件结构:

from scrapy import signals
from scrapy.http import HtmlResponse
from selenium import webdriver
from selenium.webdriver.common.by import By

class SeleniumMiddleware:
    def __init__(self):
        self.driver = webdriver.Chrome()
        # 提前完成国家/货币偏好初始化
        self.driver.get("https://example.com")
        # ... 完成偏好设置操作

    @classmethod
    def from_crawler(cls, crawler):
        middleware = cls()
        crawler.signals.connect(middleware.spider_closed, signal=signals.spider_closed)
        return middleware

    def process_request(self, request, spider):
        # 只处理标记了需要JS渲染的请求
        if request.meta.get('render_js', False):
            self.driver.get(request.url)
            # 返回渲染后的HTML作为Response给Scrapy
            return HtmlResponse(
                self.driver.current_url,
                body=self.driver.page_source,
                encoding='utf-8',
                request=request
            )
        return None

    def spider_closed(self, spider):
        self.driver.quit()

然后在settings.py中启用这个中间件:

DOWNLOADER_MIDDLEWARES = {
    'myproject.middlewares.SeleniumMiddleware': 800,
}

调试小技巧

  • 可以在代码中打印self.driver.get_cookies(),确认是否包含国家/货币相关的Cookie字段;
  • 手动在浏览器中完成偏好设置后,查看开发者工具的Cookie面板,记下对应的Cookie名称,方便在代码中验证是否正确保留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:02:49