初级爬虫反爬应对:解决 403、IP 限制的简单方法

在 Python 爬虫入门实践中,新手最常遇到的两大 "拦路虎" 莫过于 403 Forbidden 错误和 IP 限制。这两种反爬机制是网站最基础的防护手段,却常常让刚接触爬虫的开发者无从下手。本文将从问题本质出发,分享 3 种简单易操作、可直接落地的解决方案,帮助新手快速突破基础反爬限制,顺利完成数据采集。

一、先搞懂:403 和 IP 限制的核心原因

在解决问题前,我们需要明确网站为何会抛出这些限制,才能针对性应对:

  • 403 Forbidden 错误:服务器识别出请求不符合规范,拒绝提供服务。常见原因包括:未携带浏览器标识(User-Agent)、请求频率过高、缺少必要的请求头参数,或是服务器直接禁止爬虫访问。
  • IP 限制:网站通过记录访问 IP 的请求次数,对短期内高频访问的 IP 进行封禁(临时或永久),本质是防止恶意爬虫对服务器造成压力。比如连续 1 分钟发送 100 次请求,IP 可能被限制几小时甚至几天无法访问。

这两种问题的核心矛盾的是:服务器将爬虫请求与正常用户请求区分开来。因此,我们的应对思路也很明确 ------ 让爬虫 "伪装" 成正常用户,同时控制请求频率,减少服务器警惕。

二、解决方案 1:伪装请求头,破解 403 基础限制

网站首先通过请求头(Request Headers)判断访问来源。默认情况下,Python 的 requests 库发送的请求头会暴露 "爬虫身份"(如 python-requests/2.31.0),导致服务器直接返回 403。

操作步骤:

  1. 获取正常用户的请求头

    • 打开目标网站(如某电商商品页),按 F12 打开开发者工具,切换到「Network」(网络)选项卡。
    • 刷新页面,点击任意一个请求(如商品接口),在右侧「Headers」(请求头)中找到「User-Agent」(浏览器标识),复制其值(示例:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36)。
  2. 在爬虫中添加请求头 :将复制的 User-Agent 封装到请求头字典中,通过 requests.get()headers 参数传入。为了更逼真,还可以添加 Referer(来源页)、Accept(接收数据格式)等参数。

示例代码:

python

运行

复制代码
import requests

# 目标 URL(示例:某公开数据接口)
url = "https://example.com/api/data"

# 伪装成浏览器的请求头
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
    "Referer": "https://example.com",  # 来源页,模拟从官网跳转
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"  # 接收的数据格式
}

# 发送请求
response = requests.get(url, headers=headers)
if response.status_code == 200:
    print("请求成功!")
    print(response.text)
else:
    print(f"请求失败,状态码:{response.status_code}")

注意事项:

  • User-Agent 可以多准备几个(不同浏览器、不同系统),避免单一标识被识别。
  • 不要随意修改 Host 等核心请求头参数,否则可能导致请求失效。

三、解决方案 2:控制请求频率,避免 IP 被封禁

即使伪装了请求头,若请求频率过高(如每秒发送 10 次请求),服务器依然会判定为爬虫,进而限制 IP。控制请求速度是解决 IP 限制的基础方法,简单且无成本。

操作步骤:

  1. 添加随机延迟 :使用 time 模块的 sleep() 函数,在每次请求后添加随机时长的延迟(推荐 1-5 秒),模拟用户浏览时的停顿。
  2. 避免并发请求:新手初期尽量使用单线程爬虫,不要盲目使用多线程、多进程,否则会导致请求频率暴增。

示例代码:

python

运行

复制代码
import requests
import time
import random

url = "https://example.com/api/data"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}

# 循环请求(模拟采集多页数据)
for page in range(1, 10):  # 采集1-9页
    try:
        full_url = f"{url}?page={page}"  # 拼接分页URL
        response = requests.get(full_url, headers=headers)
        if response.status_code == 200:
            print(f"第{page}页采集成功")
            # 处理数据(如解析、保存)
        else:
            print(f"第{page}页采集失败,状态码:{response.status_code}")
        
        # 随机延迟1-3秒,避免频率过高
        time.sleep(random.uniform(1, 3))
    except Exception as e:
        print(f"第{page}页采集出错:{str(e)}")
        time.sleep(5)  # 出错时延迟更久,避免持续报错

优化技巧:

  • 延迟时间可根据网站响应速度调整:若网站加载慢,可适当延长延迟(3-5 秒);若网站响应快,1-2 秒即可。
  • 遇到 429 Too Many Requests 状态码(请求过于频繁),说明延迟时间不足,需进一步延长。

四、解决方案 3:使用代理 IP,突破 IP 封禁限制

如果已经出现 IP 被封禁(无论怎么请求都返回 403 或 503),或者需要高频采集数据,仅靠控制频率无法满足需求,此时需要使用代理 IP 来更换访问身份。

核心原理:

代理 IP 相当于 "中转站",爬虫的请求会先发送到代理服务器,再由代理服务器转发到目标网站。网站只能识别代理 IP,无法获取真实 IP,从而避免真实 IP 被封禁。

操作步骤:

  1. 获取免费代理 IP:新手可先使用免费代理 IP 练手(生产环境建议使用付费代理,稳定性更高),推荐来源:

  2. 在爬虫中配置代理 IP :通过 requests.get()proxies 参数传入代理 IP,支持 HTTP 和 HTTPS 协议。

示例代码:

python

运行

复制代码
import requests
import time
import random

url = "https://example.com/api/data"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}

# 免费代理 IP 列表(建议多准备几个,定期更换)
proxies_list = [
    {"http": "http://123.45.67.89:8080", "https": "https://123.45.67.89:8080"},
    {"http": "http://98.76.54.32:3128", "https": "https://98.76.54.32:3128"}
]

for page in range(1, 10):
    # 随机选择一个代理 IP
    proxies = random.choice(proxies_list)
    try:
        full_url = f"{url}?page={page}"
        # 配置代理发送请求,超时时间设为10秒(避免代理失效导致卡壳)
        response = requests.get(full_url, headers=headers, proxies=proxies, timeout=10)
        if response.status_code == 200:
            print(f"第{page}页采集成功,使用代理:{proxies['http']}")
        else:
            print(f"第{page}页采集失败,状态码:{response.status_code}")
        
        time.sleep(random.uniform(2, 4))
    except Exception as e:
        print(f"第{page}页采集出错(代理可能失效):{str(e)}")
        # 代理失效时,更换下一个代理,延迟5秒
        time.sleep(5)

注意事项:

  • 免费代理 IP 稳定性较差,可能存在失效、速度慢等问题,建议定期更新代理列表。
  • 若使用代理后仍出现 403,可能是代理 IP 已被网站封禁,需更换新的代理。
  • 生产环境推荐使用付费代理服务(如阿布云、芝麻代理),提供高可用、高匿的代理 IP,支持自动切换,效率更高。

五、常见问题排查与避坑指南

  1. 添加了请求头仍返回 403
    • 检查 User-Agent 是否正确,是否带有特殊字符。
    • 尝试添加 Cookie 参数(从浏览器中复制真实 Cookie,模拟登录状态)。
  2. 代理 IP 无法使用
    • 确认代理 IP 的协议(HTTP/HTTPS)与目标 URL 一致(HTTPS 网站需用 HTTPS 代理)。
    • 测试代理 IP 是否有效(可通过 requests.get("https://httpbin.org/ip", proxies=proxies) 查看返回的 IP 是否为代理 IP)。
  3. 请求频率已经很低仍被限制
    • 可能是网站对同一 IP 的每日请求次数有限制,需更换代理 IP 或次日再试。
    • 避免在高峰时段(如电商平台促销期间)采集,服务器反爬策略会更严格。

六、总结

对于爬虫新手来说,解决 403 和 IP 限制的核心逻辑是 "模拟正常用户行为":

  1. 用请求头伪装浏览器身份,破解基础 403 限制;
  2. 控制请求频率,减少服务器警惕,避免 IP 被封禁;
  3. 必要时使用代理 IP 更换访问身份,突破已有的 IP 限制。

这三种方法操作简单、成本低,足以应对大部分初级反爬场景。在实际应用中,建议优先组合使用(如 "请求头 + 延迟 + 代理 IP"),既能提高采集成功率,又能保护真实 IP 安全。随着技术积累,再逐步学习 Cookie 池、验证码识别等更高级的反爬应对技巧。

注意:爬虫采集数据时需遵守网站的 robots.txt 协议,不得用于商业用途或恶意攻击服务器,避免触犯法律风险。

相关推荐
Michelle802339 分钟前
24大数据 16-1 函数复习
python
dagouaofei1 小时前
AI自动生成PPT工具对比分析,效率差距明显
人工智能·python·powerpoint
ku_code_ku1 小时前
python bert_score使用本地模型的方法
开发语言·python·bert
祁思妙想1 小时前
linux常用命令
开发语言·python
流水落花春去也1 小时前
用yolov8 训练,最后形成训练好的文件。 并且能在后续项目使用
python
Serendipity_Carl1 小时前
数据可视化实战之链家
python·数据可视化·数据清洗
失败又激情的man1 小时前
爬虫逆向之云片滑块验证码
爬虫
深蓝电商API1 小时前
从数据采集到商业变现:网络爬虫技术的实战与边界
android·爬虫
小裴(碎碎念版)2 小时前
文件读写常用操作
开发语言·爬虫·python
TextIn智能文档云平台2 小时前
图片转文字后怎么输入大模型处理
前端·人工智能·python