电脑网络 · 2018年05月2号 0

Tor网络突破IP封锁,爬虫好搭档【入门手册】

前言

本文不提供任何搭梯子之类的内容,我在这里仅仅讨论网络爬虫遇到的IP封杀,然后使用Tor如何对抗这种封杀。作为一种技术上的研究讨论。

场景

我们编写的网络爬虫全网采集的时候总会有一些网站有意识的保护自己的网站内容,以防止网络爬虫的抓取。常见的方式就是通过身份验证的方式来进行人机识别。也就是在登陆(查询)的入口增加或者加固防御。这些防御有那些呢?我目前见到的有:各种验证码、参数的加密、在前端JS挖坑、访问频率限制(IP黑名单)等。

其实前面的几种我们在某些情况下都是有办法解决的,我一一举例:

1、加密参数。其实老司机们都知道了,在客户端加密参数并没有什么卵用。因为爬虫完全可以将前端的js丢到一个游览器的内核环境中去执行js,这样的话,无论你怎么加密,都没有用,因为这和在游览器中运行没有什么区别,是无法进行人机识别的。

2、前端在Js脚本中挖坑。这是一些小聪明了,毕竟被抓取的网站方是这场战争的游戏规则制定者,他们能够自己制定规则,然后在没有什么漏洞的情况下,爬虫只能按照对方指定的规则一条条的来,一个坎一个坎的去跨。

这种情况下,网站开发人员在一大堆的js中藏着一小段预警js作为地雷。毕竟一般情况下,爬虫都是直接请求后得到的响应是一段html的文本,并不会执行其中的js。那么这样就区分出来了,网站方可以在页面加载后执行一段js,这段js不用和服务器通信,就是默默的执行。若是这段js执行了,说明访问者很可能是人,若是没有执行,那么这个访问真绝对是爬虫了。我们在正文请求中附带上的cookie中加上一个特定的标记。告诉服务器这个请求不是人发起的。服务器得到这个消息后,针对IP标记,但是这次请求是允许通过的(隐藏我们的判断依据)。下次或者这个IP访问几次后,就将这个IP拉入黑名单。

3、验证码,这东西是主要防御手段,这里不多说,我博客里面也有一篇关于这个文章。但是,只要技术能力足够,验证码还是会被突破的。君不见,12306验证码防御也没什么用。

4、IP黑名单,这个是依赖于上面的一个后台防御策略。但是再某种情况下,这种策略确实很有效,而且无解。

比如:有一个查询类的网站,通过限制IP的访问次数、频率就完全可以封锁或者限制爬虫,因为爬虫的意义就是自动化的、高效的得到数据。

IP黑名单突破的方案

针对于采用黑名单的网站,我们可以使用的策略就是代理了,我们用各种方式弄到一大批的代理IP,然后通过使用这些代理IP去发起请求,IP被封锁了,就换下一个。

我们的主题,Tor网络也就用在这里了。

首先来科普一下:

 

关于Tor网络

官网:https://www.torproject.org/

Tor网络突破IP封锁,爬虫好搭档【入门手册】

Tor是什么

  Tor是互联网上用于保护您隐私最有力的工具之一,但是时至今日仍有许多人往往认为Tor是一个终端加密工具。事实上,Tor是用来匿名浏览网页和邮件发送(并非是邮件内容加密)的。今天,我们要讨论一下Tor的是如何工作的、它做什么、不会做什么,以及我们该如何正确地使用它。

Tor的工作原理是这样的

当你通过Tor发送邮件时, tor会使用一种称为“洋葱路由”的加密技术通过网络随机生成的过程传送邮件。这有点像在一叠信中放了一封密信。网络中的每个节点都会解密消息(打开的最外信封),然后发送内部加密的内容(内密封的信封)至其下一个地址。这导致如果单看一个节点是看不了信的全部内容,并且该消息的传送路径难以追踪。

 Tor网络突破IP封锁,爬虫好搭档【入门手册】

 在Windows上使用Tor

windows上安装tor很简单,去Tor的官网下载安装洋葱游览器就可以了。

当然,我们可以只安装Tor核心,不安装任何其他附属,然后我们去找个Tor控制器,去操作Tor就可以了。

我这里有两个版本Tor控制器,Windows的Vidalia和OS X版本的Arm(Anonymizing Relay Monitor)这东西就Python开发的,可以完成Vidalia的绝大部分功能。

windows上的Vidalia:

Tor网络突破IP封锁,爬虫好搭档【入门手册】

 Mac上的Arm:

Tor网络突破IP封锁,爬虫好搭档【入门手册】

目前我使用的也就是在Mac上操作的Arm。我也是重点说Arm的。因为Window下的Tor通过C#或者Python控制都不行,不得已的情况下,换到了OS X/Linux的环境下来控制Tor。

安装Tor、Arm

首先我们得下载安装了,好消息是,Arm和Tor大部分的包管理器都有,我们可以直接下载。通过包管理器下载后,会自动安装,并完成初始化配置。

例如我在Mac上的安装以及配置:

brew install tor
brew install arm

Tor网络突破IP封锁,爬虫好搭档【入门手册】

我们另外需要安装Privoxy,需要通过Privoxy来将Socks5转换成Http。

brew install Privoxy

Tor网络突破IP封锁,爬虫好搭档【入门手册】

最后,我们还需要一个前置代理,因为Tor网络,在国内是不能访问的。所以我们需要一个在国外的前置代理,目前我自己已经搭建好了一个位于加拿大的VPN,这里可以直接用的。

配置Tor、Arm

我们需要做一些配置,我先给一张我的配置图:

Tor网络突破IP封锁,爬虫好搭档【入门手册】

这是从已经配置好的Arm看到的。如上图,绿色的字体就是我给torrc配置文件增加的内容。

我们修改配置就是在 /Users/ Likeli/.arm/torrc 路径(Mac下的路径)。完成以上修改。

Tor网络突破IP封锁,爬虫好搭档【入门手册】

关于重要参数的说明:

参数 说明
ControlPort 控制程序访问的端口(重要)
Socks5Proxy 前置代理端口
SocksProt 外部程序访问Tor的端口
MaxCircuitDirtiness 自动切换Identity的时间间隔

除了这些参数,其实还有很多的备选参数,详细说明请查看tor帮助文档,以上配置也是我从tor的官方帮助文档中找到的。

man tor

Tor网络突破IP封锁,爬虫好搭档【入门手册】

好了,配置完成了,现在去出去启动Arm,完成初始化。

在终端运行Arm,我直接用Mac 的截图工具,貌似不能构绘制圆圈勾选,这里提供几张别出弄来的图,按照选择就ok了。

Arm配置源地址:https://program-think.blogspot.com/2015/03/Tor-Arm.html?utm_source=tuicool&utm_medium=referral

Tor网络突破IP封锁,爬虫好搭档【入门手册】

 

Tor网络突破IP封锁,爬虫好搭档【入门手册】

 

Tor网络突破IP封锁,爬虫好搭档【入门手册】

配置好了,然后启动,启动成功后如下图:

下方的启动日志显示,启动进度100%。

Tor网络突破IP封锁,爬虫好搭档【入门手册】

好了,到这一步,其实代理已经通了,来测一测。

Tor网络突破IP封锁,爬虫好搭档【入门手册】

Tor网络突破IP封锁,爬虫好搭档【入门手册】

Tor网络突破IP封锁,爬虫好搭档【入门手册】

好了,搞定了,目前Tor的Socks5代理已经接通,我们直接连接127.0.0.1:9000就可以了。这里的端口是自己根据上面的配置来的。

收尾

虽然代理通了,但是还有问题,因为一般我们都是用的Http的代理。所以我们需要将Socks5代理转换成Http代理来方便我们的应用程序使用。

这里用到的工具是:Privoxy(上面的步骤中,已经通过软件库安装了)

我们需要对这个做一下一点点配置修改。

我们安装Privoxy后,打开它的配置文件:

Tor网络突破IP封锁,爬虫好搭档【入门手册】

打开后,搜索 127.0.0.1:9050

找到下图中的为之后,另起一行,插入 forward-socks5 / 127.0.0.1:9000  .

Tor网络突破IP封锁,爬虫好搭档【入门手册】

配置完成后保存关闭,若是我们尝试连接本地的8118端口,也就是 127.0.0.1:8118

若是连接不上,重启一下服务,或者重启电脑。

这里的8118端口也是可以修改的,若是修改,请直接在Privoxy的配置文件中搜索127.0.0.1:8118,并修改8118端口就可以了。

到这里我们就完成了所有的配置了,任何程序直接访问127.0.0.1:8118,并将至设置为代理,就可以躲避网站的IP限制了。

最后

以上中测试代理可以在Chrome中安装SwitchySharp插件,然后稍加配置就可以了。

好了,自由享受无限IP的刺激把,如此以后,IP黑名单(IP封锁)形同虚设~

最后附上Python控制Tor切换IP的样例代码:来源(https://stackoverflow.com/questions/9887505/how-to-change-tor-identity-in-python

复制代码
 1 import urllib2
 2 from TorCtl import TorCtl
 3 
 4 proxy_support = urllib2.ProxyHandler({"http" : "127.0.0.1:8118"})
 5 opener = urllib2.build_opener(proxy_support) 
 6 
 7 def newId():
 8     conn = TorCtl.connect(controlAddr="127.0.0.1", controlPort=9051, passphrase="your_password")
 9     conn.send_signal("NEWNYM")
10 
11 for i in range(0, 10):
12     print "case "+str(i+1)
13     newId()
14     proxy_support = urllib2.ProxyHandler({"http" : "127.0.0.1:8118"})
15     urllib2.install_opener(opener)
16     print(urllib2.urlopen("http://www.ifconfig.me/ip").read())