Python编程实战 - Python实用工具与库 - 爬虫防封与代理机制

在进行网页爬取时,如果频繁访问同一网站,极有可能被网站识别为爬虫,从而封禁 IP 或要求验证码验证。 为了保证爬虫稳定、高效运行,我们需要了解并掌握 防封机制与代理使用方法

本章将介绍 Python 爬虫中常用的防封策略、代理原理及实战应用技巧。


一、为什么会被封

网站封禁爬虫主要是为了防止资源滥用与服务器过载。常见的封禁手段包括:

  1. IP 封禁:短时间内请求频繁,直接拉黑访问 IP。
  2. User-Agent 检测:识别请求头中是否包含浏览器标识。
  3. Referer 检查:判断请求是否来自正常页面跳转。
  4. Cookie 校验:验证登录状态或访问来源。
  5. 请求频率限制:同一用户短时间内过多请求触发反爬。

要应对这些情况,我们可以从 "伪装自己""多IP访问" 两个方向入手。


二、请求伪装:模拟真实用户访问

1. 设置请求头

requests 支持通过 headers 参数自定义请求头。 常见做法是添加浏览器信息,让服务器认为请求来自正常用户。

python 复制代码
import requests

url = "https://example.com"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                  "AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/122.0.0.0 Safari/537.36",
    "Referer": "https://www.google.com",
}
response = requests.get(url, headers=headers)
print(response.status_code)

2. 随机切换 User-Agent

为了避免单一 User-Agent 被识别为爬虫,可以在请求中随机切换浏览器标识。

python 复制代码
import random

user_agents = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/123.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Firefox/124.0",
    "Mozilla/5.0 (Linux; Android 10) Mobile Safari/537.36",
]

headers = {"User-Agent": random.choice(user_agents)}

每次访问时随机选择一个头部,能有效减少被识别风险。


3. 添加延时与随机等待

频繁访问网站最容易触发风控。 合理的做法是添加访问间隔,并随机化等待时间:

python 复制代码
import time
import random

time.sleep(random.uniform(1, 3))  # 等待1~3秒

这样能让访问节奏更像人类操作。


三、使用代理服务器(Proxy)

当 IP 被封时,使用代理服务器可以切换出口 IP,从而继续访问。

代理服务器会代替你访问目标网站,然后将结果返回。 Python 中可以通过 requests 轻松使用代理。


1. 设置代理参数

python 复制代码
proxies = {
    "http": "http://123.45.67.89:8080",
    "https": "http://123.45.67.89:8080",
}

response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
print(response.text)

如果代理有效,返回的 IP 将与本机不同。


2. 使用代理池(Proxy Pool)

手动设置代理不方便,可以使用 代理池 自动随机选取可用代理。

简单示例:

python 复制代码
import requests
import random
import time

proxies_list = [
    "http://111.22.33.44:8080",
    "http://222.11.55.66:8888",
    "http://77.88.99.100:3128",
]

def get_random_proxy():
    return {"http": random.choice(proxies_list), "https": random.choice(proxies_list)}

for i in range(5):
    proxy = get_random_proxy()
    try:
        res = requests.get("https://httpbin.org/ip", proxies=proxy, timeout=5)
        print(f"使用代理 {proxy['http']} -> {res.json()}")
    except Exception as e:
        print("代理失效:", e)
    time.sleep(random.uniform(1, 2))

3. 购买或搭建代理池

免费代理常常不稳定,建议:

  • 使用付费代理服务(如芝麻代理、快代理等)。
  • 自行搭建代理池服务,结合 Redis 存储和自动检测可用 IP。

一个简单的代理池架构:

复制代码
爬虫程序 → 请求代理池接口 → 返回可用代理 → 访问目标网站
代理池后台 → 定期检测代理可用性 → 清理无效IP

四、Cookie 与会话保持

某些网站需要登录才能访问数据,这时需要处理 Cookie 。 可以使用 requests.Session() 自动保持会话状态。

python 复制代码
session = requests.Session()
login_url = "https://example.com/login"
payload = {"username": "user", "password": "pass"}
session.post(login_url, data=payload)

# 登录成功后继续访问页面
resp = session.get("https://example.com/user/profile")
print(resp.text)

Session 会自动保存登录后的 Cookie 信息,避免每次请求重新认证。


五、验证码与高级防爬

有的网站会要求输入验证码或 JavaScript 加密验证请求。 常见应对思路包括:

  1. 人工辅助识别:遇到验证码暂停爬取,手动输入。
  2. OCR 识别验证码 :通过 pytesseract 识别简单图片验证码。
  3. 模拟浏览器行为 :使用 seleniumplaywright 执行网页中的 JS 逻辑。

示例:

python 复制代码
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://example.com")
print(driver.title)
driver.quit()

这种方式能绕过大部分基于 JS 渲染或验证的防爬机制。


六、异常与重试机制

网络请求容易超时或失败,建议添加异常重试机制。

python 复制代码
import requests
import time

def safe_request(url, retries=3):
    for i in range(retries):
        try:
            res = requests.get(url, timeout=10)
            if res.status_code == 200:
                return res.text
        except requests.RequestException:
            print(f"第 {i+1} 次请求失败,重试中...")
            time.sleep(2)
    return None

七、综合实战示例

综合以上技巧,我们可以实现一个稳定、抗封的爬虫:

python 复制代码
import requests, random, time

headers_list = [
    {"User-Agent": "Mozilla/5.0 Chrome/122.0.0.0"},
    {"User-Agent": "Mozilla/5.0 Firefox/124.0"},
]
proxies_list = [
    "http://123.45.67.89:8080",
    "http://222.111.55.66:8888"
]

def fetch(url):
    headers = random.choice(headers_list)
    proxy = {"http": random.choice(proxies_list), "https": random.choice(proxies_list)}
    try:
        response = requests.get(url, headers=headers, proxies=proxy, timeout=10)
        print("访问成功:", response.status_code, "IP:", proxy)
        return response.text
    except Exception as e:
        print("访问失败:", e)
        return None

for i in range(5):
    html = fetch("https://httpbin.org/ip")
    time.sleep(random.uniform(1, 3))

八、总结

策略 说明
请求伪装 设置随机 User-Agent、Referer 等头信息
请求间隔控制 使用随机延时,模拟真实用户行为
代理机制 通过代理IP切换访问来源
会话保持 使用 Session 管理登录状态
异常重试 防止临时网络错误导致程序中断
浏览器模拟 处理验证码或动态渲染内容

通过合理运用这些防封策略与代理机制,你的 Python 爬虫将更稳定、更高效、更接近真实用户访问行为,为后续数据采集与分析奠定坚实基础。

相关推荐
程序员爱钓鱼2 小时前
Python编程实战 - Python实用工具与库 - 操作Excel:openpyxl / pandas
后端·python·面试
后端小张2 小时前
【JAVA进阶】SpringBoot启动流程深度解析:从main方法到应用就绪的完整旅程
java·spring boot·后端·spring·spring cloud·java-ee·流程分析
猫头虎2 小时前
Rust评测案例:Rust、Java、Python、Go、C++ 实现五大排序算法的执行时间效率比较(基于 OnlineGDB 平台)
java·开发语言·c++·python·golang·rust·排序算法
爱吃烤鸡翅的酸菜鱼2 小时前
【Java】基于策略模式 + 工厂模式多设计模式下:重构租房系统核心之城市房源列表缓存与高性能筛选
java·redis·后端·缓存·设计模式·重构·策略模式
milanyangbo2 小时前
从局部性原理到一致性模型:深入剖析缓存设计的核心权衡
开发语言·后端·缓存·架构
IT_陈寒2 小时前
SpringBoot实战避坑指南:我在微服务项目中总结的12条高效开发经验
前端·人工智能·后端
恒风52122 小时前
实时显示鼠标的坐标值,注意事件的(event)
python·信息技术类·对口高考
JaguarJack2 小时前
Laravel ObjectId 性能最强体积最小的分布式 UUID 生成扩展
后端·laravel
ftpeak2 小时前
Rust 嵌入式开发的经验之谈
开发语言·后端·rust