
你是不是也遇到这种情况:辛辛苦苦写了几天爬虫,运行第一天就成功抓取了10万条数据,第二天降到5万,第三天直接被封IP,一周后所有账号全部阵亡?为什么90%的工作室都死在反爬虫机制面前?一次封号损失上万,如何避免这种悲剧?
别慌,今天我就把实战多年的爬虫高可用方案全部掏出来,从IP配置到反反爬技巧,手把手教你把爬虫效率提升300%。
首先,我们得明白为什么你的爬虫会被封。无非是以下几个原因:
1. 同一IP短时间内请求频率过高
2. 请求头特征明显,容易被识别为爬虫
3. Cookie或Session管理不当
4. IP池质量差,大量IP来自同一地区或ASN
解决方案是什么?没错,就是高质量的IP代理服务。但怎么选?怎么用?这才是关键。
一、IP代理选择:静态IP vs 动态IP vs 进程IP
静态IP:适合长期、稳定的爬取任务,比如电商价格监控、竞争对手分析。IP固定,不容易触发网站的IP频率限制,但成本较高,每个IP每月约5-10元。
动态IP:适合需要大量IP轮换的场景,如大规模数据采集。IP会定期更换,可以避免单一IP被标记,成本较低,每个IP每小时约0.1-0.5元。
进程IP:适合需要极高匿名性的场景,如社交媒体爬取。每个进程独立分配IP,隔离度高,但成本最高,每个进程每小时约1-3元。
根据我们的经验,对于大多数数据采集场景,"动态IP+静态IP"混合使用效果最佳。核心账号使用静态IP,批量采集任务使用动态IP,既能保证稳定性,又能控制成本。
二、IP代理配置实战
以Python为例,我们常用的代理配置方法:
```python
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
配置代理
proxies = {
'http': 'http://your_proxy_ip:port',
'https': 'https://your_proxy_ip:port'
}
创建会话,复用连接
session = requests.Session()
重试策略
retry = Retry(
total=3,
backoff_factor=1,
status_forcelist=[500, 502, 503, 504]
)
设置适配器和代理
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
设置请求头,模拟真实浏览器
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
}
发送请求
try:
response = session.get('https://target-website.com', headers=headers, proxies=proxies, timeout=30)
print(response.text)
except Exception as e:
print(f"请求失败: {e}")
```
三、IP轮换策略
单一IP再好,也扛不住高频请求。IP轮换是关键:
- 基于时间的轮换:每5-10分钟更换一次IP
- 基于请求数的轮换:每50-100个请求更换一次IP
- 基于响应状态的轮换:遇到429状态码或验证码立即更换IP
示例代码:
```python
import time
import random
class RotatingProxy:
def init(self, proxy_list):
self.proxy_list = proxy_list
self.current_proxy_index = 0
self.request_count = 0
self.last_change_time = time.time()
self.requests_per_proxy = 50 # 每个IP最大请求数
self.proxy_change_interval = 600 # IP更换间隔(秒)
def get_proxy(self):
current_time = time.time()
# 检查是否需要更换IP
if (self.request_count >= self.requests_per_proxy or
current_time - self.last_change_time >= self.proxy_change_interval):
self.current_proxy_index = (self.current_proxy_index + 1) % len(self.proxy_list)
self.request_count = 0
self.last_change_time = current_time
proxy = self.proxy_list[self.current_proxy_index]
self.request_count += 1
return {
'http': f'http://{proxy["ip"]}:{proxy["port"]}',
'https': f'https://{proxy["ip"]}:{proxy["port"]}'
}
使用示例
proxy_list = [
{"ip": "1.2.3.4", "port": 8080},
{"ip": "5.6.7.8", "port": 8080},
# 更多IP...
]
rotating_proxy = RotatingProxy(proxy_list)
在请求中使用
proxies = rotating_proxy.get_proxy()
response = requests.get('https://target-website.com', proxies=proxies, headers=headers)
```
四、反反爬虫高级技巧
请求间隔随机化:
python # 不要使用固定间隔,要随机 time.sleep(random.uniform(3, 8)) # 3-8秒随机间隔User-Agent轮换:
python user_agents = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", # 更多UA... ] headers['User-Agent'] = random.choice(user_agents)Cookie和Session管理:
```python
# 使用session保持cookie
session = requests.Session()
session.headers.update(headers)
# 定期更新cookie
if random.random() < 0.1: