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

深度解析:使用ChromeDriver和webdriver_manager实现无头浏览器爬虫

爬虫代理

问题背景

在现代网络爬虫的实践中,动态网页的内容加载和复杂的反爬虫机制使得数据采集变得愈发困难。传统的静态网页爬取方法已无法满足需求,尤其是在需要模拟用户行为、处理JavaScript渲染的场景下。为此,采用无头浏览器(Headless Browser)技术成为一种有效的解决方案。

无头浏览器能够在后台运行,模拟真实用户的浏览器行为,执行JavaScript脚本,获取动态加载的内容。然而,直接使用Selenium的ChromeDriver可能会暴露出自动化的痕迹,导致被目标网站识别为爬虫。为此,需要采取措施,如设置代理IP、伪装User-Agent和处理Cookies,以提高爬虫的隐蔽性和稳定性。

技术架构图与核心模块拆解

以下是使用ChromeDriver和webdriver_manager实现无头浏览器爬虫的技术架构图:

+-------------------+
|   用户请求        |
+-------------------+
         |
         v
+-------------------+
|   Selenium        |
|   WebDriver       |
+-------------------+
         |
         v
+-------------------+
|   ChromeDriver    |
+-------------------+
         |
         v
+-------------------+
|   Chrome浏览器    |
|   (无头模式)      |
+-------------------+
         |
         v
+-------------------+
|   目标网站        |
+-------------------+

核心模块拆解:

  1. Selenium WebDriver:用于驱动浏览器,模拟用户行为,如点击、滚动等。
  2. ChromeDriver:Selenium与Chrome浏览器之间的桥梁,负责执行Selenium指令。
  3. Chrome浏览器(无头模式):在后台运行的浏览器实例,执行JavaScript,加载动态内容。
  4. 代理IP设置:通过配置代理服务器,隐藏真实IP,避免被目标网站封禁。
  5. User-Agent伪装:修改浏览器的User-Agent,模拟不同的设备和浏览器,降低被识别为爬虫的风险。
  6. Cookies处理:管理和维护Cookies,模拟真实用户的会话状态。

性能对比数据与行业应用案例

在实际应用中,使用无头浏览器爬虫相较于传统的静态网页爬取方法,具有以下优势:

  • 动态内容加载:能够获取JavaScript渲染的动态内容,适用于现代复杂网页。
  • 模拟用户行为:通过模拟点击、滚动等操作,获取完整的网页数据。
  • 反爬虫规避:通过设置代理IP、伪装User-Agent和处理Cookies,降低被识别为爬虫的风险。

行业应用案例:

  • 电商价格监控:通过模拟用户行为,获取电商平台的商品价格和库存信息,进行价格监控和竞争分析。
  • 社交媒体数据采集:获取社交媒体平台的用户评论、点赞数等数据,用于舆情分析和市场研究。
  • 招聘信息抓取:从招聘网站获取职位信息,进行人才市场分析和招聘策略制定。

实现代码示例

以下是使用ChromeDriver和webdriver_manager实现无头浏览器爬虫的代码示例,包含代理IP、User-Agent和Cookies的设置,以及采集TikTok视频简介和评论的功能:

import time
import base64
import zipfile
import string
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

# 代理服务器配置(以亿牛云爬虫代理 www.16yun.cn为例)
proxy_host = "proxy.16yun.cn"  # 代理服务器域名
proxy_port = "3111"  # 代理服务器端口
proxy_user = "16yun"  # 代理用户名
proxy_pass = "16IP"  # 代理密码

# 创建代理认证扩展
def create_proxy_auth_extension(proxy_host, proxy_port, proxy_username, proxy_password, scheme='http', plugin_path=None):
    if plugin_path is None:
        plugin_path = f'/tmp/{proxy_username}_{proxy_password}@{proxy_host}.zip'

    manifest_json = """
    {
        "version": "1.0.0",
        "manifest_version": 2,
        "name": "Proxy Auth",
        "permissions": [
            "proxy",
            "tabs",
            "unlimitedStorage",
            "storage",
            "<all_urls>",
            "webRequest",
            "webRequestBlocking"
        ],
        "background": {
            "scripts": ["background.js"]
        },
        "minimum_chrome_version": "22.0.0"
    }
    """

    background_js = string.Template("""
    var config = {
        mode: "fixed_servers",
        rules: {
            singleProxy: {
                scheme: "${scheme}",
                host: "${host}",
                port: parseInt(${port})
            },
            bypassList: ["foobar.com"]
        }
    };

    chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});

    function callbackFn(details) {
        return {
            authCredentials: {
                username: "${username}",
                password: "${password}"
            }
        };
    }

    chrome.webRequest.onAuthRequired.addListener(
        callbackFn,
        {urls: ["<all_urls>"]},
        ['blocking']
    );
    """).substitute(
        host=proxy_host,
        port=proxy_port,
        username=proxy_username,
        password=proxy_password,
        scheme=scheme,
    )

    with zipfile.ZipFile(plugin_path, 'w') as zp:
        zp.writestr("manifest.json", manifest_json)
        zp.writestr("background.js", background_js)

    return plugin_path

# 创建代理认证扩展
proxy_auth_plugin_path = create_proxy_auth_extension(
    proxy_host=proxy_host,
    proxy_port=proxy_port,
    proxy_username=proxy_user,
    proxy_password=proxy_pass
)

# 设置Chrome选项
chrome_options = Options()
chrome_options.add_argument('--headless')  # 无头模式
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('lang

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

相关文章:

  • 【C++八股】 前置 ++i vs. 后置 i++ 的区别
  • AI分支知识之机器学习,深度学习,强化学习的关系
  • 用 DeepSeek + Kimi 自动做 PPT,效率起飞
  • 使用PyCharm进行Django项目开发环境搭建
  • 01单片机上电后没有正常运行怎么办
  • Jetbrains IDE http客户端使用教程
  • OpenEuler学习笔记(二十二):OpenEuler上部署开源ERP系统Odoo
  • E7770A公共接口单元
  • 全面理解-c++11中的智能指针
  • Bash语言的移动应用开发
  • Halcon缓存?内存泄漏?
  • Spring 整合 MyBatis:核心知识点详解
  • 搜索二维矩阵——巧用右上角起点搜索法,高效解决二维矩阵查找问题
  • vue动态table 动态表头数据+动态列表数据
  • JAVA程序员面试总结
  • 【数据结构-异或字典树】力扣421. 数组中两个数的最大异或值
  • 【Pandas】pandas Series nunique
  • C++:将函数参数定义为const T的意义
  • 网络编程(预备知识)
  • GaN技术基站需要匹配的高性能电源解决方案
  • 美颜SDK架构设计指南:性能优化与跨平台适配实战
  • 数据可视化与交互融合:APP 界面设计的新维度
  • Python3 ImportError: cannot import name ‘XXX‘ from ‘XXX‘
  • 【Kubernetes的SpringCloud最佳实践】有Service是否还需要Eureka?
  • 【数据结构】双向链表(真正的零基础)
  • Rust 测试组织指南:单元测试与集成测试