咱们尝试维护过一个免费的代理池,可是代理池效果用过就知道了,毕竟里面有大量免费代理,虽然这些代理是可用的,可是既然咱们能刷到这个免费代理,别人也能呀,因此就致使这个代理同时被不少人使用来抓取网站,因此当咱们兴致勃勃地拿他来抓取某个网站的时候,会发现它仍是被网站封禁的状态,因此在某些状况下免费代理池的成功率仍是比较低的。html
固然咱们也能够去购买一些代理,好比几块钱提取几百几千个的代理,然而通过测试后质量也是很通常,也能够去购买专线代理,不过价格也是不菲的。那么目前最稳定并且又保证可用的代理方法就是设置ADSL拨号代理了。git
本篇来说解一下ADSL拨号代理服务器的相关设置。github
你们可能对ADSL比较陌生,ADSL全称叫作Asymmetric Digital Subscriber Line,非对称数字用户环路,由于它的上行和下行带宽不对称。它采用频分复用技术把普通的电话线分红了电话、上行和下行三个相对独立的信道,从而避免了相互之间的干扰。web
有种主机叫作动态拨号VPS主机,这种主机在链接上网的时候是须要拨号的,只有拨号成功后才能够上网,每拨一次号,主机就会获取一个新的IP,也就是它的IP并非固定的,并且IP量特别大,几乎不会拨到相同的IP,若是咱们用它来搭建代理,既能保证高度可用,又能够自由控制拨号切换。redis
经测试发现这也是最稳定最有效的代理方式,本节详细介绍一下ADSL拨号代理服务器的搭建方法。数据库
因此在开始以前,咱们须要先购买一台动态拨号VPS主机,这样的主机在百度搜索一下,服务商仍是至关多的,在这里推荐一家云立方,感受仍是比较良心的,非广告。api
配置的话能够自行选择,看下带宽是否能够知足需求就行了。安全
购买完成以后,就须要安装操做系统了,进入拨号主机的后台,首先预装一个操做系统。服务器
在这里推荐安装CentOS7系统。网络
而后找到远程管理面板找到远程链接的用户名和密码,也就是SSH远程链接服务器的信息。
好比我这边的IP端口分别是 153.36.65.214:20063,用户名是root。
命令行下输入:
而后输入管理密码,就能够链接上远程服务器了。
进入以后,能够发现有一个可用的脚本文件,叫作ppp.sh,这是拨号初始化的脚本,运行它会让咱们输入拨号的用户名和密码,而后它就会开始各类拨号配置,一次配置成功,后面的拨号就不须要重复输入用户名和密码了。
运行ppp.sh脚本,输入用户名密码等待它的配置完成。
都提示成功以后就能够进行拨号了。
在拨号以前若是咱们测试ping任何网站都是不通的,由于当前网络还没联通,输入拨号命令:
能够发现拨号命令成功运行,没有任何报错信息,这就证实拨号成功完成了,耗时约几秒钟。接下来若是再去ping外网就能够通了。
若是要中止拨号能够输入:
中止以后,能够发现又连不通网络了。
因此只有拨号以后才能够创建网络链接。
因此断线重播的命令就是两者组合起来,先执行adsl-stop
再执行adsl-start
,每拨一次号,ifocnfig
命令观察一下主机的IP,发现主机的IP一直是在变化的,网卡名称叫作ppp0。
因此,到这里咱们就能够知道它做为代理服务器的巨大优点了,若是将这台主机做为代理服务器,若是咱们一直拨号换IP,就不怕遇到IP被封的状况了,即便某个IP被封了,从新拨一次号就行了。
因此接下来咱们要作的就有两件事,一是怎样将主机设置为代理服务器,二是怎样实时获取拨号主机的IP。
以前咱们常常据说代理服务器,也设置过很多代理了,可是可能没有本身设置吧,本身有一台主机怎样设置为代理服务器呢?接下来咱们就亲自试验下怎样搭建HTTP代理服务器。
在Linux下搭建HTTP代理服务器,推荐TinyProxy和Squid,配置都很是简单,在这里咱们以TinyProxy为例来说解一下怎样搭建代理服务器。
固然第一步就是安装TinyProxy这个软件了,在这里我使用的系统是CentOS,因此使用yum来安装,若是是其余系统如Ubuntu能够选择apt-get等命令安装,都是相似的。
命令行执行yum安装指令:
运行完成以后就能够完成tinyproxy的安装了。
安装完成以后还须要配置一下TinyProxy才能够用做代理服务器,须要编辑配置文件,它通常的路径是/etc/tinyproxy/tinyproxy.conf
。
能够看到有一行
在这里能够设置代理的端口,默认是8888。
而后继续向下找,有这么一行
这是被容许链接的主机的IP,若是想任何主机均可以链接,那就直接将它注释便可,因此在这里咱们选择直接注释,也就是任何主机均可以使用这台主机做为代理服务器了。
修改成
设置完成以后重启TinyProxy便可。
验证TinyProxy
好了,这样咱们就成功搭建好代理服务器了,首先ifconfig
查看下当前主机的IP,好比当前个人主机拨号IP为112.84.118.216
,在其余的主机运行测试一下。
好比用curl命令设置代理请求一下httpbin,检测下代理是否生效。
若是有正常的结果输出而且origin的值为代理IP的地址,就证实TinyProxy配置成功了。
好,那到如今,咱们接下来要作的就是须要动态实时获取主机的IP了。
真正的好戏才开始呢,咱们怎样动态获取主机的IP呢?可能你首先想到的是DDNS也就是动态域名解析服务,咱们须要使用一个域名来解析,也就是虽然IP是变的,但域名解析的地址能够随着IP的变化而变化。
它的原理实际上是拨号主机向固定的服务器发出请求,服务器获取客户端的IP,而后再将域名解析到这个IP上就能够了。
国内比较有名的服务就是花生壳了,也提供了免费版的动态域名解析,另外DNSPOD也提供了解析接口来动态修改域名解析设置,DNSPOD,可是这样的方式都有一个通病,那就是慢!
缘由在于DNS修改后到彻底生效是须要必定时间的,因此若是在前一秒拨号了,这一秒的域名解析的可能仍是原来的IP,时间长的话可能须要几分钟,也就是说这段时间内,服务器IP已经变了,可是域名仍是上一次拨号的IP,因此代理是不能用的,对于爬虫这种秒级响应的需求,是彻底不能接受的。
因此根据花生壳的原理,能够彻底本身实现一下动态获取IP的方法。
因此本节重点介绍的就是怎样来实现实时获取拨号主机IP的方法。
要实现这个须要两台主机,一台主机就是这台动态拨号VPS主机,另外一台是具备固定公网IP的主机。动态VPS主机拨号成功以后就请求远程的固定主机,远程主机获取动态VPS主机的IP,就能够获得这个代理,将代理保存下来,这样拨号主机每拨号一次,远程主机就会及时获得拨号主机的IP,若是有多台拨号VPS,也统一发送到远程主机,这样咱们只须要从远程主机取下代理就行了,保准是实时可用,稳定高效的。
总体思路大致是这样子,固然为了更完善一下,咱们要作到以下功能:
远程主机:
拨号VPS:
说了这么多,那么咱们就梳理一下具体的实现吧,整个项目咱们用Python3实现。
远程主机做为一台服务器,动态拨号VPS会定时请求远程主机,远程主机接收到请求后将IP记录下来存入数据库。
由于IP是一直在变化的,IP更新了以后,原来的IP就不能用了,因此对于一个主机来讲咱们可能须要屡次更新一条数据。另外咱们不能仅限于维护一台拨号VPS主机,固然是须要支持多台维护的。在这里咱们直接选用Key-Value形式的非关系型数据库存储更加方便,因此在此选用Redis数据库。
既然是Key-Value,Key是什么?Value是什么?首先咱们能肯定Value就是代理的值,好比112.84.119.67:8888,那么Key是什么?咱们知道,这个IP是针对一台动态拨号VPS的,并且这个值会不断地变,因此咱们须要有一个不变量Key来惟一标识这台主机,因此在这里咱们能够把Key当作主机名称。名称怎么来?本身取就行了,只要每台主机的名字不重复,咱们就能够区分出是哪台主机了,这个名字能够在拨号主机那边指定,而后传给远程主机就行了。
因此,在这里数据库咱们选用Redis,Key就是拨号主机的名称,能够本身指定,Value就是代理的值。
因此能够写一个操做Redis数据库的类,参考以下:
首先初始化Redis链接,咱们能够将Key设计成adsl:vm1
这种形式,冒号前面是总的key,冒号后面是主机名称name,这样显得结构更加清晰。
而后指定set()和get()方法,用来存储代理和获取代理。
拨号主机会一直向远程主机发送请求,远程主机固然能够获取拨号主机的IP,可是代理端口是没法得到的,咱们在拨号主机上设置了TinyProxy或者Squid,可是服务器不知道是在哪一个端口开的,因此端口也是须要客户端传给远程主机的。远程主机接收到请求后,将解析获得的IP和端口合并就能够做为完整的代理保存了。
因此如今咱们知道拨号主机须要传送给远程主机的信息已经有两个了,一是拨号主机自己的名称,二是代理的端口。
为了保证远程主机不被恶意的请求干扰,能够设置一个传输秘钥,最简单的方式能够两者共同规定一个秘钥字符串,拨号主机在传送这个字符串,远程主机匹配一下,若是能正确匹配,那就进行下一步的处理,若是不能匹配,那么多是恶意请求,就忽略这个请求。
固然确定有更好的加密传输方式,但为了方便起见能够用如上来作。
因此客户机还须要传送一个数据,那就是通讯秘钥,一共须要传送三个数据。
因此咱们须要架设一个服务器,一直监听客户端的请求,在这里咱们用tornado实现。
tornado的安装也很是简单,利用pip安装便可:
定义一个处理拨号主机请求的方法,在这里咱们使用post请求,参考以下。
远程主机获取请求的token,也就是上面咱们所说的通讯密钥,保证安全。port是拨号机的代理端口,name是拨号主机的名称。而后咱们再获取请求的remote_ip,也就是拨号主机的IP。而后将IP和端口拼合就能够获得拨号主机的完整代理信息了,将其存入数据库便可。
在远程主机端咱们须要作一下代理检测,若是某个代理不可用了,会及时将其去除,以避免出现获取到代理后不可用的状况。
注意:在这里在拨号主机端验证是不够的,由于可能忽然遇到某个拨号主机宕机的状况,这样拨号主机就不会再向远程主机发送请求,而最后一次获得的代理还会存在于数据库中,因此在远程主机端统一验证比较科学。
验证方式能够定时检测,也能够每收到一次请求检测一次,用获取到的代理来请求某个网站,检测一下是否能访问便可。若是不能,将其从数据库中删除。
远程主机已经将拨号主机的IP和端口保存下来了,那也就是说,全部的可用的代理已经在远程主机保存了,咱们须要提供一个接口来将代理获取下来。
好比咱们能够提供这么几个方法,获取全部代理,获取最新代理,获取随机代理等等。
而后用tornado搭建API服务,若是能够的话还能够绑定一个域名,更加便捷,举例以下:
获取随机代理:
获取最新代理:
获取全部代理:
请求接口获取可用代理便可,好比获取一个随机代理:
这样咱们拿到的IP都是稳定可用的,并且过段时间从新请求取到的IP就会变化,是一直动态变化的高可用代理。
拨号VPS须要每隔一段时间就拨号一次,咱们能够直接执行命令行来拨号,那在Python里咱们只须要调用一下这个拨号命令就行了。利用subprocess模块调用脚本便可,在这里定义一个变量ADSL_BASH为adsl-stop;adsl-start
,这就是拨号的脚本。
经过getstatusoutput方法能够获取脚本的执行状态和输出结果,若是status为0,则证实拨号成功,而后检测一下拨号接口是否获取了IP地址。
执行ifconfig
命令能够获取当前的IP,我这台主机接口名称叫作ppp0,固然网卡名称能够本身指定,因此将ppp0接口的IP提取出来便可。
若是方法正常返回IP,则证实IP存在,拨号成功,接下来向远程主机发送请求便可,而后sleep一段时间从新再次拨号。
若是方法返回的值为空,那证实IP不存在,咱们须要从新拨号。
发送的时候须要携带这么几个信息,一个是通讯秘钥,一个是代理端口,另外一个是主机的标识符,用requests发送便可。
因此总体的思路实现能够写成这样子:
这样咱们就能够作到定时拨号并向远程主机发送请求了。
Talk is cheap, show me the code! 在这里提供一份完整代码实现,其中client模块是在动态VPS主机运行,server模块在远程主机运行,具体的操做使用能够参考README。
转载请注明:静觅 » 使用Tornado+Redis维护ADSL拨号服务器代理池