当前位置: 首页 > article >正文

爬虫—Scrapy 整合 ChromeDriver 实现动态网页拉取

在进行爬虫开发时,使用 Scrapy 配合 ChromeDriver 来模拟真实浏览器加载 JavaScript 渲染内容是一种常见且高效的方法。Scrapy 本身是一个非常强大的爬虫框架,然而它默认使用的是 requests 库来抓取静态网页内容。对于需要通过 JavaScript 渲染的动态网页,Scrapy 本身可能无法直接处理。

因此,使用 ChromeDriver 来模拟浏览器渲染 JavaScript 生成动态内容,然后再用 Scrapy 提取数据,成为了解决这一问题的一种好方式。本文将带你通过实际代码示例,教你如何结合 Scrapy 和 ChromeDriver 抓取动态网页内容。


1. 环境准备

1.1 安装 Scrapy

首先,需要确保你已经安装了 Scrapy。你可以使用以下命令来安装 Scrapy:

pip install scrapy

1.2 安装 Selenium 和 ChromeDriver

在 Scrapy 中使用 Chrome 浏览器来模拟请求,我们需要通过 Selenium 来控制 ChromeDriver。所以,首先需要安装 Selenium

pip install selenium

然后,下载并安装 ChromeDriver。你可以根据你 Chrome 浏览器的版本去 ChromeDriver 官网 下载合适的版本。确保 ChromeDriver 路径已经加入到系统环境变量中,或者你可以在代码中指定路径。

1.3 安装 Scrapy-Selenium

为了让 Scrapy 与 Selenium 配合使用,官方提供了 scrapy-selenium 扩展。安装它:

pip install scrapy-selenium

2. 配置 Scrapy 项目

2.1 创建 Scrapy 项目

在命令行中创建一个新的 Scrapy 项目:

scrapy startproject scrapy_chromedriver
cd scrapy_chromedriver

2.2 配置 settings.py

打开项目目录中的 settings.py,添加以下配置来启用 scrapy-selenium 中间件。

# settings.py

# 启用 scrapy-selenium 中间件
DOWNLOADER_MIDDLEWARES = {
    'scrapy_selenium.SeleniumMiddleware': 800,
}

# 设置 ChromeDriver 的路径
SELENIUM_DRIVER_NAME = 'chrome'
SELENIUM_DRIVER_EXECUTABLE_PATH = '/path/to/chromedriver'  # 替换成你下载的 ChromeDriver 路径
SELENIUM_DRIVER_ARGUMENTS = ['--headless', '--disable-gpu', '--no-sandbox']  # 使用无头模式(可选)

# 默认设置 User-Agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'

2.3 配置 Spider

现在,你可以创建一个爬虫(Spider)来抓取动态网页。

scrapy genspider dynamic_spider example.com

编辑生成的 dynamic_spider.py 文件,配置爬虫来使用 Selenium 打开网页并提取数据。

# dynamic_spider.py

import scrapy
from scrapy_selenium import SeleniumRequest

class DynamicSpider(scrapy.Spider):
    name = 'dynamic_spider'
    allowed_domains = ['example.com']
    start_urls = ['https://example.com/dynamic-page']

    def start_requests(self):
        # 使用 SeleniumRequest 代替 Scrapy 的 Request
        for url in self.start_urls:
            yield SeleniumRequest(url=url, callback=self.parse)

    def parse(self, response):
        # 使用 Selenium 请求加载后的 HTML 页面
        page_title = response.xpath('//title/text()').get()
        print("Page Title: ", page_title)

        # 提取页面中的其他数据,例如某些动态生成的内容
        dynamic_data = response.xpath('//div[@class="dynamic-content"]/text()').get()
        yield {
            'title': page_title,
            'dynamic_data': dynamic_data
        }

在这个例子中,我们用 SeleniumRequest 替代了 Request,并在回调函数中提取动态页面内容。SeleniumRequest 会启动一个浏览器实例来加载页面,并返回最终渲染的 HTML 内容。


3. 运行爬虫

完成配置后,你可以在命令行中运行爬虫:

scrapy crawl dynamic_spider

如果一切配置正确,Scrapy 会通过 Selenium 启动 Chrome 浏览器,加载动态内容并提取数据。


4. 调试与优化

4.1 启用浏览器可视化模式

为了调试,你可以去掉 --headless 参数,这样就可以看到实际的浏览器行为:

SELENIUM_DRIVER_ARGUMENTS = ['--disable-gpu', '--no-sandbox']

4.2 增加等待时间

有时动态内容加载较慢,你可能需要等待页面完全加载后再提取数据。可以通过 Selenium 提供的 WebDriverWait 来增加等待时间。

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

def parse(self, response):
    driver = response.request.meta['driver']
    # 等待某个元素加载完毕
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//div[@class="dynamic-content"]')))
    
    # 继续提取数据
    dynamic_data = response.xpath('//div[@class="dynamic-content"]/text()').get()
    yield {
        'dynamic_data': dynamic_data
    }

4.3 调整延迟与请求频率

在进行大量数据抓取时,记得调整请求的频率,避免过度访问同一网站导致 IP 被封锁:

DOWNLOAD_DELAY = 2  # 每次请求之间延迟 2 秒

5. 总结

通过 ScrapySelenium 结合使用,能够轻松抓取需要 JavaScript 渲染的动态网页。scrapy-selenium 提供了一个方便的接口来使用浏览器驱动,模拟用户行为获取动态数据。

  1. 安装 ScrapySeleniumscrapy-selenium
  2. 配置 settings.py,启用 Selenium 驱动。
  3. 在 Spider 中使用 SeleniumRequest 替代传统的 Request
  4. 进行调试和优化,确保爬虫运行稳定。

通过这种方式,你能够有效地抓取动态生成的网页内容,而不必担心 JavaScript 渲染的问题。希望本教程能够帮助你更好地理解如何在 Scrapy 中集成 ChromeDriver,成功地进行动态网页抓取。


http://www.kler.cn/a/419775.html

相关文章:

  • leetcode--螺旋矩阵
  • 《山海经》:北山
  • 大R玩家流失预测在休闲社交游戏中的应用
  • Linux 各个目录作用
  • redis 快 原因 详解
  • .NET 9 中 LINQ 新增功能实现过程
  • oracle数据库的启动与关闭
  • mongodb下载与使用
  • 分布式协同 - 分布式系统的特性与互斥问题
  • TI毫米波雷达(七)——high accurary示例分析(二)
  • 微信小程序——文档下载功能分享(含代码)
  • MySQL基础(语句)知识复习 (除索引和视图)
  • Hive项目实战:大数据处理与分析
  • 算法:上楼梯(递归)升级版
  • 高原地区分布式光伏电站监测系统解决方案
  • Node.js 中的文件系统(fs)模块详解与代码示例
  • 鸿蒙技术分享:Navigation页面容器封装-鸿蒙@fw/router框架源码解析(三)
  • 人体热释电传感器
  • 利用OpenAI、LangChain和Streamlit进行智能数据分析和可视化
  • MATLAB - ROS2 ros2genmsg 生成自定义消息(msg/srv...)
  • SpringBoot 驱动在线家具商城设计与实现的深度探索
  • C++/Cli里重载winform的WndProc和ProcessCmdKey
  • springboot vue 开源 会员收银系统 (12)购物车关联服务人员 订单计算提成
  • python学习笔记12 python中的函数(上)
  • 深度学习7 梯度下降优化、过拟合、手机价格预测
  • 机器学习——生成对抗网络(GANs):原理、进展与应用前景分析