爬虫进阶:反反爬虫技术--2 使用可变IP

一:IP代理池
从技术上说,IP 地址是可以通过发送数据包进行伪装的,就是分布式拒绝服务攻击技术(Distributed Denial of Service,DDoS),攻击者不需要关心接收的数据包(这样发送请求的时候就可以使用假 IP 地址)。但是网络数据采集是一种需要关心服务器响应的行为,所以我们认为 IP 地址是不能造假的。

如果一个固定的ip在短暂的时间内,快速大量的访问一个网站,那自然会引起注意,管理员可以通过一些手段把这个ip给封了,爬虫程序自然也就做不了什么了。

解决方法:

比较成熟的方式是:IP代理池
简单的说,就是通过ip代理,从不同的ip进行访问,这样就不会被封掉ip了。
可是ip代理的获取本身就是一个很麻烦的事情,网上有免费和付费的,但是质量都层次不齐。如果是企业里需要的话,可以通过自己购买集群云服务来自建代理池。

这里实现了一个简单的代理转换,代码如下:

# -*- coding: utf-8 -*-
#生成可用代理ip#python版本2.7
from bs4 import BeautifulSoup
import httplib
import threading
import sys
import time
import random
reload(sys)
sys.setdefaultencoding('utf-8')
inFile = open('proxy.txt')
outFile = open('verified.txt', 'w')
lock = threading.Lock()

# 利用一个正则就可以直接采集代理IP的站点
PROXY_SITES_BY_REGX = {
    'urls': [
        'http://ab57.ru/downloads/proxyold.txt',
        'http://www.proxylists.net/http_highanon.txt',
        'http://www.atomintersoft.com/high_anonymity_elite_proxy_list',
        'http://www.atomintersoft.com/transparent_proxy_list',
        'http://www.atomintersoft.com/anonymous_proxy_list',
        'http://www.proxy4free.info/',
        'http://tools.rosinstrument.com/proxy/plab100.xml',
        'https://www.rmccurdy.com/scripts/proxy/good.txt',
        'http://proxy.ipcn.org/proxylist2.html',
        'http://best-proxy.ru/feed',
        'http://www.proxylists.net/?HTTP',
        'http://uks.pl.ua/script/getproxy.php?last'
    ],
    'proxy_regx': r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{2,4}"
}

# 需要利用xpath 定位代理IP 的站点
PROXY_SITES_BY_XPATH = [
    {
        'urls': ['http://www.66ip.cn/%s.html' % page for page in ['index'] + list(range(2, 11))],
        'ip_xpath': ".//*[@id='main']/div/div[1]/table/tr[position()>1]/td[1]/text()" ,
        'port_xpath': ".//*[@id='main']/div/div[1]/table/tr[position()>1]/td[2]/text()"
    },
    {
        'urls': ['http://www.mimiip.com/gngao/%s' % page for page in range(2, 10)],
        'ip_xpath': ".//table[@class='list']/tbody/tr/td[1]/text()",
        'port_xpath': ".//table[@class='list']/tbody/tr/td[2]/text()"
    },
    {
        'urls': ['http://www.ip181.com/daili/%s.html' % page for page in range(1, 8)],
        'ip_xpath': ".//div[@class='row']/div[3]/table/tbody/tr[position()>1]/td[1]/text()" ,
        'port_xpath': ".//div[@class='row']/div[3]/table/tbody/tr[position()>1]/td[2]/text()"
    }
]
# 代理输出位置
OUTPUT_FILE = "proxy_list.txt"
AgentFile = r"D:\Python Programs\Crawler\Web Crawler\user_agents.txt"
def Header_get():
    agents = []
    for line in open(AgentFile, "r"):
        agents.append(line.strip('\n\r')[1:-1])
    fakeheader = {}
    fakeheader['User-agent'] = agents[random.randint(0, len(agents)-1)]
    return fakeheader

#这里没有完全将上面所有存在代理ip的地址全部爬取下来,你可以将那些网址上的ip直接拷贝写到文件上,然后测试哪个对你当前的网络能够使用,这里使用百度的网址进行测试
def inspect_ip():
    requestHeader = {
        'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36"}
    myurl = 'http://www.baidu.com/'
    while True:
        lock.acquire()
        ll = inFile.readline().strip()
        lock.release()
        if len(ll) == 0: break
        line = ll.strip().split(':')
        ip = line[0]
        port = line[1]
        try:
			#http://ip:prot,httplib.HTTPConnection才是https
            conn = httplib.HTTPConnection(ip, port, timeout=5.0)
            conn.request(method='GET', url=myurl, headers=requestHeader)
            res = conn.getresponse()
            lock.acquire()
            print "+++Success:" + ip + ":" + port
            outFile.write(ll + "\n")
            lock.release()
        except:
            print "---Failure:" + ip + ":" + port

if __name__ == '__main__':
    inspect_ip() 

常见的代理ip使用方法:

 web_data = requests.get(url, headers=headers, proxies=proxies)     

另外国内还有个比较有名的代理ip网站
http://www.xicidaili.com/nn/

需要注意的是,由于知道的人比较多,网站也是有针对爬虫的一些手段,爬取这个网站的代理ip时,爬取效率不要太高,免得该网站把你ip封了

二:Tor 代理服务器

洋葱路由(The Onion Router)网络,常用缩写为 Tor,是一种 IP 地址匿名手段。由网络志愿者服务器构建的洋葱路由器网络,通过不同服务器构成多个层(就像洋葱)把客户端包在最里面。数据进入网络之前会被加密,因此任何服务器都不能偷取通信数据。另外,虽然每一个服务器的入站和出站通信都可以被查到,但是要想查出通信的真正起点和终点,必须知道整个通信链路上所有服务器的入站和出站通信细节,而这基本是不可能实现的。
 Tor 匿名的局限性
虽然我们在本文中用 Tor 的目的是改变 IP 地址,而不是实现完全匿名,但有必要关注一下 Tor 匿名方法的能力和不足。

虽然 Tor 网络可以让你访问网站时显示的 IP 地址是一个不能跟踪到你的 IP 地址,但是你在网站上留给服务器的任何信息都会暴露你的身份。例如,你登录 Gmail 账号后再用 Google 搜索,那些搜索历史就会和你的身份绑定在一起。

另外,登录 Tor 的行为也可能让你的匿名状态处于危险之中。2013 年 12 月,一个哈佛大学本科生想逃避期末考试,就用一个匿名邮箱账号通过 Tor 网络给学校发了一封炸弹威胁信。结果哈佛大学的 IT 部门通过日志查到,在炸弹威胁信发来的时候,Tor 网络的流量只来自一台机器,而且是一个在校学生注册的。虽然他们不能确定流量的最初源头(只知道是通过 Tor 发送的),但是作案时间和注册信息证据充分,而且那个时间段内只有一台机器是登录状态,这就有充分理由起诉那个学生了。

登录 Tor 网络不是一个自动的匿名措施,也不能让你进入互联网上任何区域。虽然它是一个实用的工具,但是用它的时候一定要谨慎、清醒,并且遵守道德规范。

在 Python 里使用 Tor,需要先安装运行 Tor,下一节将介绍。Tor 服务很容易安装和开启。只要去 Tor 下载页面下载并安装,打开后连接就可以。不过要注意,当你用 Tor 的时候网速会变慢。这是因为代理有可能要先在全世界网络上转几次才到目的地!

三:PySocks

PySocks 是一个非常简单的 Python 代理服务器通信模块,它可以和 Tor 配合使用。你可以从它的网站(https://pypi.python.org/pypi/PySocks)上下载,或者使用任何第三方模块管理器安装。

这个模块的用法很简单。示例代码如下所示。运行的时候,Tor 服务必须运行在 9150 端口(默认值)上:
在这里插入图片描述

网站 http://icanhazip.com/ 会显示客户端连接的网站服务器的 IP 地址,可以用来测试 Tor 是否正常运行。当程序执行之后,显示的 IP 地址就不是你原来的 IP 了。

如果你想在 Tor 里面用 Selenium 和 PhantomJS,不需要 PySocks,只要保证 Tor 在运行,然后增加 service_args 参数设置代理端口,让 Selenium 通过端口 9150 连接网站就可以了:
在这里插入图片描述

和之前一样,这个程序打印的 IP 地址也不是你原来的,而是你通过 Tor 客户端获得的 IP 地址。

四:从网站主机运行

如果你拥有个人网站或公司网站,那么你可能已经知道如何使用外部服务器运行你的网络爬虫了。即使是一些相对封闭的网络服务器,没有可用的命令行接入方式,你也可以通过网页界面对程序进行控制。

如果你的网站部署在 Linux 服务器上,应该已经运行了 Python。如果你用的是 Windows 服务器,可能就没那么幸运了;你需要仔细检查一下 Python 有没有安装,或者问问网管可不可以安装。

大多数小型网络主机都会提供一个软件叫 cPanel,提供网站管理和后台服务的基本管理功能和信息。如果你接入了 cPanel,就可以设置 Python 在服务器上运行——进入“Apache Handlers”然后增加一个 handler(如还没有的话):
在这里插入图片描述

这会告诉服务器所有的 Python 脚本都将作为一个 CGI 脚本运行。CGI 就是通用网关接口(Common Gateway Interface),是可以在服务器上运行的任何程序,会动态地生成内容并显示在网站上。把 Python 脚本显式地定义成 CGI 脚本,就是给服务器权限去执行 Python 脚本,而不只是在浏览器上显示它们或者让用户下载它们。

写完 Python 脚本后上传到服务器,然后把文件权限设置成 755,让它可执行。通过浏览器找到程序上传的位置(也可以写一个爬虫来自动做这件事情)就可以执行程序。如果你担心在公共领域执行脚本不安全,可以采取以下两种方法。

把脚本存储在一个隐晦或深层的 URL 里,确保其他 URL 链接都不能接入这个脚本,这样可以避免搜索引擎发现它。
用密码保护脚本,或者在执行脚本之前用密码或加密令牌进行确认。

确实,通过这些原本主要是用来显示网站的服务运行 Python 脚本有点儿复杂。比如,你可能会发现网络爬虫运行时网站的加载速度变慢了。其实,在整个采集任务完成之前页面都是不会加载的(得等到所有“print”语句的输出内容都显示完)。这可能会消耗几分钟,几小时,甚至永远也完成不了,要看程序的具体情况了。虽然它最终一定能完成任务,但是可能你还想看到实时的结果,这样就需要一台真正的服务器了。

五:从云主机运行

虽然云计算的花费可能是无底洞,但是写这篇文章时,启动一个计算实例最便宜只要每小时 1.3 美分(亚马逊 EC2 的 micro 实例,其他实例会更贵),Google 最便宜的计算实例是每小时 4.5 美分,最少需要用 10 分钟。考虑计算能力的规模效应,从大公司买一个小型的云计算实例的费用,和自己买一台专业实体机的费用应该差不多——不过用云计算不需要雇人去维护设备。

设置好计算实例之后,你就有了新 IP 地址、用户名,以及可以通过 SSH 进行实例连接的公私密钥了。后面要做的每件事情,都应该和你在实体服务器上干的事情一样了——当然,你不需要再担心硬件维护,也不用运行复杂多余的监控工具了。

猜你喜欢

转载自blog.csdn.net/huoyingchong64/article/details/89707295