爬虫进阶——解决封IP问题| 部署ADSL服务器获取动态IP

1.问题背景

我们公司需要到某环保平台爬取环保信息,但平台那边先从封cookie开始,后来又封IP,目前又开始封账号。。本章就讲讲封IP问题的一个解决策略——部署ADSL服务器吧。

ADSL服务器是什么,我在这里就不详说了,可以百度下,总结来说,就是可以通过不断的拨号断开宽带连接,从而获取新的IP。

我们老板是一个善良的人,嗯嗯,要求很明确,一是爬虫脚本能运行稳定,二是成本低(泻药。。。),然后我和另外一个同事一同测试ip代理和ADSL服务器,发现,ADSL动态拨号还是相当稳定的,于是果断选择ADSL。

ADSL服务器不但便宜,而且稳定,但比较头疼的是,服务器需要我们自己部署,折腾了好几天,总算解决了各种问题,需要考虑的问题有以下几个方面:

  • 如何部署ADSL服务器;
  • 如何才能让ADSL服务器动态拨号,获取新的IP;
  • 如何才能让公司的脚本自动获取远程ADSL服务器的IP;
  • 【需要认真琢磨的】怎样对脚本改进,使得能够实现对IP的最大利用。

2.部署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。

3.如何才能让ADSL服务器动态拨号,获取新的IP

不说废话了,在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()

4.如何才能让公司的脚本自动获取远程ADSL服务器的IP

24点了...困了,有时间补上。。。提示:在本地运行一个获取ip脚本,用到的主要模块是paramiko...

你可能感兴趣的:(爬虫)