我们公司需要到某环保平台爬取环保信息,但平台那边先从封cookie开始,后来又封IP,目前又开始封账号。。本章就讲讲封IP问题的一个解决策略——部署ADSL服务器吧。
ADSL服务器是什么,我在这里就不详说了,可以百度下,总结来说,就是可以通过不断的拨号断开宽带连接,从而获取新的IP。
我们老板是一个善良的人,嗯嗯,要求很明确,一是爬虫脚本能运行稳定,二是成本低(泻药。。。),然后我和另外一个同事一同测试ip代理和ADSL服务器,发现,ADSL动态拨号还是相当稳定的,于是果断选择ADSL。
ADSL服务器不但便宜,而且稳定,但比较头疼的是,服务器需要我们自己部署,折腾了好几天,总算解决了各种问题,需要考虑的问题有以下几个方面:
我使用的是云立方的动态拨号服务,预装的系统是ubuntu14.04,因为个人熟悉的原因。如果你喜欢Centos或者windows,也可以。以下是折腾几天部署服务器的总结:
目前使用的是云立方平台提供的ADSL动态拨号服务。
URL: https://www.yunlifang.cn/
Account: 账户名:XXXX 密码:XXXX 自己注册下吧。
0.远程登录
ssh root@远程ip -p 端口号
1.TinyProxy安装,在安装前应该先adsl-start打开网络,否则安装包无法更新。
adsl-start
sudo apt-get update
apt-get install tinyproxy
注:在云立方ADSL服务器中, adsl-start/stop是pppoe-start/stop的别名,是shell命令。
2.然后配置参数文件:
vi /etc/tinyproxy.conf
3.修改下面两个部分。
Port 8888 #预设是8888端口
Allow 127.0.0.1 #将127.0.0.1改成你自己的IP,只有这个IP才能连接,前面打#注释掉则所有人都可以连接
4.TinyProxy打开与关闭
service tinyproxy start/restart/stop
5.在sender.py文件目录下发送文件到远程服务器根目录下
scp -P 20133 sender.py [email protected]:~/
6.安装依赖的包文件
apt-get install python3-pip
pip3 install requests
[
进程查看命令
ps -ef | grep python/ppp
]
7.在运行sender.py文件前务必关闭防火墙
sudo apt-get install ufw
sudo ufw disable
8.运行sender2.py
python3 sender2.py便可获取新的ip
9.有时会遇到多个ppp的问题,这是由于ppp进程冲突导致的,解决方法是重启服务器,
reboot
10.有时会遇到adsl-start超时问题,重启也无法解决,貌似是宽带的问题,还是直接问云立方客服吧, QQ:4006677945。
不说废话了,在2里第8个步骤我已经提示了下,就是通过运行sender2.py这个脚本,从而实现ip的自动更换,下面直接粗暴的贴上代码,核心代码就是 pppoe-start/stop,执行一次脚本后,就能实现动态拨号:
import subprocess
import re
import requests
import time
# 拨号网卡
ADSL_IFNAME = 'ppp1'
# 测试URL
TEST_URL = 'http://www.baidu.com'
# 测试超时时间
TEST_TIMEOUT = 5
# 拨号出错重试间隔
ADSL_ERROR_CYCLE = 3
# ADSL命令
ADSL_BASH_STOP = 'pppoe-stop'
ADSL_BASH_START = 'pppoe-start'
# 代理运行端口
PROXY_PORT = 8888
# 客户端唯一标识
CLIENT_NAME = 'adsl1'
class Sender(object):
def get_ip(self, ifname=ADSL_IFNAME):
"""
获取本机ip
:param ifname: 网卡名称
:return:
"""
(status, output) = subprocess.getstatusoutput('ifconfig')
if status == 0:
print(output)
result = re.findall(ifname + '.*?inet addr:.*?(\d+\.\d+\.\d+\.\d+)', output, re.S | re.I)
if result:
ip = result[0]
return ip
def test_proxy(self, proxy):
"""
测试代理
:param proxy: 代理
:return: 测试结果
"""
try:
response = requests.get(TEST_URL, proxies={
'http': 'http://' + proxy,
'https': 'https://' + proxy
}, timeout=TEST_TIMEOUT)
if response.status_code == 200:
return True
except Exception as e:
print(e)
return False
def adsl(self):
"""
拨号主进程
:return: None
"""
print('ADSL Start, Remove Proxy, Please wait')
subprocess.getstatusoutput(ADSL_BASH_STOP)
time.sleep(0.5)
(status, output) = subprocess.getstatusoutput(ADSL_BASH_START)
print('status', status, 'output', output)
if status == 0:
print("ADSL successfully")
ip = self.get_ip()
if ip:
print('Now IP', ip)
print('Testing Proxy, Please wait')
proxy = '{ip}:{port}'.format(ip=ip, port=PROXY_PORT)
while True:
if self.test_proxy(proxy):
print('Valid Proxy')
break
else:
print('Invalid Proxy')
print('Sleeping')
subprocess.getstatusoutput('service tinyproxy stop')
time.sleep(0.5)
subprocess.getstatusoutput('service tinyproxy restart')
else:
print('Get IP Failed, Redailing')
if __name__ == '__main__':
sender = Sender()
sender.adsl()
24点了...困了,有时间补上。。。提示:在本地运行一个获取ip脚本,用到的主要模块是paramiko...