
免费代理IP池是爬虫、接口测试、数据采集场景的核心工具,可解决单一IP访问限制、高频请求封禁等问题。本文将手把手搭建一套全自动、可自用、零成本的个人代理IP池,涵盖核心模块:公开IP源抓取、IP有效性校验、存活IP存储、定时自动更新、故障重试,全程基于Python实现,无需服务器付费资源,本地/轻量云服务器均可部署。
整套IP池采用「抓取-校验-存储-更新-调用」闭环架构,模块解耦、便于维护和扩展,核心五大模块如下:
技术选型:Python3(核心逻辑)+ Requests(网络请求)+ Aiohttp(异步校验提速)+ SQLite(本地轻量化存储,无需安装数据库)+ Schedule(定时任务),全程零付费依赖。
确保设备安装Python3.8及以上版本,配置好基础环境变量。
执行以下命令安装所需第三方库,覆盖抓取、异步校验、定时任务全需求:
pip install requests aiohttp schedule python-dotenv
各库作用说明:
我们将分模块开发,最终整合为完整IP池项目,所有代码可直接复制运行。
proxy_pool/
├── config.py # 配置文件(超时时间、更新周期、校验地址)
├── crawler.py # IP抓取模块(各大免费IP源爬取)
├── validator.py # IP校验模块(异步有效性校验)
├── storage.py # 存储模块(SQLite增删改查、去重)
├── scheduler.py # 自动更新定时任务
├── api.py # IP调用接口
└── main.py # 项目入口
统一配置全局参数,方便后续调整,无需修改业务逻辑代码:
# 代理IP池全局配置
# 校验超时时间(秒),避免无效IP占用资源
VALID_TIMEOUT = 8
# IP池自动更新周期(分钟)【调大间隔,规避免费API限流】
UPDATE_CYCLE = 40
# IP过期时间(分钟),超过则自动淘汰
IP_EXPIRE_TIME = 120
# 校验目标地址(稳定公共接口,验证IP是否可正常联网)
CHECK_URL = "https://www.baidu.com"
基于SQLite实现轻量化存储,支持IP去重、过期删除、新增、查询、清空,无需额外部署数据库,本地持久化存储存活IP:
import sqlite3
import time
from config import IP_EXPIRE_TIME
# 数据库初始化
DB_PATH = "proxy_pool.db"
class ProxyStorage:
def __init__(self):
self.conn = sqlite3.connect(DB_PATH, check_same_thread=False)
self.cursor = self.conn.cursor()
self.create_table()
# 创建代理IP数据表
def create_table(self):
sql = '''
CREATE TABLE IF NOT EXISTS proxy (
ip TEXT NOT NULL,
port TEXT NOT NULL,
protocol TEXT,
speed REAL,
update_time INTEGER,
PRIMARY KEY (ip, port)
)
'''
self.cursor.execute(sql)
self.conn.commit()
# 新增有效IP(自动去重)
def add_proxy(self, ip, port, protocol, speed):
update_time = int(time.time())
try:
self.cursor.execute(
"INSERT OR IGNORE INTO proxy (ip, port, protocol, speed, update_time) VALUES (?,?,?,?,?)",
(ip, port, protocol, speed, update_time)
)
self.conn.commit()
return True
except Exception as e:
return False
# 删除过期IP
def delete_expire_proxy(self):
expire_timestamp = int(time.time()) - IP_EXPIRE_TIME * 60
self.cursor.execute("DELETE FROM proxy WHERE update_time < ?", (expire_timestamp,))
self.conn.commit()
# 获取所有有效IP
def get_all_proxy(self):
self.delete_expire_proxy()
self.cursor.execute("SELECT ip, port, protocol, speed FROM proxy")
return self.cursor.fetchall()
# 随机获取一个可用IP
def get_random_proxy(self):
import random
proxy_list = self.get_all_proxy()
if not proxy_list:
return None
return random.choice(proxy_list)
# 清空所有IP
def clear_all(self):
self.cursor.execute("DELETE FROM proxy")
self.conn.commit()
# 初始化存储实例
proxy_storage = ProxyStorage()
采用免费代理JSON API接口获取代理数据,接入简单、无需解析网页、返回格式规范、调用快捷稳定。可批量获取HTTP、HTTPS、Socks4、Socks5多类型代理IP,适配绝大多数爬虫与测试场景,接口地址已内置在项目配置代码中,无需手动配置即可落地使用。
import requests
import time
import random
PROXY_API_URL = "http://api.66daili.com/?format=json"
# 请求头伪装浏览器,避免被接口拦截
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
# 容错配置,专门解决 429 限流、超时问题
MAX_RETRY = 3
BASE_TIMEOUT = 20
class ProxyCrawler:
def crawl_api_proxy(self):
proxy_list = []
retry_count = 0
while retry_count <= MAX_RETRY:
try:
# 随机延时,彻底解决免费API高频429限流
time.sleep(round(random.uniform(1.0, 3.0), 2))
res = requests.get(PROXY_API_URL, headers=HEADERS, timeout=BASE_TIMEOUT)
res.raise_for_status()
json_data = res.json()
# 处理429限流返回
if json_data.get("code") == 429:
print("检测到API访问限流(429),延时重试...")
retry_count += 1
time.sleep(4)
continue
# 正常解析代理数据
if json_data.get("code") == 0 and "data" in json_data and isinstance(json_data["data"], list):
data_list = json_data["data"]
for item in data_list:
ip = item.get("ip", "").strip()
port = item.get("port", "").strip()
protocol = item.get("protocol", "http").strip().lower()
if ip and port:
proxy_list.append({
"ip": ip,
"port": port,
"protocol": protocol,
"speed": 0.0
})
break
except Exception as e:
retry_count += 1
print(f"抓取异常,重试({retry_count}/{MAX_RETRY}):{str(e)[:60]}")
time.sleep(2)
# 全局去重
unique_proxy = []
seen = set()
for p in proxy_list:
key = f"{p['ip']}:{p['port']}"
if key not in seen:
seen.add(key)
unique_proxy.append(p)
print(f"本次抓取成功,获取原始代理IP:{len(unique_proxy)} 个")
return unique_proxy
def crawl_all(self):
return self.crawl_api_proxy()
proxy_crawler = ProxyCrawler()
采用异步并发校验,大幅提升批量IP校验效率,过滤超时、无效IP,记录IP响应速度,筛选高质量可用IP:
import aiohttp
import asyncio
from config import VALID_TIMEOUT, CHECK_URL
class ProxyValidator:
# 异步校验单个IP
async def check_single_proxy(self, proxy):
ip = proxy["ip"]
port = proxy["port"]
protocol = proxy["protocol"]
proxy_str = f"{protocol}://{ip}:{port}"
try:
timeout = aiohttp.ClientTimeout(total=VALID_TIMEOUT)
async with aiohttp.ClientSession(timeout=timeout) as session:
start = asyncio.get_event_loop().time()
async with session.get(CHECK_URL, proxy=proxy_str) as res:
if res.status == 200:
speed = round(asyncio.get_event_loop().time() - start, 2)
return {**proxy, "speed": speed}
except Exception:
return None
return None
# 批量异步校验所有IP
async def check_all_proxy(self, proxy_list):
tasks = [self.check_single_proxy(proxy) for proxy in proxy_list]
result = await asyncio.gather(*tasks)
# 过滤校验通过的有效IP
valid_proxy = [p for p in result if p is not None]
print(f"校验通过有效IP数量:{len(valid_proxy)}")
return valid_proxy
# 同步调用入口
def run_check(self, proxy_list):
return asyncio.run(self.check_all_proxy(proxy_list))
# 初始化校验实例
proxy_validator = ProxyValidator()
整合抓取、校验、存储模块,实现定时自动更新IP池,自动清理过期IP、补充新IP,全程无人值守:
import schedule
import time
from config import UPDATE_CYCLE
from crawler import proxy_crawler
from validator import proxy_validator
from storage import proxy_storage
class ProxyScheduler:
# IP池更新核心逻辑
def update_proxy_pool(self):
print("===== 开始更新代理IP池 =====")
# 1. 抓取原始IP
raw_proxy = proxy_crawler.crawl_all()
# 2. 异步校验筛选有效IP
valid_proxy = proxy_validator.run_check(raw_proxy)
# 3. 存入数据库
for p in valid_proxy:
proxy_storage.add_proxy(p["ip"], p["port"], p["protocol"], p["speed"])
# 4. 清理过期IP
proxy_storage.delete_expire_proxy()
print("===== IP池更新完成 =====\n")
# 启动定时任务
def start_schedule(self):
# 首次立即更新一次
self.update_proxy_pool()
# 定时循环更新
schedule.every(UPDATE_CYCLE).minutes.do(self.update_proxy_pool)
print(f"定时任务已启动,每{UPDATE_CYCLE}分钟更新一次IP池")
# 永久循环执行定时任务
while True:
schedule.run_pending()
time.sleep(10)
# 初始化定时任务实例
proxy_scheduler = ProxyScheduler()
提供极简调用方法,支持随机获取IP、批量获取IP,适配爬虫、测试等各类业务场景:
from storage import proxy_storage
class ProxyApi:
# 随机获取一个可用代理(格式化输出)
def get_random(self):
proxy = proxy_storage.get_random_proxy()
if not proxy:
return None
ip, port, protocol, speed = proxy
return {
"proxy": f"{protocol}://{ip}:{port}",
"ip": ip,
"port": port,
"protocol": protocol,
"speed": speed
}
# 获取所有可用代理
def get_all(self):
proxy_list = proxy_storage.get_all_proxy()
res_list = []
for ip, port, protocol, speed in proxy_list:
res_list.append({
"proxy": f"{protocol}://{ip}:{port}",
"ip": ip,
"port": port,
"protocol": protocol,
"speed": speed
})
return res_list
# 初始化接口实例
proxy_api = ProxyApi()
启动项目,开启自动更新服务,同时提供调用测试示例:
import threading
from scheduler import proxy_scheduler
from api import proxy_api
# 后台运行定时更新任务
def run_pool():
proxy_scheduler.start_schedule()
if __name__ == "__main__":
# 开启子线程运行定时服务,不阻塞调用
pool_thread = threading.Thread(target=run_pool, daemon=True)
pool_thread.start()
# 测试调用
import time
time.sleep(3) # 等待首次IP池更新完成
print("随机获取代理IP:", proxy_api.get_random())
print("当前可用IP总数:", len(proxy_api.get_all()))
# 保持程序运行
while True:
time.sleep(60)
在项目根目录执行命令,即可启动全自动代理IP池:
python main.py
启动后会自动执行:首次抓取IP→校验筛选→存入数据库→开启定时更新,全程后台运行。
在爬虫、测试代码中调用IP池接口,快速获取可用代理:
from api import proxy_api
import requests
# 获取随机代理
proxy_info = proxy_api.get_random()
if proxy_info:
proxies = {
"http": proxy_info["proxy"],
"https": proxy_info["proxy"]
}
# 带代理请求测试
res = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
print("请求结果:", res.text)
else:
print("暂无可用代理IP")
本地运行关闭窗口后服务终止,可通过以下方式实现7×24小时运行:
nohup python main.py > proxy.log 2>&1
本文搭建的免费代理IP池实现了零成本、全自动、高可用的核心能力,摒弃了容易解析失败的传统网页爬取方式,采用稳定的公开结构化API作为IP数据源,从源头获取标准化代理数据,通过异步校验过滤劣质IP,配合定时更新和过期淘汰机制,保证IP池持续可用。整套架构轻量化、纯技术向、易扩展,完全适配个人爬虫、小型数据采集场景,可根据实际业务需求迭代优化。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。