所有分类
  • 所有分类
  • 攻略

爬虫任务动态代理IP,请求重试异常自愈代码示例详解

爬虫任务动态代理ip+请求重试异常自愈代码示例详解,一篇就能跑通
关键词:python爬虫代理IP自动切换、高匿代理池搭建、requests重试装饰器、免费代理ip测试、反爬403自愈方案、爬虫超时异常处理、动态代理ip购买推荐

一、为什么你的爬虫总被封?
写完解析规则,跑了两页就403,再跑直接Timeout,八成是IP被拉黑。目标站点现在普遍上了“反爬套餐”:同IP请求频次>30次/5min就弹验证码,再狠点直接返回空数据。静态代理列表早就过时,只有“动态代理IP+自动重试+异常自愈”才能续命。

二、动态代理IP池到底长啥样?
别被“池”吓到,核心就三句话:

  1. 买接口→返回“代理IP:端口”json,比如http://api.xxx.com/get?num=10&type=1,每次掉用给10个高匿IP。
  2. 本地维护一个队列,爬虫线程每次pop一个IP,用完塞回尾部并记录耗时、失败次数。
  3. 失败>3次自动剔除,队列长度<5时触发补充。整个逻辑30行代码就能跑,后面直接给。

三、requests+Retry+自愈,代码直接搬
pip install requests retrying,复制下面这段,改两行就能用:

import requests, random, time, json
from retrying import retry
from queue import Queue

# 1. 动态拉代理
def fetch_ips():
    api = 'http://api.xxx.com/get?num=20&type=1'
    return [f"http://{ip}" for ip in requests.get(api, timeout=5).json()['data']]

# 2. 失败自动换IP
class ProxyPool:
    def __init__(self):
        self.q = Queue()
        self._fill()
    def _fill(self):
        for ip in fetch_ips():
            self.q.put({'ip': ip, 'fail': 0})
    def get(self):
        if self.q.qsize() < 5:
            self._fill()
        return self.q.get()
    def feedback(self, proxy, ok):
        if ok or proxy['fail'] >= 3:
            return
        proxy['fail'] += 1
        self.q.put(proxy)

pool = ProxyPool()

# 3. 装饰器:超时+重试+自愈
@retry(stop_max_attempt_number=4, wait_fixed=2000)
def safe_get(url):
    proxy = pool.get()
    try:
        r = requests.get(url, proxies={'http': proxy['ip'], 'https': proxy['ip']},
                         headers={'User-Agent': random.choice(UA_LIST)},
                         timeout=8)
        if r.status_code == 200 and len(r.content) > 1000:
            pool.feedback(proxy, True)
            return r.text
        else:
            raise Exception('block')
    except Exception as e:
        pool.feedback(proxy, False)
        raise e

# 4. 业务侧直接调
for page in range(1, 101):
    html = safe_get(f'https://example.com/article?page={page}')
    parse(html)  # 你的解析函数
    time.sleep(random.uniform(0.5, 1.5))

跑起来后,控制台会看到“fail→换IP→重试”循环,全程无人工,24h稳抓几千页数据。

四、免费代理能不能白嫖?
可以,但时间也是钱。免费代理平均可用率5%,还要自己写检测:

  • 先往httpbin.org/ip发请求,回显IP与代理一致才算高匿;
  • 再测访问目标站点,延迟>3s直接丢。
    一套下来代码量翻倍,且随时失效,适合练手,真上线还是买动态代理IP省心,平均1~2分/次,成本远低于重新抓。

五、常见坑速查表

  1. https站点忘记加verify=False,直接SSLError。
  2. 代理返回空响应但status=200,记得加“内容长度”校验,防假200。
  3. retrying装饰器默认只在函数抛异常时才重试,想对特定状态码重写得自己raise。
  4. 多线程场景下Queue要加锁,或者直接用线程安全的queue.Queue,别用list.pop。

六、把代码做成微服务
如果公司级项目,建议把代理池独立成Flask服务:/get_proxy返回一个最佳IP,/report反馈失败次数,爬虫端只负责调用,逻辑解耦,后续换语言也不折腾。

七、动态代理IP购买避坑
看三点:

  • 是否支持“每次请求换IP”,而不是固定5分钟才变;
  • 有没有白名单+账密双重鉴权,方便本地和云函数同时跑;
  • 是否给响应时间<2s的SLA,不然再便宜也白搭。

采购代理IP请添加微信客户经理:x31471626

阅读全文
原文链接:https://sk5ip.com.cn/hangyezixun/pachongrenwudongtaidailiipqing/,转载请注明出处~~~
0
分享海报

爬虫任务动态代理IP,请求重试异常自愈代码示例

爬虫任务动态代理IP+请求重试异常自愈代码示例,让你的Python爬虫再也不被封

为什么你的爬虫总被封?

写爬虫最怕两件事:ip被封、数据没抓完。很多人以为把headers写全就万事大吉,结果跑不到十分钟就403,再换账号继续403,心态炸裂。问题根源是同一个IP高频访问,目标站点的防火墙直接把你当机器人。动态代理ip就是给爬虫披马甲,每请求一次换一张脸,防火墙认不出你,自然放行。

动态代理IP到底怎么玩?

动态代理≠随便找个免费IP。免费池子脏、慢、随时挂,真要用还得找高匿、支持HTTP/HTTPS/Socks5的付费短效代理,每次请求从API接口随机抽一个,3分钟失效就换下一批。市面上叫“动态转发”或“隧道代理”,一个入口地址背后海量IP轮换,省掉自己维护池子的麻烦,适合日采百万级数据的小团队。

请求重试+异常自愈思路

再稳的代理也会踩雷,网络抖动、IP被限速、目标站点返回521,这些都要在代码层兜底。核心思路:异常捕获→换IP重试→记录失败→超过阈值再报警。用requests+adapters+retrying,10行代码就能搞定,别傻傻手写while循环。

直接能跑的Python代码

import requests, random, time
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

PROXY_API = 'http://api.xxx.com/get?num=1&type=2&key=你的key&port=11&ts=3'
TARGET_URL = 'https://example.com/article/'

def get_proxy():
    return requests.get(PROXY_API).json()['list'][0]['proxy']

def safe_get(url, timeout=8, max_retry=5):
    s = requests.Session()
    retry = Retry(total=max_retry, backoff_factor=0.3, status_forcelist=[500,502,503,504,521,403])
    s.mount('http://', HTTPAdapter(max_retries=retry))
    s.mount('https://', HTTPAdapter(max_retries=retry))
    for i in range(max_retry):
        try:
            proxy = get_proxy()          # 每次重试都换新IP
            resp = s.get(url, proxies={'http': proxy, 'https': proxy}, timeout=timeout, headers={
                'User-Agent': random.choice(['Mozilla/5.0 (Win10)...','Mozilla/5.0 (macOS)...'])
            })
            if resp.status_code == 200:
                return resp.text
        except Exception as e:
            print(f'第{i+1}次失败,原因:{e},自动换IP再来')
            time.sleep(1)
    return None

html = safe_get(TARGET_URL)
print(html[:200])

把PROXY_API换成你自己的隧道地址,就能跑。代码逻辑:每次重试重新拉取代理,失败自动退避,5次都拿不到数据才返回None,避免死循环。

常见坑位提醒

  1. 代理返回502别急着重试,先sleep 0.5s,给代理网关一点喘息。
  2. headers里的User-Agent、Referer、Accept-Language三件套别偷懒,最好从真实浏览器复制。
  3. 并发量大时用协程+代理池,但动态转发本身有QPS限制,先问供应商上限再开线程,否则秒封通道。
  4. 日志一定落盘,记录“URL+代理IP+状态码+时间”,方便回捞失败任务,也便于向代理商索赔无效IP。

把代码做成微服务

单脚本够用,但长期跑建议封装成API:Flask暴露/crawl?url=xxx,内部调度代理+重试,前端只关心结果。Docker一把梭,挂到云函数,每天定时拉数据,手机躺收Excel。

一句话总结

动态代理ip是爬虫的防弹衣,重试自愈代码是防弹衣上的补丁;两者一起上,才能在高反爬战场里横着走。采购代理IP请添加微信客户经理:x31471626

阅读全文
原文链接:https://sk5ip.com.cn/hangyezixun/pachongrenwudongtaidailiipqing/,转载请注明出处~~~
0
分享海报

评论0

请先
显示验证码

社交账号快速登录

微信扫一扫关注
如已关注,请回复“登录”二字获取验证码