动态代理IP怎么用?从提取到测试再到接入,爬虫实操流程详解

做爬虫的人大概率都遇到过这种情况:跑着跑着请求突然被目标站拦了,返回一堆403或者验证码页面。你盯着屏幕愣了几秒,心里清楚——IP被标记了。这时候你需要的不是换台电脑,而是一套靠谱的动态代理IP方案。
但”动态代理IP怎么用”这个问题,真不是拿到一个IP列表往代码里一塞就完事的。从你决定用哪种类型的代理,到怎么提取、怎么验证质量、怎么真正嵌进爬虫逻辑里,每一步都有讲究。今天这篇文章我就按实操顺序,把整个流程掰开了讲,你跟着走一遍就能跑起来。
先想清楚:你该用短效还是长效动态代理
很多人一上来就问”给我来点IP”,但没想清楚自己要什么节奏的。动态代理IP分两种主流形态,选错了后面全得返工。
| 对比维度 | 短效动态代理 | 长效动态代理 |
|---|---|---|
| IP存活时间 | 3~30分钟(可自定义) | 1~24小时(可自定义) |
| 适合场景 | 高频翻页采集、多页面轮询、短周期任务 | 需要同一IP持续在线数小时的长任务 |
| IP池规模 | 3000万+储备,覆盖300+省市 | 同样运营商合规线路,纯净度99.83% |
| 并发能力 | 无并发上限,平均延迟约0.03秒 | 无提取冷却,日均十万次以上请求 |
| 计费方式 | 包量(低至0.0023元/IP)或时长包月 | 按量(最低0.12元/IP)或按时长包时 |
我的建议是:如果你的爬虫是”跑完一批就换一批”的节奏,短效动态代理够用且成本最低;如果你的业务需要同一个IP保持在线几小时(比如模拟一个用户持续浏览),那就上长效的。网帆代理这两条线都有,注册之后还能领免费测试IP先跑跑看,不用一上来就掏钱。
提取IP:别急着写代码,先把参数定好
提取IP这件事看着简单,但有几个参数你提前想清楚,能省掉后面大量调试时间。
第一,地域。你要采的是哪个地区的站点?如果目标站有地域识别,你就得指定提取对应省市的IP。网帆代理支持精确到区县级别的筛选,也可以多城市混播,看你的需求。
第二,存活时长。短效代理默认给你3/5/10/15/30分钟几个档位,但实际支持1到30分钟自由定制。比如你每页请求间隔大概8秒,一个IP用5分钟足够翻60多页了,没必要开30分钟。
第三,协议。HTTP、HTTPS、SOCKS5都兼容,看你爬虫框架支持哪种。大部分Python爬虫用HTTP/HTTPS就够了。
参数定好之后,提取方式一般走API接口。下面是一个典型的提取请求示例:
import requests
# 提取短效动态IP(以网帆代理API为例,具体参数以控制台文档为准)
extract_url = "http://api.fanproxy.com/getip"
params = {
"username": "你的账号",
"password": "你的密码",
"num": 10, 一次提取10个
"province": "浙江", 指定省份,不填则全国随机
"city": "杭州", 指定城市,可选
"expire": 10, 存活10分钟
"protocol": "http" 协议类型
}
resp = requests.get(extract_url, params=params, timeout=10)
if resp.status_code == 200:
ip_list = resp.text.strip().split("")
print(f"成功提取 {len(ip_list)} 个IP")
for ip in ip_list[:3]:
print(ip)
else:
print(f"提取失败,状态码:{resp.status_code}")
提取回来的IP格式通常是 ip:port,你存到本地列表或者Redis里都行。注意一点:提取出来的IP是有时效的,短效代理过了存活时间就失效了,别存着不用,过期了白占额度。
测试IP质量:这步省了,后面全白干
我见过太多人拿到IP直接往爬虫里塞,跑了两百个请求发现一半超时、三分之一被目标站拒绝,然后回头骂代理质量差。其实很多时候是IP本身没问题,是你没做前置验证。
提取完IP,先跑一轮快速测试,主要看三个指标:
1. 连通性——能不能正常建立TCP连接,响应时间多少。
2. 出口IP一致性——你请求一个”查IP”的接口,返回的IP是不是你提取的那个,防止中间被劫持。
3. 目标站可达性——用这个IP去请求你真正要采的站点,看返回状态码是不是200。
测试代码不用写多复杂,核心逻辑就是并发请求、记录结果、过滤掉不合格的:
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
def test_single_ip(ip_port, target_url="https://www.example.com"):
"""测试单个IP的连通性和出口一致性"""
proxy = f"http://{ip_port}"
try:
第一步:测连通性 + 出口IP
r1 = requests.get(
"https://httpbin.org/ip",
proxies={"http": proxy, "https": proxy},
timeout=5
)
if r1.status_code != 200:
return ip_port, False, f"出口检测失败: {r1.status_code}"
real_ip = r1.json().get("origin", "")
expected_ip = ip_port.split(":")[0]
if real_ip != expected_ip:
return ip_port, False, f"出口IP不一致: {real_ip}"
第二步:测目标站可达性
r2 = requests.get(
target_url,
proxies={"http": proxy, "https": proxy},
timeout=8,
headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
)
if r2.status_code == 200:
return ip_port, True, "OK"
else:
return ip_port, False, f"目标站返回 {r2.status_code}"
except requests.exceptions.Timeout:
return ip_port, False, "超时"
except Exception as e:
return ip_port, False, str(e)
# 并发测试
ip_list = ["1.2.3.4:8080", "5.6.7.8:8080", "9.10.11.12:8080"] 你提取到的IP
valid_ips = []
with ThreadPoolExecutor(max_workers=10) as pool:
futures = {pool.submit(test_single_ip, ip): ip for ip in ip_list}
for future in as_completed(futures):
ip_port, is_valid, msg = future.result()
if is_valid:
valid_ips.append(ip_port)
else:
print(f"[剔除] {ip_port} -> {msg}")
print(f"测试完成:{len(valid_ips)}/{len(ip_list)} 个IP可用")
一般运营商直供的纯净IP,连通性通过率在95%以上。如果你测出来通过率低于80%,先检查是不是自己网络环境的问题(比如本地DNS解析异常),再考虑联系服务商排查。网帆代理的IP纯净度标称99.8%,正常情况下一轮测试筛完,剩下的基本都能直接用。
接入爬虫:三种常见写法,按你的框架选
IP测试通过了,接下来就是真正嵌入爬虫逻辑。根据你用的框架不同,接入方式有区别,我分三种情况说。
写法一:requests / httpx 直接代理
最简单直接,适合脚本类、小项目:
import requests
import random
# 从测试通过的池子里随机取一个
proxy = f"http://{random.choice(valid_ips)}"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept": "text/html,application/xhtml+xml",
}
session = requests.Session()
session.proxies = {"http": proxy, "https": proxy}
session.headers.update(headers)
# 正常发请求
resp = session.get("https://www.example.com/page/1", timeout=10)
print(resp.status_code, len(resp.text))
写法二:Scrapy 中间件方式
如果你的项目是Scrapy架构,推荐写一个代理中间件,这样IP轮换逻辑和爬虫逻辑解耦,维护起来清爽:
scrapy_proxies.py
import random
from scrapy import signals
class DynamicProxyMiddleware:
"""动态代理IP中间件:每次请求自动分配新IP"""
def __init__(self, ip_pool):
self.ip_pool = ip_pool 测试通过的IP列表
@classmethod
def from_crawler(cls, crawler):
middleware = cls(ip_pool=crawler.settings.get("PROXY_IP_POOL", []))
return middleware
def process_request(self, request, spider):
if not self.ip_pool:
return 池子空了,走默认逻辑或触发重新提取
ip_port = random.choice(self.ip_pool)
request.meta["proxy"] = f"http://{ip_port}"
request.meta["download_timeout"] = 10
每次请求换一个UA,降低指纹特征
request.headers["User-Agent"] = random.choice(spider.user_agents)
settings.py 里注册
DOWNLOADER_MIDDLEWARES = {
"myproject.middlewares.DynamicProxyMiddleware": 610,
}
PROXY_IP_POOL = ["1.2.3.4:8080", "5.6.7.8:8080", ...]
写法三:隧道代理,免维护IP池
如果你不想自己管IP的提取、测试、过期回收这一整套流程,可以用隧道代理。你只需要配一个统一的入口地址,后面IP的轮换、调度、失效替换全部由服务端自动完成。对开发来说,代码里就一行代理配置的事:
# 隧道代理接入——你只需要这一个地址
tunnel_proxy = "http://用户名:密码@隧道入口地址:端口"
session = requests.Session()
session.proxies = {"http": tunnel_proxy, "https": tunnel_proxy}
# 每次请求自动走不同IP,不用你操心
for page in range(1, 51):
url = f"https://www.example.com/list?page={page}"
resp = session.get(url, timeout=10)
正常解析...
if resp.status_code != 200:
print(f"第{page}页异常,状态码{resp.status_code},继续下一页")
continue
网帆代理的隧道代理支持1到10分钟IP存活周期自定义,你可以设成”一次一换”(每次请求都是新IP),也可以设成”稳定连续访问”(同一IP保持几分钟)。后台还有可视化的监控面板,实时看IP消耗、在线状态,不用自己写日志去猜。
几个容易踩的坑,提前说
超时别设太短。代理多了一跳网络,延迟会比直连高一点。网帆代理平均延迟在0.03秒左右,但加上目标站本身的响应时间,你请求超时建议设8~15秒。设成3秒的话,正常IP也会被判超时,白白浪费。
加个重试机制,但别死磕。单个IP请求失败,换下一个IP重试一次就够了。如果连续3个IP都失败,大概率是目标站那边有问题(比如临时限流),这时候应该暂停几秒再恢复,而不是疯狂换IP硬怼。
import time
def fetch_with_retry(url, ip_pool, max_retries=3):
for i, ip_port in enumerate(ip_pool[:max_retries]):
proxy = f"http://{ip_port}"
try:
resp = requests.get(
url,
proxies={"http": proxy, "https": proxy},
timeout=10,
headers=headers
)
if resp.status_code == 200:
return resp
elif resp.status_code in (403, 429):
被限流,等几秒再试
time.sleep(3)
continue
except Exception:
continue
重试次数用完,记录日志,跳过这条
print(f"[WARN] {url} 重试{max_retries}次仍失败,跳过")
return None
IP池别一次提太多。短效代理有存活时间,你一次提500个IP但任务只跑10分钟,后面400个全浪费了。按需提取,跑完一批再提下一批,成本最可控。网帆代理的包量计费是0.0023元/IP起,量大的话还有赠送比例,但前提是别浪费。
别所有请求共用一个Session。如果你用requests.Session,代理是绑定在session上的。多线程场景下每个线程应该有自己的session,或者每次请求前重新设置proxy,不然会出现线程A的请求走了线程B的IP,日志根本对不上。
常见问题
Q1:我提取的IP测试都通过了,但跑爬虫的时候还是频繁被目标站拒绝,怎么回事?
大概率不是IP本身的问题,而是你的请求行为太”机器”了。检查一下:请求间隔是不是太规律(比如精确每2秒一次)?User-Agent是不是从头到尾没变过?有没有带上正常的Referer和Cookie?代理IP解决的是”你是谁”的问题,但”你怎么访问”的行为特征也得模拟得像人。把请求间隔加个随机抖动(比如1.5~4秒之间随机),UA轮换一下,大部分情况就好了。
Q2:短效代理的IP存活时间到了,我正在跑的任务会中断吗?
如果你用的是隧道代理,不会。隧道入口是固定的,IP到期了服务端自动给你调度新的,你的代码完全无感知。但如果你是自己提取IP池、手动管理的那种,IP过期后那个IP就废了,你需要在任务逻辑里判断”当前IP是否快到期”,提前从池子里取下一个。建议存活时间设得比单轮任务周期长一些,留个buffer。
Q3:我同时跑多个爬虫任务,IP会冲突吗?
不会。每个任务独立提取自己的IP,或者走隧道代理时服务端会做隔离调度。但有一个注意点:如果你的多个任务采的是同一个目标站,即使IP不同,短时间内大量请求打过去也可能触发目标站的全局限流。这种情况建议错开任务启动时间,或者把总QPS控制在合理范围内。网帆代理单秒无并发上限,但目标站那边可没有这个承诺。
Q4:第一次用,怎么低成本验证代理质量再决定要不要长期用?
网帆代理注册之后会送免费测试IP(短效最高2000个,长效有12小时试用额度),你拿这些免费IP跑一遍上面说的提取→测试→接入流程,把整个链路走通。重点看三个数据:IP提取成功率、测试通过率、实际跑爬虫时的请求成功率。如果三项都在95%以上,说明这条线路适合你的业务,再根据实际用量选包量还是包月。别一上来就买大套餐,先小量跑个一两天,数据说话。
