做爬虫这事儿,写代码其实是最简单的一步。真正让人头大的,是跑着跑着IP被封了、请求全403了、数据采到一半就断了。尤其是你刚入门,对着满屏的报错信息,连是代码写错了还是网络问题都分不清。今天这篇文章我就把"代理IP怎么配进爬虫"这件事掰开了揉碎了讲,你跟着步骤走,基本一次就能跑通。
先搞清楚:你的爬虫到底需不需要代理IP
别一上来就买代理,先判断你的场景。如果你的爬虫只是偶尔抓个两三条数据,目标网站也没啥反爬机制,那用本机IP直接请求就行,没必要多此一举。但下面这几种情况,代理IP基本是刚需:
第一,目标网站有频率限制。你连续请求同一个接口,对方发现IP没变、请求太密集,直接给你429或者封IP。这时候你需要不断换IP,让每次请求看起来像不同用户发出来的。
第二,你需要采集的数据量比较大。比如你要抓某个平台几百个城市的门店信息,用同一个IP跑几个小时,大概率中途就会被限流。这时候代理IP池的价值就体现出来了——你手里有一大堆IP可以轮换着用。
第三,你需要模拟不同地区的访问。有些网站的内容会根据IP归属地展示不同版本,比如不同城市的房价、不同地区的商品列表。这时候你需要指定城市级别的代理IP,让请求"看起来"是从那个城市发出去的。
简单说,只要你的爬虫不是"发一次请求就完事"的玩具项目,代理IP就该安排上。
三种代理IP,别选错了白花钱
市面上代理IP大致分三类,很多新手一上来就懵:到底该买哪种?我直接给你一张对照表,你对着自己的需求看就行:
| 类型 | IP存活时间 | 适合场景 | 一句话总结 |
|---|---|---|---|
| 短效动态IP | 3~30分钟 | 高频轮换、大规模数据采集、反爬严格的网站 | 用完即换,IP池大,不容易被识别 |
| 长效静态IP | 1~24小时 | 需要一段时间内保持同一IP的任务 | 比短效稳定,比固定灵活 |
| 固定IP | 长期不变 | 对稳定性要求很高、IP需求量不大的场景 | 一个IP用到底,纯净度高 |
我个人的建议是:新手第一次跑通,优先选短效动态IP。原因很简单——短效IP的池子大、更新快,你不用操心"这个IP还能不能用"的问题,每次请求换一个,容错率最高。等你的项目跑稳了、对IP的存活时间有明确需求了,再考虑长效或者固定IP。
说到具体服务商,我目前用的是神龙HTTP,国内三大运营商正规授权的IP资源,池子有3000万+,覆盖300多个城市节点。我选它主要看两点:一是IP纯度标称99.8%,实际跑下来可用率确实高,很少遇到拿到一个IP结果连不通的情况;二是它的API接口文档写得比较清楚,你不用对着代码猜参数,照着文档调就行。短效动态IP那边支持3/5/10/15/30分钟不同时长,计费方式有包量和包时两种,个人测试阶段用包时比较划算,不用一次囤太多。
手把手:把代理IP塞进你的爬虫代码里
下面这段代码我用Python写的,逻辑很直白:从神龙HTTP的API拿一个代理IP,然后带着这个IP去请求目标页面。你只需要把API地址和密钥换成你自己的就行。
import requests
import time
神龙HTTP API地址(替换成你自己的)
PROXY_API = "https://api.shenlongip.com/getip?key=你的密钥&num=1&format=json"
def get_proxy():
"""从神龙HTTP获取一个短效动态代理IP"""
resp = requests.get(PROXY_API, timeout=10)
data = resp.json()
返回格式一般是 {"ip": "1.2.3.4", "port": 8080, "expire": 300}
proxy_ip = data["ip"]
proxy_port = data["port"]
return f"http://{proxy_ip}:{proxy_port}"
def fetch_page(url, proxy):
"""带着代理IP去请求目标页面"""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
proxies = {
"http": proxy,
"https": proxy
}
try:
resp = requests.get(url, headers=headers, proxies=proxies, timeout=15)
if resp.status_code == 200:
return resp.text
else:
print(f"请求失败,状态码:{resp.status_code}")
return None
except requests.exceptions.ProxyError:
print("代理连接失败,换一个IP重试")
return None
except requests.exceptions.Timeout:
print("请求超时")
return None
主流程
target_url = "https://example.com/data"
max_retry = 3
for i in range(max_retry):
proxy = get_proxy()
print(f"第{i+1}次尝试,使用代理:{proxy}")
result = fetch_page(target_url, proxy)
if result:
print("采集成功!")
break
time.sleep(2) 换IP前稍等两秒,别太急
几个关键点我单独拎出来说一下:
proxy格式别写错。HTTP代理的格式是 http://IP:端口,注意前面要带协议头。如果你用的是SOCKS5协议,那就写成 socks5://IP:端口。神龙HTTP默认支持HTTP/HTTPS/SOCKS5三种协议,你在API请求的时候指定一下就行。
一定要加超时和重试。代理IP再稳定,网络环境也不可能100%完美。你代码里如果不做异常处理,一个IP连不通整个脚本就卡死了。上面代码里我用了try-except加循环重试,这个结构你直接抄就行。
请求间隔别太短。就算你每次换了一个新IP,如果一秒钟发出去十几个请求,目标网站还是能识别出异常。建议每次请求之间加1~3秒的随机延迟,模拟正常人的操作节奏。
跑起来之后,这几个坑我替你踩过了
坑一:拿到IP但连不上。这种情况一般是IP已经过期了。短效IP的存活时间就那几分钟,如果你从API拿到IP之后隔了十几秒才用,可能已经失效了。解决办法:拿到IP立刻用,别缓存。如果确实需要缓存,把存活时间设短一点,比如只缓存30秒。
坑二:同一个IP被目标网站标记了。虽然你换了IP,但如果你的请求头、请求频率、访问路径完全一样,有些严格的反爬系统还是能关联起来。建议每次请求稍微随机化一下User-Agent、请求头顺序,别每次都一模一样。
坑三:城市定位没生效。你指定了要某个城市的IP,但实际请求出去发现归属地不对。这个一般是IP池里那个城市的资源暂时不够,系统给你分配了附近的。神龙HTTP支持300+城市级精准定位,如果你发现某个小城市经常定位不准,可以联系他们的技术支持确认一下资源覆盖情况,或者改用省份级别的定位,命中率会高很多。
坑四:HTTPS请求报错。有些代理只支持HTTP协议,你拿它去请求HTTPS的网址就会握手失败。确认一下你拿到的代理是否支持HTTPS,神龙HTTP的IP是支持HTTP/HTTPS/SOCKS5的,但你在代码里proxies字典里两个都要写上,别只写了http漏了https。
常见问题,问得最多的几个
Q1:我刚开始学爬虫,预算不多,怎么买代理IP比较合理?
别一上来就买大套餐。先用包时模式开个最小规格,跑通你的项目逻辑,确认代理IP确实能解决你的问题之后,再根据实际用量升级。神龙HTTP的短效动态IP支持包时计费,你按小时买,用多少算多少,测试阶段一天花不了几块钱。等你的项目稳定了、日均请求量上来了,再考虑包量或者企业定制方案,单价会低很多。
Q2:代理IP的"可用率99.9%"是什么意思?我实际用会不会有连不通的?
99.9%的可用率意味着你拿1000个IP,大概有1个可能连不通或者响应异常。这不是说你的代码会报错,而是说在极端情况下个别IP质量不达标。所以你的代码里一定要写重试逻辑——连不通就换一个IP再来,连续换3~5次还连不通,再考虑是不是网络本身有问题。神龙HTTP那边有实时监控,如果某个IP持续异常会被自动剔除出池子,你正常用基本感知不到。
Q3:我用Python的Scrapy框架,代理IP怎么配进去?
Scrapy里配代理比requests稍微多一步。你在settings.py里加一个PROXIES字典,然后在你的spider里通过meta参数传给每个请求。核心写法是这样的:
settings.py
PROXIES = {
"http": "http://1.2.3.4:8080",
"https": "http://1.2.3.4:8080"
}
spider.py 里
def parse(self, response):
每次请求动态设置代理
next_request = Request(
url="https://example.com/page2",
meta={"proxy": self.get_new_proxy()}, 自己写个方法从API拿新IP
callback=self.parse
)
return [next_request]
逻辑和requests一样,就是代理IP的传递方式从proxies参数变成了meta里的proxy字段。如果你用Scrapy的proxy中间件,还可以做更复杂的轮换策略,但新手阶段手动换就够了。
Q4:我的爬虫需要同时跑多个任务,代理IP够用吗?会不会互相冲突?
不会冲突。每个请求拿到的IP是独立的,你开10个线程或者10个进程,每个各自从API拿自己的IP,互不影响。神龙HTTP那边支持高并发提取,你同时请求几十个IP它都能正常返回。独特需要注意的是你本地的网络带宽和CPU,别开太多线程把机器跑满了。一般个人项目开5~10个并发线程,配短效动态IP,体验是很流畅的。
最后说一句,代理IP这个东西,工具本身不复杂,复杂的是你怎么把它嵌进你的工作流里。第一次跑通之后你会发现,后面就是调参数、调频率、调重试策略的事。别被"代理IP"三个字吓住,它就相当于给你的爬虫换了一副"面孔",让你能更稳定、更从容地去采集你需要的公开数据。把上面代码里的API地址和密钥换成你自己的,跑一遍,通了就通了,没通就看下报错信息,大概率是格式或者超时的问题,改一下就行。


