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

Python爬虫进阶:突破反爬机制(UA伪装+代理池+验证码识别)

在爬虫开发中,“反爬”是绕不开的门槛——当请求频率过高、请求特征异常时,目标网站会通过封禁IP、弹出验证码、返回无效数据等方式拦截爬虫。本文将聚焦UA伪装、代理池搭建、验证码识别三大核心反爬场景,结合实战代码讲解具体解决方案,帮助你高效、合规地获取数据。

 

一、基础反爬:UA伪装——让爬虫“伪装”成真实浏览器

 

1.1 为什么需要UA伪装?

 

UA(User-Agent)是HTTP请求头中的关键字段,用于标识请求来源(如浏览器型号、操作系统)。网站通过识别UA,可轻松区分“爬虫程序”与“真实用户”——若UA为 python-requests/2.25.1 (requests库默认值),大概率会被直接拦截。

 

1.2 实战:动态生成并使用UA

 

1.2.1 方案选择:使用fake-useragent库

 

 fake-useragent 可自动生成不同浏览器、不同系统的真实UA,无需手动维护UA列表。

 

安装依赖:

 

python

pip install fake-useragent

 

 

1.2.2 核心代码实现

 

python

import requests

from fake_useragent import UserAgent

 

# 1. 初始化UA生成器(use_cache_server=False避免缓存失效问题)

ua = UserAgent(use_cache_server=False)

 

# 2. 动态获取一个Chrome浏览器的UA

headers = {

    "User-Agent": ua.chrome, # 也可指定ua.firefox/ua.safari

    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" # 补充其他请求头,模拟真实浏览器

}

 

# 3. 发送请求(以测试网站httpbin.org为例,可查看请求头是否生效)

url = "http://httpbin.org/get"

response = requests.get(url, headers=headers)

 

# 4. 验证结果:查看返回的UA是否为伪装后的内容

print("请求头中的UA:", headers["User-Agent"])

print("网站接收的UA:", response.json()["headers"]["User-Agent"])

 

 

1.2.3 避坑点

 

- 若 fake-useragent 报错“Maximum retries exceeded”,需添加 use_cache_server=False 禁用缓存服务器;

- 不要频繁使用同一UA,建议每次请求前重新生成,降低被识别风险。

 

二、进阶反爬:代理池搭建——解决IP封禁问题

 

2.1 IP被封禁的场景与危害

 

当爬虫用同一IP高频次请求网站时(如每秒10次以上),网站会将该IP加入黑名单,导致后续请求返回403/503错误,甚至无法访问网站。此时,代理IP是唯一解决方案——通过切换不同IP发送请求,规避IP封禁。

 

2.2 实战:搭建简易代理池(免费代理+有效性检测)

 

2.2.1 核心思路

 

1. 从免费代理网站(如“西刺代理”“快代理”)爬取代理IP;

2. 对爬取的代理进行有效性检测(测试能否正常访问目标网站);

3. 维护一个“可用代理列表”,供爬虫随机调用。

 

2.2.2 代理池核心代码

 

python

import requests

from fake_useragent import UserAgent

import time

 

# 1. 爬取免费代理(以快代理为例,仅作演示,免费代理稳定性较低)

def get_free_proxies():

    proxies_list = []

    url = "https://www.kuaidaili.com/free/inha/1/"

    headers = {"User-Agent": UserAgent(use_cache_server=False).chrome}

    response = requests.get(url, headers=headers)

    

    # 解析页面(此处用正则提取IP和端口,实际可结合lxml/xpath)

    import re

    pattern = r'<td data-title="IP">(\d+\.\d+\.\d+\.\d+)</td>.*?<td data-title="PORT">(\d+)</td>'

    proxies = re.findall(pattern, response.text, re.S)

    

    # 整理为requests可识别的格式({"http":"http://IP:端口", "https":"https://IP:端口"})

    for ip, port in proxies:

        proxies_list.append({

            "http": f"http://{ip}:{port}",

            "https": f"https://{ip}:{port}"

        })

    return proxies_list

 

# 2. 检测代理有效性(测试能否访问目标网站,此处以百度为例)

def check_proxy(proxy, target_url="https://www.baidu.com"):

    try:

        # 超时时间设为5秒,避免无效代理阻塞程序

        response = requests.get(target_url, proxies=proxy, timeout=5)

        # 若状态码为200,说明代理可用

        return response.status_code == 200

    except:

        return False

 

# 3. 构建可用代理池

def build_proxy_pool():

    free_proxies = get_free_proxies()

    valid_proxies = []

    for proxy in free_proxies:

        if check_proxy(proxy):

            valid_proxies.append(proxy)

            print(f"新增可用代理:{proxy}")

        time.sleep(1) # 避免检测频率过高被代理网站拦截

    print(f"\n可用代理池构建完成,共{len(valid_proxies)}个可用代理")

    return valid_proxies

 

# 4. 爬虫调用代理池(随机选择一个可用代理)

if __name__ == "__main__":

    proxy_pool = build_proxy_pool()

    if not proxy_pool:

        print("无可用代理,程序退出")

        exit()

    

    # 随机选择一个代理

    import random

    target_url = "https://目标网站.com" # 替换为你的目标网站

    selected_proxy = random.choice(proxy_pool)

    

    try:

        response = requests.get(

            target_url,

            proxies=selected_proxy,

            headers={"User-Agent": UserAgent(use_cache_server=False).chrome},

            timeout=10

        )

        print(f"请求成功,状态码:{response.status_code}")

    except Exception as e:

        print(f"请求失败,原因:{str(e)}")

 

 

2.2.3 优化建议

 

- 免费代理稳定性差,生产环境建议使用付费代理API(如阿布云、芝麻代理),可直接获取高可用代理;

- 给代理池添加“定时更新”逻辑(如每10分钟重新爬取+检测),保证代理有效性;

- 记录代理使用次数,若某代理连续失败3次,从池中移除。

 

三、高阶反爬:验证码识别——突破人机验证门槛

 

3.1 常见验证码类型与应对方案

 

网站常用的验证码分为“简单图形验证码”(如数字+字母组合)和“复杂验证码”(如滑块验证码、点选验证码),不同类型对应不同解决方案:

 

验证码类型 解决方案 适用场景 

数字/字母图形验证码 Tesseract-OCR(免费)、第三方API(如百度AI) 验证码无扭曲、无干扰线 

滑块验证码 模拟鼠标拖动(如selenium+ActionChains) 需验证“滑动轨迹是否自然” 

点选验证码 图像识别+坐标定位(如百度AI图像识别) 需点击指定文字/图形 

 

3.2 实战1:用Tesseract-OCR识别简单图形验证码

 

3.2.1 环境准备

 

1. 安装Tesseract-OCR引擎(官网下载,需配置系统环境变量);

2. 安装Python依赖:

 

python

pip install pytesseract pillow # pillow用于图像处理

 

 

3.2.2 核心代码(含图像预处理)

 

图形验证码常存在“干扰线、噪点”,需先进行灰度处理、二值化(黑白化),提升识别准确率:

 

python

from PIL import Image

import pytesseract

import requests

from io import BytesIO

 

# 1. 下载验证码图片(替换为目标网站的验证码URL)

captcha_url = "https://目标网站.com/captcha.jpg"

response = requests.get(captcha_url)

image = Image.open(BytesIO(response.content))

 

# 2. 图像预处理:灰度处理 → 二值化(去除干扰)

def preprocess_image(image):

    # 灰度处理:将彩色图转为黑白图

    gray_image = image.convert("L")

    # 二值化:设定阈值(127),低于阈值设为0(黑),高于设为255(白)

    threshold = 127

    binary_image = gray_image.point(lambda x: 0 if x < threshold else 255, "1")

    return binary_image

 

# 3. 识别验证码

processed_image = preprocess_image(image)

# 调用Tesseract识别(lang="eng"表示识别英文,若有数字可省略)

captcha_text = pytesseract.image_to_string(processed_image, lang="eng")

# 去除识别结果中的空格、换行符

captcha_text =

captcha_text.strip().replace(" ", "").replace("\n", "")

 print(f"识别出的验证码:{captcha_text}")

 

3.2.3 避坑点

- 若识别准确率低,可调整二值化阈值(如100-150之间测试);

- 若验证码有中文,需下载Tesseract中文语言包(放入Tesseract的 tessdata 目录),并将 lang 改为 "chi_sim" 。

 

3.3 实战2:用Selenium突破滑块验证码

 

以“某网站滑块验证码”为例,核心是模拟“人类滑动轨迹”(匀速加速+轻微抖动),避免被识别为机器:

from selenium import webdriver

from selenium.webdriver.common.action_chains import ActionChains

import time

import random

 

# 1. 初始化浏览器(需下载对应浏览器的驱动,如ChromeDriver)

driver = webdriver.Chrome()

driver.get("https://目标网站.com/login") # 替换为带滑块验证码的页面

time.sleep(2) # 等待页面加载

 

# 2. 定位滑块元素(需根据目标网站的HTML结构调整xpath)

slider = driver.find_element("xpath", '//div[@class="slider-btn"]') # 滑块按钮

slider_track = driver.find_element("xpath", '//div[@class="slider-track"]') # 滑块轨道

 

# 3. 模拟人类滑动轨迹:先加速后减速,带轻微抖动

def simulate_slide(slider, track_width):

    # 计算滑动距离(轨道宽度 - 滑块宽度,需根据实际情况调整)

    slide_distance = track_width - 50 # 50为滑块宽度,需实测

    

    # 生成滑动轨迹(分3段:加速→匀速→减速)

    track = []

    current_distance = 0

    # 第一段:加速(滑动距离的60%)

    while current_distance < slide_distance * 0.6:

        speed = random.randint(5, 10) # 加速阶段速度递增

        track.append(speed)

        current_distance += speed

    # 第二段:匀速(滑动距离的30%)

    while current_distance < slide_distance * 0.9:

        speed = random.randint(3, 5) # 匀速阶段速度稳定

        track.append(speed)

        current_distance += speed

    # 第三段:减速(剩余10%距离)

    while current_distance < slide_distance:

        speed = random.randint(1, 3) # 减速阶段速度递减

        track.append(speed)

        current_distance += speed

    

    # 执行滑动操作

    ActionChains(driver).click_and_hold(slider).perform() # 按住滑块

    for x in track:

        # 横向滑动x像素,纵向随机抖动±1像素(模拟人类操作)

        ActionChains(driver).move_by_offset(xoffset=x, yoffset=random.randint(-1, 1)).perform()

        time.sleep(random.uniform(0.01, 0.03)) # 每步停顿,模拟真实速度

    time.sleep(random.uniform(0.1, 0.2)) # 滑动结束后停顿

    ActionChains(driver).release().perform() # 释放滑块

 

# 4. 执行滑动

track_width = slider_track.size["width"] # 获取轨道宽度

simulate_slide(slider, track_width)

time.sleep(3) # 等待验证结果

 

# 5. 验证是否成功(根据页面提示调整判断逻辑)

if "验证成功" in driver.page_source:

    print("滑块验证码突破成功!")

else:

    print("滑块验证码突破失败,需重新尝试")

 

driver.quit() # 关闭浏览器

 

四、爬虫合规性与注意事项

 

1. 遵守robots协议:爬取前查看目标网站的 robots.txt (如 https://www.xxx.com/robots.txt ),不爬取禁止访问的目录;

2. 控制请求频率:即使使用代理,也需添加 time.sleep(random.uniform(1, 3)) ,避免给网站服务器造成压力;

3. 避免过度爬取:仅获取必要数据,不下载无关资源(如图片、视频),尊重网站版权;

4. 应对反爬升级:若网站启用“指纹识别”(如Canvas指纹、WebGL指纹),需使用 selenium+undetected-chromedriver 隐藏浏览器指纹。

 

本文从“UA伪装”“代理池搭建”“验证码识别”三个维度,讲解了Python爬虫突破反爬的核心方案,每个场景均提供可直接运行的实战代码。反爬与反反爬是动态博弈的过程,关键在于模拟真实用户行为+持续关注网站反爬策略变化。

http://www.dtcms.com/a/410356.html

相关文章:

  • 华为发布开源超节点架构,以开放战略叩响AI算力生态变局
  • 从格伦的角度理解信息哲学
  • 网站建设分金手指专业三十WordPress 多用户数据
  • obsidian git操作及踩坑记录:ssh秘钥设置以及推送到多个远程仓库
  • 【Linux】网络部分——网络基础(Socket 编程预备)
  • 【音频】SIP服务器Yate搭建
  • 贵阳网站建设宏思锐达网站挂服务器后图片不显示
  • @tanstack/react-query:React 服务器状态管理与数据同步解决方案
  • RCNN系列边界框回归损失函数
  • 郑州专业网站制作建设python基础教程雪峰
  • Go基础:文件与文件夹操作详解
  • 鸿蒙:侧边栏显示与隐藏
  • 【开题答辩实录分享】以《基于爬虫的娱乐新闻采集系统设计与实现》为例进行答辩实录分享
  • BMAD方法论与自动化工具的协同演进:重塑Go语言微服务的技术债务
  • 月匣 - 百度推出的AI情感陪伴与剧情互动应用
  • dw网站建设教程网站建设费税率
  • 网站样版风格排版WordPress超级链接不跳转
  • Redis 五大核心数据结构知识点梳理
  • 微信小程序学习(一)
  • 零售企业档案检索慢?档案管理系统解决档案管理痛点
  • Docker 全阶段学习指南
  • Arbess从入门到实战(3) - 使用Arbess+GitLab实现Vue.js项目自动化部署
  • 智慧停车大屏数据分析与设计文档
  • 网站建设商家注册免费
  • 做网站后台系统的规范个人小程序商城
  • Linux 进程程序替换
  • 铜钟音乐前端技术解析
  • Flutter 运行IOS真机,提示无法打开“****”
  • Windows配置C/C++环境:MinGW+Vscode
  • Docker安装(Centos/Ubuntu/UOS)