手把手教你搭建海外代理 IP 池,实现稳定高效的数据爬取

 目录

1. 引言:为什么要搭建 IP 池? 

2. 获取 IPIPGO 代理 IP 

2.1 获取API链接

2.2 代理 IP 的格式

2.3 使用 API 获取代理 IP

3. 搭建 IP 池:存储 & 管理代理 IP 

3.1 代理 IP 应该存在哪?

3.2 自动存储代理 IP 到 SQLite

4. 维护 IP 池:检测 & 轮换代理 IP 

4.1 自动检测代理 IP 是否可用

5. 让爬虫使用代理 IP 池 

5.1 随机选取可用代理

5.2 爬取全球公开网页

6. 定期优化 IP 池:自动更新与清理 

6.1 定期获取新代理 IP 并清理无效 IP

7. 总结


1. 引言:为什么要搭建 IP 池? 

问题来了! 你写了一个爬虫,信心满满地去采集全球各大网站公开数据,结果没爬几次,IP就不能用了?网站返回403?甚至验证码狂弹?

为什么?因为大部分网站都有安全验证机制,如果同一个 IP 频繁请求,就会被识别为异常行为,导致访问受阻。

怎么办?
使用代理 IP 轮换,让爬虫的 IP 不断变换,控制每个IP的请求频率,降低被识别的风险。
搭建 IP 池,让爬虫可以自动获取可用代理,稳定运行。

今天,我们就来使用 IPIPGO 搭建一个属于自己的 IP 池,并且实现全球数据的公开访问。 

2. 获取代理 IP 

2.1 获取API链接

  • 领取代理 IP:进入用户中心完成认证获得代理IP,如果不够,可以自行选购

  • 获取API链接:进入API 提取页面设置代理IP 参数并生成API链接

📌 API 链接示例

http://api.ipipgo.com/ip?cty=00&c=10&pt=1&ft=txt&pat=\n&rep=1&key=你的API密钥&ts=3

📌 代码解析

  • c=10:获取 10 个代理 IP(可调整)
  • ft=txt:返回格式为纯文本,每行一个 IP
  • key=你的API密钥:你的专属 API 密钥,一般生成后直接复制链接即可,无需手动替换

💡 提示:你可以在 IPIPGO 后台查看 API 详情,也可以选择其他参数,如指定国家或地区的代理

2.2 代理 IP 的格式

IPIPGO 返回的代理 IP 形式如下(每行一个):

172.65.64.115:13192
185.180.196.73:24561
102.129.249.53:10080
  • IP 地址172.65.64.115
  • 端口号13192
  • 完整代理http://172.65.64.115:13192

2.3 使用 API 获取代理 IP

有了 API 链接后,我们可以用 Python 代码自动获取代理 IP

📌 代码示例

import requests

API_URL = "http://api.ipipgo.com/ip?cty=00&c=10&pt=1&ft=txt&pat=\n&rep=1&key=你的API密钥&ts=3"

def fetch_proxies():
    response = requests.get(API_URL)  # 发送请求获取代理IP
    if response.status_code == 200:  # 判断是否请求成功
        proxies = response.text.strip().split("\n")  # 按行分割 IP
        print("获取到代理 IP:", proxies)
        return proxies
    else:
        print("API 请求失败!请检查密钥或套餐状态。")
        return []

fetch_proxies()

📌 代码解析

  • requests.get(API_URL):向 API 发送请求,获取代理 IP
  • response.status_code == 200:检查 API 请求是否成功(200 表示成功)
  • response.text.strip().split("\n"):将返回的文本按换行符拆分,获取一个 IP 列表
  • print(proxies):打印获取到的代理 IP

3. 搭建 IP 池:存储 & 管理代理 IP 

3.1 代理 IP 应该存在哪?

获取到代理 IP 后,我们需要存储它们,方便后续管理。以下是几种常见的存储方式:

存储方式优点适用场景
纯文本 (txt)简单易用适合小规模测试
SQLite 数据库支持查询、去重、定期更新适合中等规模的爬取
Redis高效缓存,支持分布式适合大规模爬取

这里,我们选择 SQLite,因为它比文本存储更灵活,比 Redis 更简单,适合大多数应用场景

3.2 自动存储代理 IP 到 SQLite

📌 代码示例

import sqlite3

conn = sqlite3.connect("proxy_pool.db")
cursor = conn.cursor()

cursor.execute("""
    CREATE TABLE IF NOT EXISTS proxies (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        ip TEXT UNIQUE,
        last_checked TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        is_valid INTEGER DEFAULT 1
    )
""")
conn.commit()

def store_proxies(proxies):
    for proxy in proxies:
        cursor.execute("INSERT OR IGNORE INTO proxies (ip) VALUES (?)", (proxy,))
    conn.commit()
    print(f"成功存储 {len(proxies)} 个代理 IP")

proxies = fetch_proxies()
store_proxies(proxies)

📌 代码解析

  • sqlite3.connect("proxy_pool.db"):连接 SQLite 数据库(如果不存在,会自动创建)
  • CREATE TABLE IF NOT EXISTS proxies:创建存储代理 IP 的表
  • INSERT OR IGNORE INTO proxies (ip) VALUES (?):避免重复存储相同的代理 IP
  • conn.commit():提交数据,使存储生效

这样,每次获取的新 IP 都会自动存到数据库中,并避免重复存储!

4. 维护 IP 池:检测 & 轮换代理 IP 

4.1 自动检测代理 IP 是否可用

📌 代码示例

def check_proxy(proxy):
    try:
        response = requests.get("http://httpbin.org/ip", proxies={"http": f"http://{proxy}", "https": f"http://{proxy}"}, timeout=5)
        return response.status_code == 200
    except:
        return False

def update_proxy_status():
    cursor.execute("SELECT ip FROM proxies")
    all_proxies = cursor.fetchall()
    
    for (proxy,) in all_proxies:
        status = 1 if check_proxy(proxy) else 0
        cursor.execute("UPDATE proxies SET is_valid = ? WHERE ip = ?", (status, proxy))
    
    conn.commit()
    print("代理检测完成")

update_proxy_status()

📌 代码解析

  • check_proxy(proxy):测试代理 IP 是否可用,使用 httpbin.org/ip 返回的 IP 信息
  • status = 1 if check_proxy(proxy) else 0:根据代理是否可用更新数据库状态
  • UPDATE proxies SET is_valid = ?:将不可用的代理标记为 0(失效)

5. 让爬虫使用代理 IP 池 

5.1 随机选取可用代理

爬虫在运行时,如何选择一个可用的代理 IP 呢?最简单的方法就是从 IP 池中随机选择一个可用的代理 IP,并将其应用到爬虫请求中。这样可以避免一直使用同一个 IP,降低被封的风险。

📌 代码示例

import random

def get_random_proxy():
    cursor.execute("SELECT ip FROM proxies WHERE is_valid=1 ORDER BY RANDOM() LIMIT 1")
    result = cursor.fetchone()
    return result[0] if result else None

proxy = get_random_proxy()
print(f"使用代理: {proxy}")

📌 代码解析

  • SELECT ip FROM proxies WHERE is_valid=1 ORDER BY RANDOM() LIMIT 1:从数据库中随机选择一个可用(is_valid=1)的代理 IP
  • cursor.fetchone():返回查询的第一行结果
  • return result[0] if result else None:如果查询到代理 IP,则返回;否则返回 None

5.2 爬取全球公开网页

当我们搭建好 IP 池后,接下来的关键就是让爬虫能够自动使用代理池中的 IP 进行网页数据爬取

📌 代码示例

import requests

target_url = "https://example.com"  # 目标网站

proxy = get_random_proxy()  # 从代理池中获取一个可用代理
if proxy:
    proxies = {"http": f"http://{proxy}", "https": f"http://{proxy}"}  # 设置代理
    try:
        response = requests.get(target_url, proxies=proxies, timeout=5)  # 发送请求
        print(response.text[:500])  # 打印前500个字符,防止输出过长
    except requests.RequestException:
        print("请求失败")  # 代理可能失效,需要切换
else:
    print("没有可用的代理 IP")

📌 代码解析

  • proxy = get_random_proxy():从 IP 池中随机选取一个可用的代理 IP
  • proxies = {"http": f"http://{proxy}", "https": f"http://{proxy}"}:为 requests 设置代理
  • requests.get(target_url, proxies=proxies, timeout=5):通过代理发送 HTTP 请求,超时时间设为 5 秒
  • print(response.text[:500]):打印网页内容的前 500 个字符,防止输出过长影响阅读
  • except requests.RequestException::如果请求失败(如代理不可用、超时),会捕获异常并提示请求失败

6. 定期优化 IP 池:自动更新与清理 

6.1 定期获取新代理 IP 并清理无效 IP

为了保持 IP 池的可用率,我们需要定期从获取新的代理 IP,并且清理掉那些已经失效的 IP,这样可以确保爬虫的稳定运行,避免使用无效的代理。

📌 代码示例

import schedule
import time

def refresh_proxies():
    new_proxies = fetch_proxies()
    store_proxies(new_proxies)
    print("代理 IP 已更新!")

def update_proxy_status():
    cursor.execute("SELECT ip FROM proxies")
    all_proxies = cursor.fetchall()
    
    for (proxy,) in all_proxies:
        status = 1 if check_proxy(proxy) else 0
        cursor.execute("UPDATE proxies SET is_valid = ? WHERE ip = ?", (status, proxy))
    
    conn.commit()
    print("代理检测完成")

schedule.every(10).minutes.do(refresh_proxies)
schedule.every(15).minutes.do(update_proxy_status)

while True:
    schedule.run_pending()
    time.sleep(60)

📌 代码解析

  • schedule.every(10).minutes.do(refresh_proxies):每 10 分钟获取一次新的代理 IP
  • schedule.every(15).minutes.do(update_proxy_status):每 15 分钟检查一次代理 IP 的可用性
  • while True: schedule.run_pending():不断执行定时任务

7. 总结

至此,你已经成功搭建了一个可用的全球代理 IP 池,并能用它进行网页数据爬取!定期优化 IP 池,智能切换代理,让你的爬虫更加稳定高效,高效全球公开网络数据!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值