爬虫使用代理IP的完整工作流程是怎样的

谷德IP代理 2026-03-05 10:37:09

下午六点,程序员小李盯着屏幕,眉头都皱成疙瘩了。

他写了个爬虫爬电商数据,前两百条顺得一批,可到了第三百条,直接疯狂报 403 Forbidden

爬虫使用代理IP的完整工作流程是怎样的

隔壁老员工路过瞟了一眼:“你IP被封了,换个代理继续跑就行。”


小李翻出收藏夹里那几个免费代理网站,一个个试——连不上的、慢到怀疑人生的、好不容易连上又秒封的。

折腾半小时,数据没抓几条,代码改了七八版。


说实话,这几乎是每个写爬虫的人,都踩过的坑。

代理IP这东西,说简单也简单,说复杂能把人绕晕。

今天我就把整套逻辑,掰开揉碎了讲明白。


代理IP在爬虫里的作用,说白了就是个“替身”。


你的真实IP,就像你出门带的身份证。

你去访问一个网站,人家会记下你的号。

去一两次没事,一天跑个上万次,人家立马反应过来:这肯定是机器。直接拉黑。


代理IP,就是帮你换张“临时身份证”再进门。

你的请求先发到代理服务器,再由它转给目标网站。

对方看到的IP是代理的,你的真实IP藏得严严实实。

就算被封,封的也是代理,换一个继续,根本伤不到你自己。


整个流程就两件事:

第一,怎么拿到靠谱的代理;

第二,怎么在代码里用起来。


先说说怎么搞代理。

市面上的代理分三六九等。

免费的网上一搜一大把,随便写个小脚本就能爬下来。


def fetch_free_proxies(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    proxies = []
    for row in soup.select("table tr")[1:]:
        columns = row.find_all("td")
        ip = columns[0].text.strip()
        port = columns[1].text.strip()
        proxies.append(f"{ip}:{port}")
    return proxies


代码一跑,能抓一堆IP。

但问题也很明显:质量完全没保证——可能下一秒就失效,可能慢得要死,甚至还有可能是别人故意放的“钓鱼代理”。


想省心,就得用付费的。

数据中心代理速度快、便宜,但容易被识别;

住宅代理用的是真实用户IP,伪装效果拉满,价格贵点也正常。


代理拿到手,千万别直接扔代码里用,一定要先验货。

方法很简单:用这个代理去请求一个能显示IP的网站(比如 httpbin.org/ip),看看返回的IP是不是代理本身。


def test_proxy(proxy):
    proxies = {"http": f"http://{proxy}", "https": f"https://{proxy}"}
    try:
        response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=5)
        if response.status_code == 200:
            print(f"代理 {proxy} 可用")
            return True
    except:
        pass
    return False


能连通只是第一步。

你还要看速度快不快、是不是高匿(不暴露你用了代理)、有没有被目标网站拉黑。

一套测下来,十个里能用一两个都算不错了。


代理验完,就该在爬虫里用了。


最简单的方法:随机切换

维护一个代理列表,每次请求随便挑一个。


proxy_pool = [
    {"http": "http://123.45.67.89:8080"},
    {"https": "http://112.89.33.21:3128"}
]


for _ in range(10):
    proxy = random.choice(proxy_pool)
    try:
        response = requests.get(url, proxies=proxy, timeout=5)
        # 处理数据
    except:
        continue


优点是简单粗暴,缺点也明显:抽到失效代理直接报错。

稍微改进一下,就是智能轮询容错


class ProxyRotator:
    def __init__(self, proxies):
        self.proxies = cycle(proxies)


    def get_page(self, url):
        for _ in range(len(self.proxies)):
            current_proxy = next(self.proxies)
            try:
                resp = requests.get(url, proxies=current_proxy, timeout=8)
                return resp.text
            except:
                continue
        raise Exception("所有代理都挂了")


这个版本会一个个轮着试,直到找到能用的为止,比纯随机稳得多。


更高级的玩法,是代理池 + 中间件

自己搭一个代理池服务,自动爬免费IP、自动验证、自动去重、存数据库,再提供接口给爬虫调用。

配合 Scrapy 这类框架,配好中间件,你的爬虫主代码里,甚至不用写一句代理逻辑。


# settings.py配置
DOWNLOADER_MIDDLEWARES = {
    'scrapy_proxy_pool.middlewares.ProxyPoolMiddleware': 100,
}


PROXY_POOL_URL = 'http://your-proxy-pool:5010'  # 自建代理池API


这种方案适合大规模采集,能自动管理成千上万的IP。


有了代理还不够,访问策略也很重要。


光换IP不行,你得让请求看起来像真人。

User-Agent 要经常换,别从头到尾一个标识。

访问频率也要控制,一秒钟刷几十次,再好的代理也得被封。

加点随机延迟,模仿正常人的浏览节奏。


更聪明的做法是动态调整速度

成功率高就稍微快一点,遇到封禁就放慢节奏。


def adjust_delay(self, success):
    if success:
        self.current_delay = max(self.min_delay, self.current_delay * 0.9)  # 成功就加快
    else:
        self.current_delay = min(self.max_delay, self.current_delay * 1.5)  # 失败就减慢


最后说几个最容易踩的坑。


代理连不上最常见:IP端口写错、代理挂了、网络不通。

排查也简单:先测本地网,再单独用请求工具测代理。


超时也很烦人。

有些代理本身就慢,等半天没反应。

调大 timeout 是治标,换优质低负载代理才是治本。


需要账号密码的代理,格式别写错:


http://username:password@ip:port


把整套流程串起来,就是一个完整闭环:


采集代理源 → 验证可用性 → 放进代理池 → 爬虫请求时自动取用

→ 成功继续,失败标记剔除 → 定期补充新IP、清理失效IP


听起来有点麻烦,但只要跑通一次,后面一劳永逸。

你的爬虫就像随时能换身份,对方很难再把你识别出来。


小李听完这套思路,回去自己搭了个简易代理池。

第二天一看,爬虫安安稳稳跑了一整夜,抓了十几万条数据,一条封禁都没有。

他这才明白:

代理IP这东西,把流程理顺,比临时瞎找免费代理靠谱一百倍。