利用Selenium和PhantomJS提升网页内容抓取与分析的效率

简介: 利用Selenium和PhantomJS提升网页内容抓取与分析的效率

核心观点:效率的提升之道
Selenium本身是一个自动化测试工具,用于模拟真实用户操作。直接使用它来爬虫可能会很慢。提升效率的关键在于,将其从“模拟视觉化用户”转变为“高性能的无头数据采集工具”。
第一部分:为什么是 Selenium + 无头模式?

  1. 处理动态内容:对于通过JavaScript异步加载数据的页面(如单页应用SPA),传统的Requests库无法获取完整内容。Selenium可以驱动浏览器完整执行JS,直接获取最终渲染的DOM。
  2. 绕过简单反爬:可以模拟真实浏览器的行为,如滚动、点击、输入等,使得爬虫行为更接近人类,从而绕过一些基于用户行为检测的反爬机制。
  3. 无头模式的效率飞跃:
    ○ PhantomJS的遗产:PhantomJS是早期无头浏览器的代表,不需要图形界面,节省了资源。
    ○ 现代替代品:Chrome和Firefox都推出了原生的无头模式,性能更优,兼容性更好,是当前的主流选择。我们应放弃PhantomJS,转向Chrome/Firefox的无头模式。
    第二部分:现代化高效实践(代码示例)
    以下示例均使用 Selenium + Chrome 无头模式。
  4. 基础设置:启用无头模式并优化选项
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.common.by import By
    import time
    import zipfile

代理信息

proxyHost = "www.16yun.cn"
proxyPort = "5445"
proxyUser = "16QMSOML"
proxyPass = "280651"

创建Chrome选项

chrome_options = Options()

创建代理认证插件

def create_proxy_auth_extension(proxy_host, proxy_port, proxy_username, proxy_password, scheme='http'):
"""创建带有代理认证的Chrome扩展"""

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

background_js = """
var config = {
    mode: "fixed_servers",
    rules: {
        singleProxy: {
            scheme: "%s",
            host: "%s",
            port: parseInt(%s)
        },
        bypassList: ["localhost"]
    }
};

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

chrome.webRequest.onAuthRequired.addListener(
    function(details) {
        return {
            authCredentials: {
                username: "%s",
                password: "%s"
            }
        };
    },
    {urls: ["<all_urls>"]},
    ['blocking']
);
""" % (scheme, proxy_host, proxy_port, proxy_username, proxy_password)

# 创建临时插件文件
import tempfile
import os
from pathlib import Path

plugin_dir = tempfile.mkdtemp()
plugin_file = Path(plugin_dir) / "proxy_auth_plugin.zip"

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

return plugin_file

创建代理认证插件

proxy_plugin = create_proxy_auth_extension(
proxy_host=proxyHost,
proxy_port=proxyPort,
proxy_username=proxyUser,
proxy_password=proxyPass
)

添加插件到Chrome选项

chrome_options.add_extension(proxy_plugin)

核心:启用无头模式

chrome_options.add_argument("--headless=new")
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--window-size=1920,1080")

可选:禁用图片加载

prefs = {"profile.managed_default_content_settings.images": 2}
chrome_options.add_experimental_option("prefs", prefs)

初始化驱动

driver = webdriver.Chrome(options=chrome_options)

try:

# 测试代理是否生效
driver.get("https://httpbin.org/ip")
page_source = driver.page_source
print(page_source)
print("代理设置成功!")

# 您的实际爬虫代码
# driver.get("https://example.com")
# ... 其他操作

finally:
driver.quit()

# 清理临时文件
import os
import shutil
plugin_dir = os.path.dirname(proxy_plugin)
if os.path.exists(plugin_dir):
    shutil.rmtree(plugin_dir)
  1. 效率提升技巧:智能等待代替固定休眠
    固定使用time.sleep()是效率低下的主要原因。应使用显式等待。
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC

driver.get("https://example.com/dynamic-content")

try:

# 显式等待:最多等10秒,直到指定元素出现在DOM中
# 一旦元素出现,立即继续执行,无需等待完10秒
target_element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "dynamic-content-list"))
)

# 对找到的元素进行操作
items = target_element.find_elements(By.TAG_NAME, "li")
for item in items:
    print(item.text)

except Exception as e:
print("元素未在指定时间内加载出来:", e)

  1. 高级分析:直接执行JavaScript获取数据
    有时,数据直接保存在页面的JS变量中,直接提取比解析HTML更高效。

    假设页面有一个JS变量:var userData = {name: "John", id: 123};

    user_data = driver.execute_script("return window.userData;")
    print(user_data) # 直接得到Python字典:{'name': 'John', 'id': 123}

或者,用JS进行复杂的DOM查询或操作

all_links_text = driver.execute_script("""
var links = Array.from(document.querySelectorAll('a'));
return links.map(link => link.textContent);
""")
print(all_links_text)
第三部分:超越基础,构建稳健的爬虫系统

  1. 并发与池化:
    ○ 使用concurrent.futures.ThreadPoolExecutor管理多个浏览器实例。
    ○ 注意:每个WebDriver实例资源开销大,需要根据机器性能谨慎控制并发数。
    ○ 考虑使用selenium-grid进行分布式爬取。
    规避检测:
    ○ 现代网站会检测自动化工具。可以使用selenium-stealth等库来隐藏Selenium的特征。
    ○ 随机化用户代理、视口大小和鼠标移动轨迹。
  2. python
    from selenium_stealth import stealth

    ... 驱动初始化后

    stealth(driver,
     languages=["en-US", "en"],
     vendor="Google Inc.",
     platform="Win32",
     webgl_vendor="Intel Inc.",
     renderer="Intel Iris OpenGL Engine",
     fix_hairline=True,
     )
    
  3. 错误处理与重试机制:
    ○ 网络不稳定、元素未找到等情况很常见,必须使用try-except块并实现重试逻辑。
    总结:效率提升清单
    操作 低效做法 高效做法
    浏览器模式 使用有图形界面的浏览器 使用Chrome/Firefox无头模式
    等待方式 大量使用time.sleep(n) 使用WebDriverWait
    显式等待
    资源加载 加载所有图片、CSS、字体 禁用图片加载,可选择性阻塞不必要资源
    驱动管理 每次任务都创建/销毁驱动 考虑使用驱动池(需自行实现)
    数据提取 仅通过page_source
    然后解析 结合execute_script
    直接从JS上下文获取
    并发 单线程顺序爬取 多线程/分布式(Selenium Grid)
    最终建议:虽然Selenium功能强大,但它始终是资源密集型工具。在爬虫项目中,应遵循 “首选轻量级,不得已再用Selenium” 的原则。首先尝试分析网站的API接口(通过浏览器开发者工具的“网络”面板),能用Requests模拟API调用是速度最快、最稳定的方案。当面对纯JS渲染、且没有清晰API的网站时,Selenium配合无头浏览器才是你的终极武器。
相关文章
|
3月前
|
数据采集 监控 API
告别手动埋点!Android 无侵入式数据采集方案深度解析
传统的Android应用监控方案需要开发者在代码中手动添加埋点,不仅侵入性强、工作量大,还难以维护。本文深入探讨了基于字节码插桩技术的无侵入式数据采集方案,通过Gradle插件 + AGP API + ASM的技术组合,实现对应用性能、用户行为、网络请求等全方位监控,真正做到零侵入、易集成、高稳定。
585 50
|
3月前
|
人工智能 监控 安全
提效40%?揭秘AI驱动的支付方式“一键接入”系统
本项目构建AI驱动的研发提效系统,通过Qwen Coder与MCP工具链协同,实现跨境支付渠道接入的自动化闭环。采用多智能体协作模式,结合结构化Prompt、任务拆解、流程管控与安全约束,显著提升研发效率与交付质量,探索大模型在复杂业务场景下的高采纳率编码实践。
497 26
提效40%?揭秘AI驱动的支付方式“一键接入”系统
|
3月前
|
人工智能 监控 Java
构建定时 Agent,基于 Spring AI Alibaba 实现自主运行的人机协同智能 Agent
借助 Spring AI Alibaba 框架,开发者可快速实现定制化自动定时运行的 Agent,构建数据采集、智能分析到人工参与决策的全流程AI业务应用。
1234 56
|
3月前
|
SQL 人工智能 关系型数据库
AI Agent的未来之争:任务规划,该由人主导还是AI自主?——阿里云RDS AI助手的最佳实践
AI Agent的规划能力需权衡自主与人工。阿里云RDS AI助手实践表明:开放场景可由大模型自主规划,高频垂直场景则宜采用人工SOP驱动,结合案例库与混合架构,实现稳定、可解释的企业级应用,推动AI从“能聊”走向“能用”。
949 39
AI Agent的未来之争:任务规划,该由人主导还是AI自主?——阿里云RDS AI助手的最佳实践
|
3月前
|
存储 人工智能 安全
揭秘 MCP Streamable HTTP 协议亲和性的技术内幕
函数计算推出MCP Streamable HTTP亲和机制,支持会话级请求绑定,解决传统Serverless对会话应用支持不足的问题。实现高效生命周期控制,并支持Bearer认证,助力开发者构建更稳定、安全、高性能的AI应用服务。
710 25
|
3月前
|
机器学习/深度学习 数据可视化 算法
sklearn 特征选择实战:用 RFE 找到最优特征组合
特征越多模型未必越好,过多特征易导致过拟合、训练慢、难解释。递归特征消除(RFE)通过反复训练与特征评分,逐步剔除不重要特征,提升模型泛化能力与效率。本文详解RFE原理,并用scikit-learn实战葡萄酒数据集,展示如何结合逻辑回归与随机森林进行特征选择,比较不同模型的筛选差异,并通过RFECV自动确定最优特征数量,辅以可视化分析,帮助构建更简洁、高效、可解释的模型。
296 1
sklearn 特征选择实战:用 RFE 找到最优特征组合
|
3月前
|
缓存 安全 Java
Java Spring BeanUtils 拷贝多个源对象 source 到目标对象 target
Spring BeanUtils可简化Java Bean属性拷贝,避免冗余get/set代码。支持忽略字段、限制类属性等操作,性能优于Apache工具,但需注意多源拷贝时的顺序问题,防止属性覆盖。
|
3月前
|
人工智能 弹性计算 双11
阿里云2025年双十一活动介绍
‌阿里云2025年双十一活动已开启,优惠时间从10月24日持续至11月30日‌,涵盖云服务器、AI大模型等产品,最高可领1728元优惠券,部分AI资源免费体验。
505 1
|
3月前
|
存储 消息中间件 Kafka
Confluent 首席架构师万字剖析 Apache Fluss(二):核心架构
原文:https://jack-vanlightly.com/blog/2025/9/2/understanding-apache-fluss 作者:Jack Vanlightly 翻译:Wayne Wang@腾讯 译注:Jack Vanlightly 是一位专注于数据系统底层架构的知名技术博主,他的文章以篇幅长、细节丰富而闻名。目前 Jack 就职于 Confluent,担任首席技术架构师,因此这篇 Fluss 深度分析文章,具备一定的客观参考意义。译文拆成了三篇文章,本文是第二篇。
431 19
|
3月前
|
存储 消息中间件 Kafka
Confluent 首席架构师万字剖析 Apache Fluss(三):湖流一体
原文:https://jack-vanlightly.com/blog/2025/9/2/understanding-apache-fluss 作者:Jack Vanlightly 翻译:Wayne Wang@腾讯 译注:Jack Vanlightly 是一位专注于数据系统底层架构的知名技术博主,他的文章以篇幅长、细节丰富而闻名。目前 Jack 就职于 Confluent,担任首席技术架构师,因此这篇 Fluss 深度分析文章,具备一定的客观参考意义。译文拆成了三篇文章,本文是第二篇。
525 25
Confluent 首席架构师万字剖析 Apache Fluss(三):湖流一体