Python3 爬虫教程:搭建 ADSL 拨号代理服务

概述

做过电商、自媒体这类反爬较严平台的爬虫工程师,大概率都踩过IP 被秒封/分钟级限流的坑——传统的第三方共享代理池要么贵到离谱,要么 IP 重复率高、可用性差、甚至可能已经被别人“用烂”提前拉黑。

本教程将带你搭建一套完全自主可控、成本可控、IP 量级千万级、匿名性拉满的 ADSL 拨号代理服务,轻松解决 IP 封禁问题。

相比第三方代理池,自主搭建的 ADSL 方案优势明显:

  • 纯动态 IP:每次拨号强制换一个全新 IP,运营商随机分配
  • 专线独享带宽:稳定性、响应速度远胜共享代理
  • 完全掌控配置:匿名度、端口、拨号频率全由你定
  • 支持多机负载:多台云主机同时跑,IP 池可无限扩容

1. ADSL 技术原理(通俗版)

ADSL 是「非对称数字用户线路」的缩写,重点要抓住两个核心、一个优势

两个核心

  1. 上小下大的不对称带宽:下行(从服务器收数据)快、上行(给服务器发请求)慢——刚好完美适配爬虫场景,不用为没用的上行带宽多花钱
  2. 强制拨号换 IP:和家里早年的「猫」拨号上网一样,重新连接宽带时,运营商会从自己的动态 IP 池里随机给你分配一个全新的(大概率不在同一 A/B 段)

一个优势

IP 量级千万级:一般云服务商提供的 ADSL 动态池,覆盖全国多个省市的运营商 IP,完全不用担心重复率问题。


2. 准备工作

2.1 采购 ADSL 拨号云主机

市面上主流的有两类云主机可选:

  • 纯拨号云:带宽便宜(1-2Mbps 下行足够普通爬虫)、IP 池干净,阿斯云、云立方是国内用得最多的(注意选「动态 IP ADSL」而非「静态云」
  • 阿里云/腾讯云轻量转拨号:稳定性稍高,但需要自己配置 PPPoE,门槛略高

建议配置:至少 2 台 1核1G、1-2Mbps 下行的云主机,错开拨号时间避免同时无代理可用。

2.2 SSH 连接服务器

拿到云主机的 IP、端口、用户名(一般是 root)、密码后,用终端 SSH 连接:

# 替换 your_server_ip、port_number、your_password
ssh root@your_server_ip -p port_number

3. 测试拨号功能

先别急着装代理!先确认云主机的拨号功能正常:

3.1 常用拨号命令

不同云厂商的拨号命令可能不一样,先试通用的,不行就问客服要专属脚本:

pppoe-start  # 开始拨号
pppoe-stop   # 停止拨号

3.2 验证 IP 变化

拨号前后分别查一下接口 ppp0 的 IP:

ifconfig | grep ppp0 -A 2

如果看到 inet 后面的 IP 变了,说明拨号功能没问题!


4. 搭建 Squid 代理服务器

我们需要用 Squid 把云主机的动态 IP 做成可对外访问的 HTTP/HTTPS 代理,并且配置成「高匿代理」——让目标服务器完全看不到你的真实 IP。

4.1 安装 Squid

CentOS/RedHat 系统用 yum 一键安装:

yum install squid -y

4.2 基础启动配置

先启动、开机自启、确认状态:

systemctl start squid
systemctl enable squid  # 重启后自动启动
systemctl status squid  # 看到 active(running) 就成功

4.3 核心配置(高匿+公网访问)

编辑 Squid 的主配置文件 /etc/squid/squid.conf(建议用 vimnano),修改以下 5 个关键部分

① 允许所有公网 IP 访问代理

找到默认的访问规则,http_access deny all 删掉或注释掉,换成:

http_access allow all

② 添加全局允许的 ACL 规则

在文件开头的 acl 区域附近,新增一行:

acl localnet src 0.0.0.0/0

③ 开启高匿模式(必须改!

在文件末尾新增以下 3 行,完全隐藏代理痕迹:

request_header_access Via deny all
request_header_access X-Forwarded-For deny all
request_header_access From deny all

④ 修改默认端口(可选但推荐)

默认端口是 3128,容易被扫描到,建议改成自定义的(比如 3328):

http_port 3328

⑤ 重启 Squid 生效

systemctl restart squid

4.4 本地测试代理

在云主机本机用 curl 测试一下:

# 替换成你设置的端口
curl -x http://127.0.0.1:3328 https://httpbin.org/ip

如果返回的 IP 是你云主机当前的 ppp0 IP,说明代理配置成功!


5. 实现动态 IP 自动管理

现在有了代理,但每次手动拨号太麻烦,还要记录 IP。我们用 Python 库 adslproxy 实现「自动拨号 → 自动获取新 IP → 自动存入 Redis 代理池」的全流程。

5.1 安装依赖

先在云主机上装 Python3、pip3 和 adslproxy

yum install python3 python3-pip -y
pip3 install adslproxy

5.2 准备 Redis(可选但推荐)

如果有多台云主机,或者需要从外部批量取代理,需要一台公网可访问的 Redis 服务——可以单独买一台轻量云装,也可以用阿里云/腾讯云的 Redis 服务(更稳定)。

5.3 设置环境变量

在云主机上配置 adslproxy 连接 Redis 和拨号的参数:

# 替换成你自己的 Redis 信息
export REDIS_HOST='your_redis_public_ip'
export REDIS_PORT='6379'
export REDIS_PASSWORD='your_redis_password'
export REDIS_DB='0'  # 可选,默认0号库

# 替换成你设置的代理端口、拨号命令、拨号接口
export PROXY_PORT='3328'
export DIAL_BASH='pppoe-stop; sleep 3; pppoe-start'  # 加sleep 3避免拨号冲突
export DIAL_IFNAME='ppp0'  # 一般都是ppp0,不行就问客服

# 每台云主机必须设置唯一的名称!不然会覆盖
export CLIENT_NAME='adsl1'

5.4 启动拨号进程

后台启动拨号进程,让它自己跑:

nohup adslproxy dial > /var/log/adslproxy_dial.log 2>&1 &

可以用 tail -f /var/log/adslproxy_dial.log 查看日志,确认是否正常拨号、存 IP。


6. 从代理池取 IP(Python 调用/API 接口)

adslproxy 自带了一个轻量级的 API 服务,也可以直接用 Python 代码从 Redis 取。

6.1 用自带的 API 服务

① 启动 API

本地电脑单独的 API 服务器上(和 Redis 能连通就行),安装 adslproxy 并设置 Redis 环境变量后,启动:

adslproxy server

默认端口是 8000,可以用 -p 参数改:

adslproxy server -p 9000

② 常用 API 接口

接口路径方法功能
/randomGET获取一个随机的可用代理
/allGET获取所有当前可用的代理
/countGET获取当前可用代理的数量

6.2 用 Python 直接调用(更灵活)

import redis
import random

# 连接 Redis
r = redis.StrictRedis(
    host='your_redis_public_ip',
    port=6379,
    password='your_redis_password',
    db=0,
    decode_responses=True  # 直接返回字符串,不用解码
)

# 获取所有代理的列表
proxies = r.hkeys('adslproxy:proxies')

# 随机取一个
if proxies:
    proxy = random.choice(proxies)
    print(f"当前可用代理:http://{proxy}")
else:
    print("当前没有可用代理!")

7. 常见问题&最佳实践

常见问题

  1. 拨号失败?
    • 先手动运行 pppoe-stop; pppoe-start 看报错
    • 检查云主机的宽带账号密码、PPPoE 配置(问客服要专属的 /etc/ppp/chap-secrets/etc/ppp/peers/pppoe 配置)
  2. 代理不可用?
    • 云主机上 curl -x http://127.0.0.1:3328 https://httpbin.org/ip 先测
    • 检查云主机的防火墙是否开放了代理端口(比如 firewall-cmd --zone=public --add-port=3328/tcp --permanent && firewall-cmd --reload
  3. Redis 连不上?
    • 检查 Redis 的 bind 配置(改成 bind 0.0.0.0 或注释掉)、防火墙是否开放了 6379 端口
    • 确认密码正确

最佳实践

  1. 多主机错开拨号:用 adslproxyDIAL_CYCLE 环境变量设置不同的拨号周期(比如 15分钟、17分钟、20分钟),避免同时无代理
  2. 定期清理 Redis:虽然 adslproxy 会自动删除不可用的代理,但可以加个定时任务定期清理一下
  3. 增加代理可用性检测adslproxy 自带检测,可以通过 PROXY_TEST_URL 环境变量改成你要爬的目标网站(比如 https://www.taobao.com),这样更精准
  4. 保护 API 接口:如果 API 要对外暴露,建议加个简单的 Token 验证,或者用 Nginx 反向代理限制 IP 访问

10. 总结

通过本教程,我们从零搭建了一套自主可控、成本低廉、IP 量级千万级的 ADSL 拨号代理服务,完全解决了爬虫 IP 被封的问题。这套方案特别适合爬取反爬较严的电商、自媒体、招聘类平台。