抓包与代理池
一、抓包工具 Charles
Charles(青花瓷)是一款基于 HTTP 协议的代理服务器:让它成为电脑或手机的代理,所有请求经它转发,即可截取请求与响应进行分析。
1. 工作原理
客户端 → Charles(代理)→ 服务端
客户端 ← Charles(代理)← 服务端前提:运行 Charles 并配置代理端口(默认 8888),客户端指向该代理。
主要功能:HTTP/HTTPS 代理、流量控制(弱网模拟)、并发请求、重复发包(Repeat)、断点修改请求与响应。
2. HTTPS 抓包配置
先理解为什么需要证书。HTTPS 建连时,客户端会验证服务器证书的真伪(是否由可信机构签发、域名是否匹配),验证不通过就拒绝连接。抓包工具的原理是做「中间人」:
客户端 ←→ Charles(对客户端伪装成服务器)←→ 真实服务器Charles 给浏览器出示的是自己签发的证书,浏览器自然不认,连接直接失败。解决办法就是把 Charles 的根证书装进系统并设为「受信任」——相当于告诉浏览器「这张假证书也是可信的」,之后 Charles 就能把加密流量解密后再转发,你才能看到明文。配置步骤:
Help → SSL Proxying → Install Charles Root Certificate,安装到「受信任的根证书颁发机构」;Proxy → SSL Proxying Settings添加要解密的域名与端口(*:443),否则抓到的 HTTPS 内容是乱码;- PC 端浏览器配合 SwitchyOmega 等插件指向 127.0.0.1:8888 即可。
3. 断点调试
选中目标请求 → 右击勾选 Breakpoints,请求发出时会暂停,可以:
- 修改请求参数后再放行(构造测试数据)
- 修改响应内容,观察页面表现,快速定位接口与数据的关系
4. 安卓 / 模拟器抓包
App 爬虫的第一步是抓包看接口。以夜神模拟器为例(要求手机与电脑同一局域网):
cmd执行ipconfig查到电脑 IPv4 地址;- 模拟器 WiFi 设置 → 长按当前网络 → 修改网络 → 手动代理,填电脑 IP 与 8888 端口;
- 模拟器浏览器访问
chls.pro/ssl下载证书,到「设置 → 安全 → 从存储设备安装」导入。
TIP
高版本 Android(7+)出于安全考虑,App 默认只信任预装在系统目录里的证书,用户手动安装的证书对 App 无效——所以装完证书浏览器能抓、App 却抓不到。解决办法:把 Charles 证书伪装成系统证书写入系统目录(需要 root / 模拟器),或用 Xposed/LSPosed 模块(如 JustTrustMe)让 App 信任用户证书;部分 App 还会内置「证书锁定(SSL Pinning)」,需要用 Frida 等工具绕过。
抓到接口后,就可以用 requests 模拟 App 的请求头(通常是移动端 UA + 加密参数)直接采集,例如豆果美食 App:
import requests
url = 'https://api.douguo.net/home/notes/40/20'
headers = {
'User-Agent': 'Mozilla/5.0 (Linux; Android 7.1.2; SM-G973N) ... Mobile Safari/537.36'
}
data = {
'client': '4',
'_session': '1670347900014351564608872123',
'direction': '2',
'request_count': '1',
'sign_ran': '8b3bbbd68fead8c06020f4fc3f266e3f',
'code': '54adff5470d6b097',
}
response = requests.post(url, headers=headers, data=data)
print(response.json())二、免费代理采集与检测
1. 代理的作用
- 隐藏真实 IP,避免被服务器封禁
- 更换 IP 绕过频率限制(反反爬的核心手段之一)
免费代理站:快代理、89 免费代理、云代理、无忧代理、66 免费代理等。免费 IP 可用率通常不足 20%,采集后必须逐一测试。
2. 采集 + 验证流程
思路:爬代理站列表页 → 解析出 IP:端口 → 逐个请求 http://httpbin.org/ip 验证 → 可用的存入文件或数据库。
import requests
from lxml import etree
class ProxyPool:
def __init__(self):
self.base_url = 'https://www.kuaidaili.com/free/inha/{}/'
self.test_url = 'http://httpbin.org/ip'
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}
def get_response(self, url, proxies=None):
try:
return requests.get(url, headers=self.headers, proxies=proxies, timeout=3).text
except Exception as e:
print('请求有误:', e)
return None
def parse(self, html):
tree = etree.HTML(html)
for tr in tree.xpath('//table//tbody/tr'):
ip, port = tr.xpath('./td/text()')[0], tr.xpath('./td/text()')[1]
proxies = {'http': f'http://{ip}:{port}'}
self.verify(proxies)
def verify(self, proxies):
try:
response = requests.get(self.test_url, headers=self.headers,
proxies=proxies, timeout=2)
if response.status_code == 200:
print('可用:', proxies, response.text)
with open('proxy.txt', 'a') as f:
f.write(proxies['http'] + '\n')
except Exception:
print('超时淘汰:', proxies)
def run(self, pages=3):
for page in range(1, pages + 1):
html = self.get_response(self.base_url.format(page))
if html:
self.parse(html)
if __name__ == '__main__':
ProxyPool().run()WARNING
免费代理过期很快:入池前要验证,每次使用前也要验证,并定期重测清理失效 IP。
三、付费代理
「免费:除了免费没有优点;付费:除了付费没有缺点。」生产环境建议购买付费代理(如快代理、芝麻代理等):
- 注册账号,按项目选择套餐;
- 在订单页生成 API 提取链接(可设置提取数量、返回格式、分隔符);
- 代码里定期请求该链接获取新 IP,配合队列维护一个本地代理池。
使用私密代理(带认证)的示例:
import requests
from queue import Queue
from retrying import retry
class Crawler:
def __init__(self):
self.ip_url = 'https://dps.kdlapi.com/api/getdps/?secret_id=xxx&num=1&signature=xxx'
self.username, self.password = '账号', '密码'
self.ip_queue = Queue()
def get_ip(self):
"""后台线程:代理池不足时从 API 补充"""
while True:
if self.ip_queue.empty():
self.ip_queue.put(requests.get(self.ip_url).text.strip())
@retry(stop_max_attempt_number=3)
def get_data(self, url):
ip = self.ip_queue.get()
auth = {'user': self.username, 'pwd': self.password, 'proxy': ip}
proxies = {
'http': 'http://%(user)s:%(pwd)s@%(proxy)s/' % auth,
'https': 'http://%(user)s:%(pwd)s@%(proxy)s/' % auth,
}
response = requests.get(url, proxies=proxies, timeout=2, verify=False)
if response.status_code == 200:
self.ip_queue.put(ip) # 好用的 IP 放回去复用
else:
assert '状态码错误'
return response四、代理池的设计
一个完整的代理池包含四个模块:
采集器 ──→ 存储(Redis DB)──→ 校验器(定时重测)──→ 调度 API(随机取一个可用 IP)
↑__________________________________________________|
失效 IP 删除- 存储:Redis 的
zset,score 存可用分数(成功 +1,失败 -1,低于阈值删除) - 校验:定时任务批量重测,兼顾「刚采的」和「池里的」
- 调度:Flask/FastAPI 暴露
/get(随机取一个)与/pop(取出并删除)接口 - 使用方:爬虫请求失败时换一个 IP 重试;也可以把
dont_filter/重试逻辑与代理结合
社区现成方案可参考 proxy_pool,原理与上图一致。
五、小结
- App 爬虫三步走:抓包 → 分析接口 → 代码模拟
- 免费代理要「采集即验证、用前再验证」;付费代理用 API 提取 + 本地池维护
- 代理只是反反爬的一环,还需配合随机 UA、Cookie 管理、请求频率控制
- 代理失效被识别时,Charles 的 Repeat 与断点功能也能帮助复现和调试问题请求