代理ip怎么用,Python异步请求保持长连接不掉线:从入门到不踩坑
——写给不想被反爬、不想被限流、还想薅数据的你
一、先别急着写代码,先搞清“代理ip”到底干嘛
很多人以为代理IP就是换个出口IP,其实它更像一次“整容”:服务器看到的不再是你的真面目,而是代理那张脸。只要脸够多,就能轮着用,反爬就认不出你。但脸也有质量:高匿、普匿、透明,优先级依次递减;住宅、机房、移动,权重依次升高。别贪便宜买“透明+机房”套餐,封得比脱单还快。
二、异步请求到底香在哪?
同步=排队打饭,一个请求不回来,后面全干等;异步=自助餐,拿着盘子想拿啥拿啥,回调通知你“菜好了”。Python里aiohttp
就是那只盘子,单线程轻松上千并发,内存还稳。再配合asyncio.Semaphore
做并发护栏,既跑得快又不把代理打死,良心。
三、长连接≠一直不断,而是“断了能自己续”
HTTP/1.1默认keep-alive
,但代理服务器为了省资源,经常60秒就踢人。踢了你别哭,把timeout
拆成total=None, connect=10, sock_read=30
,再配RetryClient
的retry_attempts=5
,断线自动重连,cookie、header无缝接力,服务器以为你还是刚才那个“人”。
四、代码模板直接抄,改四行就能跑
import aiohttp, asyncio
from aiohttp_retry import RetryClient
proxies = 'http://账号:密码@gate.xxx.com:8080' # 这里换成你的代理
sema = asyncio.Semaphore(300) # 并发数自己调
async def fetch(url):
async with sema:
retry_options = {'attempts': 5, 'start_timeout': 1, 'max_timeout': 30}
async with RetryClient(raise_for_status=False,
retry_options=retry_options,
connector=aiohttp.TCPConnector(ssl=False, limit=0)) as client:
async with client.get(url, proxy=proxies, timeout=aiohttp.ClientTimeout(total=None, sock_read=30)) as resp:
return await resp.text()
if __name__ == '__main__':
urls = ['https://httpbin.org/ip'] * 1000
print(asyncio.run(asyncio.gather(*[fetch(u) for u in urls])))
跑起来看日志,IP是不是每次都在变?变就对了。
五、不掉线的三个隐藏开关
1 心跳包:每30秒访问一次/favicon.ico
,让代理知道“我还活着”。
2 复用连接:把TCPConnector(limit=0)
打开,force_close=False
,同代理IP的socket会复用,TCP三次握手省掉。
3 IP自动轮换:在代理后台加“每次请求换IP”开关,或者本地用round_robin
列表,别让一个IP薅到秃。
六、常见翻车现场
❌ 代理带认证却写成proxies={'http': 'http://ip:port'}
,漏了账号密码,直接407。
❌ Windows下asyncio
事件循环报错,加一句asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
就能救。
❌ 目标站走HTTPS,代理却是HTTP,没加ssl=False
,握手直接RST。
七、进阶:把代理池做成服务
用redis
列表当队列,爬虫端lpop
一个IP,用完根据状态码决定lpush
回去还是zadd
进黑名单。再写个cron
定时health check
,响应>3秒的IP直接踢,保证池子里全是“活脸”。这样即使跑8小时长任务,也不用半夜起床换代理。
八、一句话省流
选高匿住宅代理 + aiohttp
异步 + 自动重连 + 心跳续命 = 稳如老狗,数据想怎么薅就怎么薅。
采购代理IP请添加微信客户经理:x31471626
评论0