前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >无头浏览器与请求签名技术-Cloudflare防护

无头浏览器与请求签名技术-Cloudflare防护

原创
作者头像
jackcode
发布于 2025-03-11 05:50:45
发布于 2025-03-11 05:50:45
23000
代码可运行
举报
文章被收录于专栏:爬虫资料爬虫资料
运行总次数:0
代码可运行

在实际数据采集实践中,许多目标网站(例如 Amazon)都会采用 Cloudflare 等防护措施,防止机器人和非正常流量。本文将分享一个故障场景下的排查与改进方案,讲述如何利用无头浏览器、请求签名技术以及爬虫代理 IP来实现数据采集。

本文结构如下:

  • 时间轴呈现方案进程
  • 方案分析
  • 架构改进方案

时间轴呈现方案进程

  1. 初次尝试(T0):undefined在最初采集 Amazon 商品信息时,使用常规的请求方式(如 Python 的 requests 库)直接访问目标页面,但由于 Cloudflare 的机制,返回了验证码页面或直接拒绝访问。
  2. 排查与调试(T1):undefined经过详细分析,确认 Cloudflare 主要通过检测 Cookie、User-Agent 以及请求行为来判断是否为真实用户。传统的请求方式难以模拟完整的浏览器环境,导致防护措施生效。
  3. 引入无头浏览器(T2):undefined为了完整地执行页面中的 JavaScript,并获取有效的 Cookie 信息,开始采用 Selenium 等无头浏览器方案。同时,利用代理 IP 技术规避单 IP 访问过于集中的风险。
  4. 请求签名技术落地(T3):undefined在无头浏览器获取到 Cookie 信息后,通过对目标 URL 与 Cookie 的加密计算,生成请求签名。将签名附加到后续请求中,进一步模拟浏览器真实行为,绕过 Cloudflare 的二次验证。
  5. 系统测试与数据提取(T4):undefined经过多次调试后,成功采集到 Amazon 上的商品标题、价格和评价等信息,同时整个流程在代理支持下实现了稳定的运行。

方案分析

Cloudflare 防护主要依赖以下几方面来辨识是否为正常用户请求:

  • Cookie 策略: Cloudflare 会在首次访问时生成一系列 Cookie,并要求后续请求带上这些 Cookie,否则将视为异常流量。
  • User-Agent 检测: 非浏览器默认的 User-Agent 或者缺失相关头信息的请求容易被直接屏蔽。
  • 行为监测与签名验证: 通过对请求 URL 及 Cookie 等信息进行加密计算,生成签名,验证请求是否来自真实用户。

传统的 HTTP 请求难以满足上述条件,因此本文引入了无头浏览器技术。通过 Selenium 模拟完整的浏览器行为,可以获取到 Cloudflare 设置的 Cookie,再结合自定义的请求签名算法(例如 MD5 散列计算),将签名附加到请求中,从而绕过防护。同时,采用爬虫代理技术,利用代理 IP、用户名和密码等信息,确保请求来源的多样性,进一步降低被限制的风险。


架构改进方案

在当前方案基础上,为提高系统的稳定性和扩展性,建议从以下几个方面进行架构改进:

  1. 无头浏览器集群化部署:undefined利用 Docker 或 Kubernetes 部署无头浏览器集群,实现并发采集任务的分布式调度。这样既可以提高采集效率,也能避免单节点故障导致整个系统中断。
  2. 签名算法优化:undefined根据目标网站的动态检测机制,持续调整和优化签名生成算法。可以考虑通过机器学习等方式不断学习目标网站的防护规则,实现自适应的请求签名策略。
  3. 代理池管理:undefined构建一个自动化代理池,动态监控代理 IP 的可用性,并自动切换故障代理。参考爬虫代理的接入方式,实现代理IP的自动认证和更新。
  4. 多层次容错机制:undefined在请求失败或防护触发时,设置重试、延时等容错机制,同时记录失败日志,方便后续问题排查与数据补采。
  5. 数据清洗与存储:undefined对采集到的数据进行实时清洗、去重,并存储到数据库中。可以利用异步消息队列对爬虫任务进行解耦,提升系统整体的健壮性。

示例代码

下面给出一个基于 Selenium 的无头浏览器示例代码,展示如何设置代理、Cookie、User-Agent,并生成请求签名以采集 Amazon 商品信息。代码中引用了爬虫代理的域名、端口、用户名和密码(请根据实际情况替换)。

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
import time
import hashlib
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By

def generate_signature(url, cookies):
    """
    模拟生成请求签名的逻辑
    这里简单地将 URL 与所有 cookie 拼接后计算 MD5 值,实际中可能需要更复杂的算法
    """
    raw = url + ''.join([cookie['name'] + cookie['value'] for cookie in cookies])
    return hashlib.md5(raw.encode('utf-8')).hexdigest()

def scrape_amazon_product(product_url):
    # 设置 Chrome 无头浏览器选项
    chrome_options = Options()
    chrome_options.add_argument("--headless")  # 开启无头模式

    # 设置代理 IP,参考亿牛云爬虫代理的配置
    proxy_host = "proxy.16yun.cn"  # 代理服务器域名
    proxy_port = "8080"               # 代理端口
    proxy_user = "16YUN"           # 代理用户名
    proxy_pass = "16IP"           # 代理密码

    # 如果代理需要认证,则需要构造代理认证字符串,此处为简单示例
    proxy = f"{proxy_host}:{proxy_port}"
    chrome_options.add_argument(f'--proxy-server=http://{proxy}')

    # 设置 User-Agent 模拟真实浏览器
    user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36"
    chrome_options.add_argument(f'user-agent={user_agent}')

    # 初始化 webdriver(确保已安装对应的 chromedriver 并配置到环境变量中)
    driver = webdriver.Chrome(options=chrome_options)

    try:
        # 访问目标页面(Amazon 商品页面)
        driver.get(product_url)
        # 等待页面加载及 Cloudflare 防护检测通过(根据实际情况调整等待时间)
        time.sleep(5)
        
        # 获取页面 Cookie,用于生成请求签名
        cookies = driver.get_cookies()
        signature = generate_signature(product_url, cookies)
        print("生成的请求签名:", signature)
        
        # 提取商品信息(标题、价格、评价等)
        # 商品标题
        product_title = driver.find_element(By.ID, "productTitle").text if driver.find_elements(By.ID, "productTitle") else "无商品标题"
        # 商品价格(价格可能位于不同的元素中,此处仅为示例)
        try:
            product_price = driver.find_element(By.ID, "priceblock_ourprice").text
        except Exception as e:
            product_price = "价格信息获取失败"
        # 商品评价(同样,评价信息的获取可能因页面结构不同而变化)
        try:
            product_review = driver.find_element(By.ID, "acrCustomerReviewText").text
        except Exception as e:
            product_review = "评价信息获取失败"
        
        print("商品标题:", product_title)
        print("商品价格:", product_price)
        print("商品评价:", product_review)
    finally:
        # 关闭浏览器
        driver.quit()

if __name__ == '__main__':
    # 示例目标商品链接(请替换为实际存在的商品链接)
    target_url = "https://www.amazon.com/dp/B08N5WRWNW"
    scrape_amazon_product(target_url)

代码说明

  • 无头浏览器设置: 通过 chrome_options.add_argument("--headless") 启用无头模式,以便在后台静默运行浏览器。
  • 代理 IP 配置: 利用爬虫代理提供的域名、端口、用户名和密码,设置代理服务器,从而规避单 IP 请求风险。
  • User-Agent 与 Cookie: 在启动浏览器时,设置 User-Agent 参数;同时,浏览器执行页面中的 JavaScript 后能自动获取 Cloudflare 下发的 Cookie,这为后续请求签名提供数据支持。
  • 请求签名: 通过将目标 URL 与 Cookie 拼接后计算 MD5 散列值,模拟生成请求签名。

总结

在面对 Cloudflare 防护和复杂网站反爬机制时,单一的 HTTP 请求方案往往难以奏效。通过引入无头浏览器,可以完整模拟真实用户的浏览行为;结合请求签名技术,进一步通过 Cookie 与请求参数的加密验证,实现了对防护机制的绕过。同时,采用爬虫代理 IP确保了请求的分散性与稳定性。

未来,通过无头浏览器集群化、代理池管理及签名算法优化,可以不断提升数据采集的效率与成功率,为故障排查及架构改进提供更加成熟的解决方案。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
图解LeetCode——102. 二叉树的层序遍历
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。(即逐层地,从左到右访问所有节点)。
爪哇缪斯
2023/09/06
1620
图解LeetCode——102. 二叉树的层序遍历
图文详解 DFS 和 BFS
深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath First Search)是图论中两种非常重要的算法,生产上广泛用于拓扑排序,寻路(走迷宫),搜索引擎,爬虫等,也频繁出现在 leetcode,高频面试题中。
kunge
2020/04/26
5.9K0
好的,DFS,也学废了!
没错,本篇是上一篇《好的,BFS,又学废了!》的姊妹篇,意在通过简单回顾拾起学了忘、又忘了学的基础数据结构;
掘金安东尼
2022/09/19
3730
好的,DFS,也学废了!
Python学习中:最感到惊奇35个语言特征和编程技巧
从我开始学习python的时候,我就开始自己总结一个python小技巧的集合。后来当我什么时候在Stack Overflow或者在某个开源软件里看到一段很酷代码的时候,我就很惊讶:原来还能这么做!当时我会努力的自己尝试一下这段代码,直到我懂了它的整体思路以后,我就把这段代码加到我的集合里。这篇博客其实就是这个集合整理后一部分的公开亮相。如果你已经是个python大牛,那么基本上你应该知道这里面的大多数用法了,但我想你应该也能发现一些你不知道的新技巧。而如果你之前是一个c,c++,java的程序员,同时在学习python,或者干脆就是一个刚刚学习编程的新手,那么你应该会看到很多特别有用能让你感到惊奇的实用技巧,就像我当初一样。
一墨编程学习
2019/07/10
3640
LeetCode 590: N 叉树的后序遍历 N-ary Tree Postorder Traversal
Given an n-ary tree, return the postorder traversal of its nodes' values.
爱写bug
2020/01/02
6570
每日一题(2022-04-18)——字典序排数
386. 字典序排数 题目描述: 给你一个整数 n ,按字典序返回范围 [1, n] 内所有整数。 你必须设计一个时间复杂度为 O(n) 且使用 O(1) 额外空间的算法。 示例1: 输入:n = 13 输出:[1,10,11,12,13,2,3,4,5,6,7,8,9] 示例2: 输入:n = 20 输出:[1,10,11,12,13,14,15,16,17,18,19,2,20,3,4,5,6,7,8,9] 思路: 解释: 以例二来看: 可以看到字典序的遍历,就是树的深度优
传说之下的花儿
2023/04/16
2060
每日一题(2022-04-18)——字典序排数
LeetCode 589: N 叉树的前序遍历 N-ary Tree Preorder Traversal
Given an n-ary tree, return the preorder traversal of its nodes' values.
爱写bug
2020/01/02
7290
回溯——77. 组合
来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/combinations
向着百万年薪努力的小赵
2022/12/02
3430
回溯——77. 组合
英伟达小姐姐的Python隐藏技巧合集,推特2400赞,代码可以直接跑
常常发资源的英伟达工程师小姐姐Chip Huyen,又发射了一套Python隐藏功能合集。
量子位
2019/10/25
5190
数据结构与算法(四)| 队列、栈与Java集合
比如,实现图的宽度优先遍历,但是要求用栈实现;实现图的深度优先遍历,但是要求用队列实现。
行百里er
2021/07/14
5010
优雅编写Python3的62个小贴士!
▍42、创建一个迭代器,它从iterable中过滤元素,只返回谓词为False的元素
AI科技大本营
2019/08/01
7990
优雅编写Python3的62个小贴士!
弄懂这56个Python使用技巧,秒变Python大神!
你也许知道如何进行列表解析,但是可能不知道字典/集合解析。它们简单易用且高效。就像下面这个例子:
一墨编程学习
2019/08/12
1.3K0
流畅的Python 2. 数据结构 - 序列构成的数组
insort(seq, item) 把变量 item 插入到序列 seq 中,并能保持 seq 的升序顺序
Michael阿明
2021/09/06
5250
Python 容器使用的 5 个技巧和 2 个误区
在 Python 中,有四类最常见的内建容器类型: 列表(list)、 元组(tuple)、 字典(dict)、 集合(set)。通过单独或是组合使用它们,可以高效的完成很多事情。
一墨编程学习
2019/07/14
8360
35个高级Python知识点总结
众所周知,Java中强调“一切皆对象”,但是Python中的面向对象比Java更加彻底,因为Python中的类(class)也是对象,函数(function)也是对象,而且Python的代码和模块也都是对象。
py3study
2020/01/08
2.4K0
1 行 Python 代码能干哪些事,这 13 个你知道吗?
Python 之禅有一句话叫 “Simple is better than complex.”,简单,到底能多简单,一行代码?
崔庆才
2019/05/17
4600
40个你可能不知道的Python的特点和技巧
1、拆箱 >>> a, b, c = 1, 2, 3 >>> a, b, c (1, 2, 3) >>> a, b, c = [1, 2, 3] >>> a, b, c (1, 2, 3) >>> a, b, c = (2 * i + 1 for i in range(3)) >>> a, b, c (1, 3, 5) >>> a, (b, c), d = [1, (2, 3), 4] >>> a 1 >>> b 2 >>> c 3 >>> d 4     2、使用拆箱进行变量交换 >>> a, b = 1
Java学习123
2018/05/16
6830
Python基础之序列构成的数组
容器序列能够存放不同类型的数据,比扁平序列更灵活; 扁平序列只能存放一种类型的原子性的数据,体积更小速度更快。eg:数字,字符字节
py3study
2020/01/06
1.2K0
20个值得学习的 Python 技巧
本文为大家介绍20个值得记住的 Python 技巧,可以提升您编程技巧, 并为您节省大量时间。在平常编程过程中,以下技巧大多非常有用。
吾非同
2020/12/07
9710
20个值得学习的 Python 技巧
路径总和(I、II、III)
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
木子星兮
2020/07/17
1.3K0
推荐阅读
相关推荐
图解LeetCode——102. 二叉树的层序遍历
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档