Scrapy结合Selenium实现滚动翻页数据采集

来源:这里教程网 时间:2026-03-02 13:05:50 作者:

引言

在当今的互联网数据采集领域,许多网站采用动态加载技术(如AJAX、无限滚动)来优化用户体验。传统的基于  Requests    Scrapy  的爬虫难以直接获取动态渲染的数据,而  Selenium  可以模拟浏览器行为,实现滚动翻页和动态内容加载。

本文将介绍如何结合  Scrapy  (强大的Python爬虫框架)和  Selenium  (浏览器自动化工具)来高效采集滚动翻页的动态网页数据,并提供完整的代码实现。

1. 技术选型与原理

1.1 Scrapy简介

Scrapy  是一个高效的Python爬虫框架,支持异步请求、数据解析和存储。它适用于静态网页抓取,但对动态渲染的页面(如JavaScript加载的内容)支持有限。

1.2 Selenium简介

Selenium  是一个自动化测试工具,可以模拟用户操作(如点击、滚动、输入等),适用于动态网页的数据采集。

1.3 为什么结合Scrapy和Selenium?

  • Scrapy  负责高效的数据抓取、解析和存储。
  • Selenium  负责模拟浏览器行为,处理动态加载内容。
  • 结合优势  :Scrapy的调度能力 + Selenium的动态渲染能力,适用于复杂动态网页的采集。

    二、环境搭建与工具准备

    在开始实现滚动翻页数据采集之前,我们需要准备好相关的开发环境和工具。

    (一)Python环境

    确保你的系统中已经安装了Python,并且版本不低于3.6。Python是Scrapy和Selenium的基础运行环境,建议使用虚拟环境来管理项目依赖。

    (二)Scrapy框架安装

    Scrapy是一个开源的Python爬虫框架,用于快速构建高效的网页爬虫。

    (三)Selenium工具安装

    Selenium是一个自动化测试工具,能够模拟用户在浏览器中的行为。安装Selenium的Python绑定:

    此外,还需要下载对应浏览器的驱动程序,例如ChromeDriver。根据你的浏览器版本选择合适的驱动程序,并确保其路径可以被Selenium访问。可以将其加入系统的环境变量,或者在代码中指定路径。

    三、Scrapy项目创建与配置

    创建一个新的Scrapy项目,用于实现滚动翻页数据采集。

    (一)项目结构

    Scrapy项目通常具有以下结构:

    scroll_crawler/
        scrapy.cfg
        scroll_crawler/
            __init__.py
            items.py
            middlewares.py
            pipelines.py
            settings.py
            spiders/
                __init__.py
                scroll_spider.py

    (二)配置文件设置

      settings.py  文件中,我们需要进行一些配置,以便Scrapy能够与Selenium协同工作。

    1. 启用Selenium中间件    middlewares.py  文件中,定义一个Selenium中间件,用于在Scrapy请求中嵌入Selenium的浏览器操作。
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from scrapy.http import HtmlResponse
    class SeleniumMiddleware:
        def __init__(self):
            chrome_options = Options()
            chrome_options.add_argument('--headless')  # 无头模式
            self.driver = webdriver.Chrome(options=chrome_options)
        def process_request(self, request, spider):
            self.driver.get(request.url)
            # 模拟滚动翻页操作
            self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            body = self.driver.page_source
            return HtmlResponse(self.driver.current_url, body=body, encoding='utf-8', request=request)
    1. 启用中间件    settings.py  文件中,启用我们刚刚定义的Selenium中间件。
    DOWNLOADER_MIDDLEWARES = {
        'scroll_crawler.middlewares.SeleniumMiddleware': 543,
    }

    四、实现滚动翻页数据采集

      spiders  目录下创建一个爬虫文件  scroll_spider.py  ,用于实现滚动翻页数据采集。

    (一)导入依赖

    import scrapy
    from scrapy.exceptions import CloseSpider
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.common.exceptions import TimeoutException

    (二)定义爬虫类

    import scrapy
    from scrapy.exceptions import CloseSpider
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.common.exceptions import TimeoutException
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.common.proxy import Proxy, ProxyType
    # 代理信息
    proxyHost = "www.16yun.cn"
    proxyPort = "5445"
    proxyUser = "16QMSOML"
    proxyPass = "280651"
    class ScrollSpider(scrapy.Spider):
        name = 'scroll_spider'
        allowed_domains = ['example.com']  # 替换为目标网站域名
        start_urls = ['https://example.com/scroll-page']  # 替换为目标网页URL
        def parse(self, response):
            # 使用Selenium获取动态加载的数据
            driver = response.meta['driver']
            try:
                # 等待页面加载完成
                WebDriverWait(driver, 10).until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, 'div.data-item'))  # 替换为目标数据的选择器
                )
            except TimeoutException:
                raise CloseSpider('页面加载超时')
            # 模拟滚动翻页
            while True:
                # 获取当前页面的数据
                data_items = driver.find_elements(By.CSS_SELECTOR, 'div.data-item')
                for item in data_items:
                    yield {
                        'data': item.text  # 替换为目标数据的提取方式
                    }
                # 滚动到页面底部
                driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
                # 等待新数据加载
                try:
                    WebDriverWait(driver, 5).until(
                        EC.presence_of_element_located((By.CSS_SELECTOR, 'div.data-item.new'))  # 替换为新数据的选择器
                    )
                except TimeoutException:
                    # 如果没有新数据加载,退出循环
                    break
            # 关闭浏览器
            driver.quit()
    # 中间件部分
    class SeleniumMiddleware:
        def __init__(self):
            # 设置代理
            proxy = f"{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}"
            chrome_options = Options()
            chrome_options.add_argument('--headless')  # 无头模式
            chrome_options.add_argument(f"--proxy-server={proxy}")
            # 设置代理认证
            pluginfile = 'proxy_auth_plugin.zip'  # 代理插件文件路径
            chrome_options.add_extension(pluginfile)
            self.driver = webdriver.Chrome(options=chrome_options)
        def process_request(self, request, spider):
            self.driver.get(request.url)
            # 模拟滚动翻页操作
            self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            body = self.driver.page_source
            return HtmlResponse(self.driver.current_url, body=body, encoding='utf-8', request=request)

    五、代码实现细节与注意事项

    (一)Selenium的无头模式

      SeleniumMiddleware  中,我们使用了无头模式(  --headless  ),这样可以避免浏览器界面的弹出,提高爬虫的运行效率。同时,无头模式也减少了对系统资源的占用。

    (二)动态等待与超时处理

    在爬虫代码中,我们使用了  WebDriverWait  来等待目标元素的加载。通过设置合理的超时时间,可以避免爬虫因页面加载过慢而卡死。如果在指定时间内目标元素未能加载完成,将抛出  TimeoutException  ,并关闭爬虫。

    (三)滚动翻页的实现

    通过  driver.execute_script  方法,我们模拟了用户滚动页面的行为。每次滚动到页面底部后,等待新数据加载完成,然后继续滚动。当没有新数据加载时,退出循环,完成数据采集。

    (四)数据提取与存储

      parse  方法中,我们通过Selenium的  find_elements  方法获取目标数据,并将其提取为字典格式。Scrapy会自动将这些数据存储到指定的存储介质中,例如JSON文件、数据库等。

    六、总结与展望

    通过Scrapy与Selenium的结合,我们成功实现了滚动翻页数据采集。这种技术方案能够有效地应对动态加载的网页,获取隐藏在滚动翻页中的有价值数据。然而,需要注意的是,这种方案也存在一些局限性。例如,Selenium的运行速度相对较慢,可能会对爬虫的效率产生一定影响。此外,频繁的浏览器操作可能会对目标网站的服务器造成较大压力,因此在实际应用中需要合理控制爬虫的频率和并发数。

    来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31522063/viewspace-3079228/ 

  • 相关推荐