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

概述

做电商数据采集、自媒体监控这类反爬严苛的业务时,IP 被封几乎是家常便饭。用第三方付费代理要么价格离谱,要么同 IP 被多人用烂,还没开始爬就已经躺在目标网站的黑名单里。

本教程将带你从零搭建一套完全自主可控、成本可控、IP 数量千万级、高匿隐蔽的 ADSL 拨号代理服务。不用再和别人共享资源池,所有代理 IP 都是运营商动态分配的“新鲜”地址,一次拨号就是一次新生。

相比市面上动辄按量计费的代理服务,这套方案的突出优势在于:

  • 纯动态 IP:每次重拨强制换新,IP 段随机分配,几乎零重复;
  • 独享带宽:单云主机下行带宽 1-2Mbps 即可,网络稳定无干扰;
  • 配置完全定制:匿名度、拨号频率、开放端口统统由你掌控;
  • 横向扩展方便:多台云主机同时运行,可轻松将 IP 池扩充到百级、千级。

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

ADSL 全称「非对称数字用户线路」,我们只需要抓牢两个核心、一个优势

两个核心

  1. 上小下大的不对称带宽
    下行(从服务器拉数据)快,上行(发送请求到服务器)慢——这刚好匹配爬虫“请求小、响应大”的场景,几乎不用为没用的上行带宽额外付费。

  2. 强制拨号换 IP
    和早年间家里的 Modem 拨号上网一样,每次重新连接宽带时,运营商会从海量动态 IP 池里随机分配一个新地址。通常情况下,前后两次拨到的 IP 都不在同一网段,很难被网站关联。

一个优势

IP 量级千万级:主流云服务商的 ADSL 动态池覆盖全国多省市运营商的 IP 资源,重复率低到可以忽略,完全不必担心“被人用过的脏 IP”问题。


2. 准备工作

2.1 采购 ADSL 拨号云主机

目前市面主要有两类云主机可选:

  • 纯拨号云:带宽便宜(1-2Mbps 下行足够日常使用),IP 池相对干净。阿斯云、云立方是常见的选择。订购时务必选择「动态 IP ADSL」而非「静态云」
  • 阿里云/腾讯云轻量转拨号:稳定性稍高,但需要自行配置 PPPoE,操作门槛略高。

推荐配置:至少准备 2 台 1核1G、1-2Mbps 下行的云主机,然后错开它们的拨号时间,避免同一时刻所有主机都在重连而暂时无代理可用。

2.2 SSH 连接服务器

拿到云主机的 IP、端口、用户名(通常为 root)和密码后,用终端远程登录:

# 将 your_server_ip、port_number 替换成实际信息
ssh root@your_server_ip -p port_number

3. 测试拨号功能

装代理之前,先确保云主机本身能正常拨号并成功更换 IP。

3.1 常用拨号命令

不同厂商提供的拨号脚本可能略有差异,可以先尝试通用命令;如果不行,直接联系客服获取专用脚本:

pppoe-start  # 开始拨号
pppoe-stop   # 断开拨号

3.2 验证 IP 变化

在拨号前后分别查看 ppp0 接口的地址,对比是否发生变化:

ifconfig | grep ppp0 -A 2

只要 inet 一行显示的 IP 在拨号后变了,就说明拨号功能正常。


4. 搭建 Squid 代理服务器

接下来我们要用 Squid 把云主机的动态 IP 转换为可供外部访问的 HTTP/HTTPS 代理。同时,必须将它配置成高匿代理,让目标服务器完全察觉不到请求是经过代理转发的。

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

④ 修改默认端口(推荐)

Squid 默认监听 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 存入了 Redis。


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

adslproxy 不仅帮我们维护代理池,还提供了两种便捷的取用方式。

6.1 使用内置的 API 服务

① 启动 API

本地电脑一台能与 Redis 通信的服务器上,同样安装 adslproxy 并设置好 Redis 环境变量,然后启动:

adslproxy server

默认端口为 8000,如需修改可以使用 -p 参数:

adslproxy server -p 9000

② 常用 API 接口

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

6.2 用 Python 直接读取 Redis(更灵活)

在一些需要深度定制的场景下,你也可以直接从 Redis 中取出代理地址:

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 环境变量为不同主机设置不同的拨号周期(如 15min、17min、20min),避免所有主机同时重连导致暂时缺代理。

  2. 定期清理过期代理
    adslproxy 会自动移除不可用的代理,但可以额外设置定时任务,定期跑一遍 Redis 的 HDEL 清理残留。

  3. 按需定制可用性检测
    通过 PROXY_TEST_URL 环境变量将检测 URL 换成你要爬的目标网站(如 https://www.taobao.com),这样存活的代理对目标站点才更有意义。

  4. 保护 API 接口
    如果 API 服务需要暴露到公网,建议在 Nginx 后面做反向代理,同时加上简单的 Token 认证,或者限制访问 IP,防止被滥用。


10. 总结

通过本教程,你已掌握从零搭建一套自主可控、成本低廉、IP 量级千万级的 ADSL 拨号代理服务的全部流程。这套方案彻底解决了“买代理贵、共享代理脏、IP 数量瓶颈”等爬虫领域的顽固难题,尤其适合采集反爬严格的电商、自媒体、招聘网站等平台。

现在,你可以把精力集中在爬虫逻辑本身,剩下的网络身份问题,就交给这套动态 ADSL 代理池吧!