## [Python爬虫进阶七之设置ADSL拨号服务器代理]
## 提示
本教程方法已不是最优,最新解决方案请移步 [http://cuiqingcai.com/4596.html](http://cuiqingcai.com/4596.html)
## 那夜
那是一个寂静的深夜,科比还没起床练球,虽然他真的可能不练了。
我废了好大劲,爬虫终于写好了!BUG也全部调通了!心想,终于可以坐享其成了!
泡杯茶,安静地坐在椅子上看着屏幕上一行行文字在控制台跳出,一条条数据嗖嗖进入我的数据库,一张张图片悄悄存入我的硬盘。人生没有几个比这更惬意的事情了。
我端起茶杯,抿了一口,静静地回味着茶香。
这时,什么情况!屏幕爆红了!爆红了!一口茶的功夫啊喂!
怎么回事!咋爬不动了,不动了!我用浏览器点开那一个个报错的链接,浏览器显示
> 您的请求过于频繁,IP已经被暂时封禁,请稍后再试!
沃日,我IP被封了?此时此刻,空气凝固了,茶也不再香了,请给我一个爱的抱抱啊。
时候不早了,还是洗洗睡吧。
## 次日
那一晚,辗转反侧难以入睡。
怎么办?怎么办?如果是你你该怎么办?
手动换个IP?得了吧,一会又要封了,还能不能安心睡觉啊?
找免费代理?可行,不过我之前测过不少免费代理IP,一大半都不好用,而且慢。不过可以一直维护一个代理池,定时更新。
买代理?可以可以,不过优质的代理服务商价格可是不菲的,我买过一些廉价的,比如几块钱套餐一次提取几百IP的,算了还是不说了都是泪。
然而最行之有效的方法是什么?那当然是ADSL拨号!
这是个啥?且听我慢慢道来。
## 什么是ADSL
ADSL (Asymmetric Digital Subscriber Line ,非对称数字用户环路)是一种新的数据传输方式。它因为上行和下行带宽不对称,因此称为非对称数字用户线环路。它采用频分复用技术把普通的电话线分成了电话、上行和下行三个相对独立的信道,从而避免了相互之间的干扰。
他有个独有的特点,每拨一次号,就获取一个新的IP。也就是它的IP是不固定的,不过既然是拨号上网嘛,速度也是有保障的,用它搭建一个代理,那既能保证可用,又能自由控制拨号切换。
如果你是用的ADSL上网方式,那就不用过多设置了,直接自己电脑调用一个拨号命令就好了,自动换IP,分分钟解决封IP的事。
然而,你可能说?我家宽带啊,我连得公司无线啊,我蹭的网上的啊!那咋办?
这时,你就需要一台VPS拨号主机。
## 购买服务器
某度广告做的那么好是吧?一搜一片,这点谷歌可是远远比不上啊。
于是乎,我就搜了搜,键入:拨号服务器,有什么骑士互联啊、无极网络啊、挂机宝啊等等的。我选了个价钱还凑合的,选了个无极网络(这里不是在打广告),80一个月的配置,一天两块钱多点。
2核、512M内存,10M带宽。
[云立方](http://www.yunlifang.cn/)
大家觉得有更便宜的更好用请告诉我呀!
接下来开始装操作系统,进入后台,有一个自助装系统的页面。
[](http://qiniu.cuiqingcai.com/wp-content/uploads/2016/11/QQ20161121-0.png)
我装的CentOS的,在后面设置代理啊,定时任务啊,远程SSH管理啊之类的比较方便。如果你想用Windows,能配置好代理那也没问题。
有的小伙伴可能会问了,既然它的IP是拨号变化的,你咋用SSH连?其实服务商提供了一个域名,做了动态解析和端口映射,映射到这台主机的22端口就好了,所以不用担心IP变化导致SSH断开的问题。
好了装好了服务器之后,服务商提供了一个ADSL的拨号操作过程,用pppoe命令都可以完成,如果你的是Linux的主机一般都是用这个。然后服务商还会给给你一个拨号账号和密码。
那么接下来就是试下拨号了。
服务商会提供详细的拨号流程说明。
比如无极的是这样的:
[拨号流程](http://cloud.871020.com/vpsadm/pppoe.html)
设置好了之后,就有几个关键命令:
```
pppoe-start 拨号
pppoe-stop 断开拨号
pppoe-status 拨号连接状态
```
如果想重新拨号,那就执行stop、start就可以了。
反复执行,然后查看下ip地址,你会发现拨号一次换一个IP,是不是爽翻了!
好,那接下来就设置代理吧。
## 设置代理服务器
之前总是用别人的代理,没自己设置过吧?那么接下来我们就来亲自搭建HTTP代理。
Linux下搭建HTTP代理,推荐Squid和TinyProxy。都非常好配置,你想用哪个都行,且听我慢慢道来。
我的系统是CentOS,以它为例进行说明。
### Squid
首先利用yum安装squid
```
yum -y install squid
```
设置开机启动
```
chkconfig --level 35 squid on
```
修改配置文件
```
vi /etc/squid/squid.conf
```
修改如下几个部分:
```
http_access allow !Safe_ports #deny改成allow
http_access allow CONNECT !SSL_ports #deny改成allow
http_access allow all #deny改成allow
```
其他的不需要过多配置。
启动squid
```
sudo service squid start
```
如此一来配置就完成了。
代理使用的端口是3128
### TinyProxy
首先添加一下镜像源,然后安装
```
rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm
yum update
yum install tinyproxy
```
修改配置
```
vi /etc/tinyproxy/tinyproxy.conf
```
可以修改端口和允许的IP,如果想任意主机都连接那就把Allow这一行注释掉。
```
Port 8888 #预设是8888 Port,你可以更改
Allow 127.0.0.1 #将127.0.0.1改成你自己的IP
#例如你的IP 是1.2.3.4,你改成Allow 1.2.3.4,那只有你才可以连上这个Proxy
#若你想任何IP都可以脸到Proxy在Allow前面打#注释
```
启动TinyProxy
```
service tinyproxy start
```
好了,两个代理都配置好了。
你想用那个都可以!
不过你以为这样就完了吗?太天真了,我被困扰了好几天,怎么都连不上,我还在怀疑是不是我哪里设置得不对?各种搜,一直以为是哪里配置有遗漏,后来发现是iptables的锅,万恶的防火墙。踩过的的坑,那就不要让大家踩了,用下面的命令设置下iptables,放行3128和8888端口就好了。
```
service iptables save
systemctl stop firewalld
systemctl disable firewalld
systemctl start iptables
systemctl status iptables
systemctl enable iptables
```
修改iptables配置
```
vi /etc/sysconfig/iptables
```
在
```
-A IN_public_allow -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
```
的下面添加两条规则
```
-A IN_public_allow -p tcp -m tcp --dport 3128 -m conntrack --ctstate NEW -j ACCEPT
-A IN_public_allow -p tcp -m tcp --dport 8888 -m conntrack --ctstate NEW -j ACCEPT
```
如图所示
[](http://qiniu.cuiqingcai.com/wp-content/uploads/2016/11/QQ20161121-0@2x.png)
保存,然后重启iptables
```
sudo service iptabels restart
```
输入
ifconfig得到IP地址,在其他的主机上输入
```
curl -x IP:8888 www.baidu.com
```
测试一下,如果能出现结果,那就说明没问题。
[](http://qiniu.cuiqingcai.com/wp-content/uploads/2016/11/QQ20161121-1@2x.png)
如果怎么配都连不上,那干脆关了你的防火墙吧。虽然不推荐。
## 连接代理
接下来才是重头戏,你咋知道你的服务器IP现在到底是多少啊?拨一次号IP就换一次,那这还了得?
如果服务商提供了端口映射!那一切都解决了!直接用端口映射过去就好了。然而,我的并没有。
自力更生,艰苦创业!
首先我研究了一下DDNS服务,也就是动态域名解析。即使你的IP在变化,那也可以通过一个域名来映射过来。
原理简单而统一:当前拨号主机定时向一个固定的服务器发请求,服务器获取remote\_addr就好了,可以做到定时更新和解析。
那么我找了一下,国内做的比较好的就是花生壳了,然后又找到了DNSPOD的接口解析。
下面简单说下我的折腾过程,大家可以先不用试,后面有更有效的方法。
### 花生壳
现在花生壳出到3.0版本了,有免费版和付费版之分,我就试用了一下免费版的。这里是花生壳的一些配置和下载:
[花生壳配置](http://service.oray.com/question/4287.html)
下载花生壳客户端之后,会生成SN码,用这个在花生壳的官网登录后,会分配给你一个免费的域名。
接下来这个域名就能解析到你的主机了。
### DNSPOD
DNSPOD原理也是一样,不过好处是你可以配置自己的域名。
在GitHub上有脚本可以使用。
[脚本链接](https://github.com/xdtianyu/scripts/tree/master/ddns)
具体的细节我就不说了,实际上就是定时请求,利用remote\_addr更新DNSPOD记录,做到动态解析。
[解析接口](https://www.dnspod.cn/docs/records.html#dns)
不过!这两个有个通病!慢!
什么慢?解析慢!但这不是他们的锅,因为DNS修改后完全生效就是需要一定的时间,这一秒你拨号了,然后更新了IP,但是域名可能还是解析着原来的IP,需要过几分钟才能变过来。这能忍吗?
我可是在跑爬虫啊,这还能忍?
## 自力更生
嗯,V2EX果然是个好地方,逛了一下,收获不小。
[链接在此](https://www.v2ex.com/t/249694)
参考了 abelyao 的思路,自己写了脚本来获取IP,保证秒级更新!
此时,你还需要另一台固定IP的主机或者某个云服务器,只要是地址固定的就好。在这里我用了另一台有固定IP的阿里云主机,当然你如果有什么新浪云啊之类的也可以。
那么现在的思路就是,拨号VPS定时拨号换IP,然后请求阿里云主机,阿里云主机获取VPS的IP地址即可。
拨号VPS做的事情:
定时拨号,定时请求服务器。使用bash脚本,然后crontab定时执行。
远程服务器:
接收请求,获取remote\_addr,保存起来。使用Flask搭建服务器,接收请求。
废话少说,上代码
[AutoProxy](https://github.com/Germey/AutoProxy)
### 功能
由于DDNS生效时间过长,对于爬虫等一些时间要求比较紧迫的项目就不太适用,为此本项目根据DDNS基本原理来实现实时获取ADSL拨号主机IP。
### 基本原理
client文件夹由ADSL拨号客户机运行。它会定时执行拨号操作,然后请求某个固定地址的服务器,以便让服务器获取ADSL拨号客户机的IP,主要是定时bash脚本运行。
server文件夹是服务器端运行,利用Python的Flask搭建服务器,然后接收ADSL拨号客户机的请求,得到remote\_addr,获取客户机拨号后的IP。
### 项目结构
#### server
* config.py 配置文件。
* ip 客户端请求后获取的客户端IP,文本保存。
* main.py Flask主程序,提供两个接口,一个是接收客户端请求,然后将IP保存,另外一个是获取当前保存的IP。
#### client
* crontab 定时任务命令示例。
* pppoe.sh 拨号脚本,主要是实现重新拨号的几个命令。
* request.sh 请求服务器的脚本,主要是实现拨号后请求服务器的操作。
* request.conf 配置文件。
### 使用
#### 服务器
服务器提供两个功能,record方法是客户机定时请求,然后获取客户机IP并保存。proxy方法是供我们自己用,返回保存的客户机IP,提取代理。
##### 克隆项目
```
git clone https://github.com/Germey/AutoProxy.git
```
##### 修改配置
修改config.py文件
* KEY 是客户端请求服务器时的凭证,在client的request.conf也有相同的配置,二者保持一致即可。
* NEED\_AUTH 在获取当前保存的IP(即代理的IP)的时候,为防止自己的主机代理被滥用,在获取IP的时候,需要加权限验证。
* AUTH\_USER和AUTH\_PASSWORD分别是认证用户名密码。
* PORT默认端口,返回保存的结果中会自动添加这个端口,组成一个IP:PORT的代理形式。
#### 运行
```
cd server
nohup python main.py
```
#### ADSL客户机
##### 克隆项目
```
git clone https://github.com/Germey/AutoProxy.git
```
##### 修改配置
修改reqeust.conf文件
* KEY 是客户端请求服务器时的凭证,在server的config.py也有相同的配置,二者保持一致即可。
* SERVER是服务器项目运行后的地址,一般为http://:/record。如`http://120.27.14.24:5000/record`。
修改pppoe.sh文件
这里面写上重新拨号的几条命令,记得在前两行配置一下环境变量,配置上拨号命令所在的目录,以防出现脚本无法运行的问题。
#### 运行
设置定时任务
```
crontab -e
```
输入crontab的实例命令
```
*/5 * * * * /var/py/AutoProxy/client/request.sh /var/py/AutoProxy/client/request.conf >> /var/py/AutoProxy/client/request.log
```
注意修改路径,你的项目在哪里,都统一修改成自己项目的路径。
最前面的\*/5是5分钟执行一次。
好了,保存之后,定时任务就会开启。
### 验证结果
这样一来,访问服务器地址,就可以得到ADSL拨号客户机的IP了。
```
import requests
url = 'http://120.27.14.24:5000'
proxy = requests.get(url, auth=('admin', '123')).text
print(proxy)
```
实例结果:
```
116.208.97.22:8888
```
### 扩展
如果你有域名,可以自己解析一个域名,这样就可以直接请求自己的域名,拿到实时好用的代理了,而且定时更新。

### 代理设置
#### urllib2
```
import urllib2
proxy_handler = urllib2.ProxyHandler({"http": 'http://' + proxy})
opener = urllib2.build_opener(proxy_handler)
urllib2.install_opener(opener)
response = urllib2.urlopen('http://httpbin.org/get')
print response.read()
```
### requests
```
import requests
proxies = {
'http': 'http://' + proxy,
}
r = requests.get('http://httpbin.org/get', proxies=proxies)
print(r.text)
```
以上便秒级解决了动态IP解析,自己实现了一遍DDNS,爽!
那这样以来,以后就可以直接请求你的主机获取一个最新可用的代理IP了,稳定可用,定时变化!
以上便是ADSL拨号服务器配置的全过程,希望对大家有帮助!
- LINUX命令
- 用户组和用户管理
- Linux文件共享服务
- Linux服务软件
- 网络管理
- ping不通
- Linux防火墙
- 解压缩
- vim编辑器
- GIT服务器
- GitLab
- 文件和目录命令
- 文件权限
- 文件属性
- 端口管理
- LInux基本命令
- ll
- screen命令
- sh 脚本
- 基本操作
- 磁盘管理
- vmware 磁盘扩容
- 基本目录介绍
- 调整分区
- 查看磁盘大小
- 统计文件大小
- 关机、重启
- 定时任务
- 定时任务排查
- 按秒执行脚本
- 执行php请求
- 环境变量
- 把php加入到环境变量
- 系统时间操作
- 进程管理
- CPU 管理
- TOP命令简介
- ps 命令介绍
- ps使用实例
- 报错管理
- ifconfig 报错
- fuser 报错
- 内存管理
- 查看内存
- PHP
- 函数管理
- Curl请求
- 加密函数
- 闭包函数
- php自定义函数
- 获取字符串首字母生成图片
- 字符串处理
- 隐藏部分字符串
- 字符串编码格式
- GB2312编码
- ASCII码介绍
- 随机生成汉字
- 编码转换函数
- 获取字符串首字母
- 全半角转换
- 字符串加、解密
- 字符串截取
- 数组处理
- 控制抽奖概率
- 二维数组转化为字符串
- 获取数组中最后一个元素
- 数组去重
- 数组排序
- 插件管理
- TCPDF
- PHP扩展
- Redis扩展
- TP5中使用Redis
- redis 服务不能开启
- CURl
- 魔术方法
- 系统函数
- PHP规范
- PSR-4
- 个人规范
- 数据表规范
- 系统常量、变量
- 常量PHP_SAPI与函数php_sapi_name()
- 进制转换
- ThinkPHP
- TP5.0
- 发送邮件
- TP5.1
- 控制器
- composer类库
- 通过json格式实现三级联动
- 查询语法
- model 模型
- PSR规范
- 导入导出
- CSV导出
- 文件目录操作
- 递归创建目录
- 文件大小单位转换
- 微信小程序
- 小程序支付
- 打印输出
- 日志操作
- 数据类型转换
- 数组转XML格式
- XML转数组
- 时间日期
- 计算时间差值的函数
- 计算程序运行时间
- 图片处理
- 图片压缩类
- Mysql
- 字段类型介绍
- 安装配置
- 数据库操作
- 数据表
- 查看创建表
- 创建表
- 插入数据
- 修改表
- 删除表
- 查询
- 时间查询
- 表的高级操作
- 视图
- 触发器
- 存储过程
- 事务
- 索引
- 存储引擎
- 数据库优化
- mysql中使用 where 1=1和 0=1 的作用
- 在线修改字段禁忌
- mysql配置文件
- mysql8.0新特性
- 数据库引擎
- Mysql 内置函数
- GROUP BY
- group_concat 函数的限制
- 远程连接
- 远程无法连接
- mysql远程连接问题
- mysql 导入导出
- mysql日志处理
- 性能优化
- Yaconf-高性能的配置管理扩展
- FTP上传opcache缓存
- 系统内置函数注意事项
- in_array()
- 并发和攻击
- sql防注入
- 防范csrf攻击
- XSS处理
- DDOS攻击和防范
- 日常报错
- 文件访问权限
- 专业术语
- PV、 UV、IP
- TPS、QPS、RT
- 安全配置
- 安全模式
- 报错处理
- open_basedir 报错
- PHP异常报错
- 类
- new static() 和 new self()区别
- 接口
- static::$val()和self::$val()介绍
- PHP中静态方法和实例化方法的区别
- 抽象类
- PHP函数include include_once require和require_once的区别
- final 关键字
- 内置迭代器类
- 命名空间和spl_autoload_register函数
- 修改类的私有成员属性
- php closure 的bind和bindTo
- trait 类
- php 正则
- php 正则函数
- 小案例
- foreach遍历数组
- 设计模式
- 单例模式
- 简单工厂模式
- 工厂模式
- 抽象工厂方法设计模式
- 使用简单工厂来优化抽象工厂模式
- 使用反射来优化抽象工厂模式
- 原型模式
- 适配器模式
- 对象适配器模式
- 桥接设计模式
- 装饰设计模式
- 组合设计模式
- 透明组合设计模式
- 安全组合设计模式
- 外观设计模式
- 享元设计模式
- 代理设计模式
- 模板设计模式
- 命令设计模式
- 迭代器设计模式
- 观察者设计模式
- 单元测试框架
- PHPUnit_Framework_TestCase
- Windowns
- 用户凭证
- 命令
- 设置电脑自动关机
- win文件共享
- excel表多人同时编辑
- 文件共享打开只读
- win 网络管理
- 电脑连接不上网络
- 法自动获取IP地址
- win10 进入安全模式
- 虚拟机
- vmware esxi集群
- Python
- 头部介绍
- 开始 工作
- 内置函数
- bytes
- 数据类型
- 位运算
- 字符串类型
- 清除空格或者填充
- 随机数
- 字符串编码
- python3 编码
- 判断是否为空,为None等
- 列表、元组、字典
- 数据处理
- 时间日期处理
- 获取下一个星期几
- 月份处理
- 函数
- 获取本地IP
- 判断当前是否可以联网
- 模块
- argparse 模块
- cookielib 模块
- urllib 爬虫模块
- types 模块
- subprocess 爬虫模块
- requests 爬虫模块
- Beautiful Soup 爬虫模块
- Xpath 爬虫模块与lxml 爬虫模块
- PhantomJS 爬虫模块
- xlrd 模块
- xlwt 模块
- 模块安装
- ssl 模块
- json 模块
- configparser 模块
- 文件操作
- 异常处理
- 面向对象
- 正则
- Mysql数据库
- Socket
- Sublime
- 数学
- 实例
- py进制转换
- 画图
- 画布详解
- 爬虫
- Python2爬取糗事百科段子
- Python2爬取百度贴吧
- python2无线网络掉线自动重连
- Python2抓取淘宝MM照片
- python2模拟登录淘宝并获取所有订单
- python2抓取爱问知识人问题并保存至数据库
- python2利用Selenium抓取淘宝匿名旺旺
- python2爬虫专用模块
- urllib 模块
- subprocess 模块
- requests 模块
- Beautiful Soup 模块
- Xpath 模块与lxml 模块
- PhantomJS 工具
- Selenium 工具
- PyQuery 工具
- 爬虫框架介绍
- PySpider 框架安装配置
- PySpider 的用法
- Scrapy 框架安装配置
- 爬虫之多进程和多线程
- 爬虫之多线程用法
- 爬虫之多进程用法
- 服务器代理
- python2
- python3
- 编辑器
- sublime
- 插件介绍
- Visual Studio Code
- 前端
- js或jquery初始化
- Vue
- 目录结构
- 环境搭建、安装
- 模块介绍与安装
- vue-axios + axios
- vuex
- vant-ui
- less
- vue 方法属性
- 前端字符串处理
- 字符串反转
- CSS
- 文本显示问题
- Jquery
- 遍历json对象
- ajax
- 获取节点
- select 操作
- 自定义函数
- in_array()
- 事件
- input事件
- 数组基本操作
- js判断是否为空
- js判断数组是否存在某个值
- 判断是否是数组
- js中json对象和字符串的转换
- 去重,过滤空数组
- 字符串基本操作
- 判断变量是否定义
- js时间日期
- 日期格式转时间戳
- Nginx
- nginx配置参数
- HTTP协议
- HTTP头部信息
- 浏览器缓存
- Content-Type类型介绍
- Content-transfer-encoding类型介绍