使用scrapy做爬虫遇到的一些坑:网站常用的反爬虫策略,如何机智的躲过反爬虫Crawled (403)

在这幅图中我们可以很清晰地看到爬虫与反爬虫是如何进行斗智斗勇的。

在学习使用爬虫时,我们制作出来的爬虫往往是在“裸奔”,非常的简单。

简单低级的爬虫有一个很大的优点:速度快,伪装度低。如果你爬取的网站没有反爬机制,爬虫们可以非常简单粗暴地快速抓取大量数据,但是这样往往就导致一个问题,因为请求过多,很容易造成服务器过载,不能正常工作。

于是许多网站为了保护自己的服务器,往往会采用反爬虫技术来“狙击”爬虫,让爬虫无法正常工作。


网站一般是如何进行识别爬虫呢?总的来说有以下几种:

一.检查header信息,一般有User-Agent,Referer、Cookies等等

1.User-Agent是检查用户所用客户端的种类和版本,在Scrapy中,通常是在下载器中间件中进行处理。
2.Referer是检查此请求由哪里来,通常可以做图片的盗链判断。在Scrapy中,如果某个页面url是通过之前爬取的页面提取到,Scrapy会自动把之前爬取的页面url作为Referfer。也可以通过上面的方式自己定义Referfer字段。
3.网站可能会检测Cookie中session_id的使用次数,如果超过限制,就触发反爬策略。

二. 网站常常会针对IP访问频率统计,设置一个阈值,当超过这个阈值时,网站就会判断这个IP访问太过频繁,会短时间甚至永久性地禁止该IP地址的访问 。

三.网站往往会给一个浏览器隐藏的连接,正常的浏览网页的人看不见,也更加不会去点击。加入来访者点击了改连接,就会被网站认定是爬虫。

那么网站识别出爬虫后就会像上图一样,开始给爬虫设置各种关卡啦!

1.设置限制访问:在一段时间内该IP是无法访问的

2.返回验证码:要求用户输入验证码,防止用户是机器

3.采用ajax异步加载:如果只是爬取静态网页的爬虫是什么都得不到的

4.爬虫陷阱:让你爬取的内容变成其他和本网站无关的信息

5.加速乐的服务:在访问之前先判断客户端的cookie正不正确。如果不正确,返回521状态码,set-cookie并且返回一段js代码通过浏览器执行后又可以生成一个cookie,只有这两个cookie一起发送给服务器,才会返回正确的网页内容。

6.javascript渲染:网页开发者将重要信息放在网页中但不写入html标签中,而浏览器会自动渲染<script>标签的js代码将信息展现在浏览器当中,而爬虫是不具备执行js代码的能力,所以无法将js事件产生的信息读取出来

至此,如果还有爬虫能够突破这些重围,那就是人生赢家了!网站一般就放弃阻止这只厉害的无法无天的爬虫了,因为再继续拦阻下去,成本会很高,得不偿失,而且如果因为反爬虫的技术太厉害,往往还会误伤友军,让一部分用户无法正常浏览网站。一般而言,反爬高效往往会与误伤友军率成非线性正比。

针对以上的反爬,可以有以下几种躲过反爬虫的策略。

1.设置等待时间:

直接:导入time,然后限制时间为正常人浏览时间

间接:看具体情况来等待,比如某些元素需要一定时间加载。wait1.until(lambda driver:driver.find_element_by_xpath("//div[@id='link-report']/span"))

2.识别验证码:

人工识别:适合比较复杂的验证码,正确率高,但是成本也高

机器识别:调用在线验证码识别软件接口识别验证码,正确率百分之八九十以上

3.异步加载:

fiddler / wireshark抓包分析ajax请求的界面,再通过规律仿造服务器构造一个请求访问服务器得到返回的真实数据包。

 通过PhantomJS+Selenium模拟浏览器行为,抓取经过js渲染后的页面。phantomjs是一个无头无界面浏览器,使用selenium可以驱动它模拟浏览器的一切操作,但缺点也很明显,爬取效率低;需要注意的是调用PhantomJs需要指定PhantomJs的可执行文件路径,通常是将该路径添加到系统的path路径,让程序执行时自动去path中寻找。使用Selenium后,请求不再由ScrapyDownloader执行,所以之前添加的请求头等信息都会失效,需要在Selenium中重新添加

4.爬虫陷阱:

一般是比较简单的死循环,可以对爬虫将要爬取的链接进行判断,不重复爬取相同的页面。除此之外,对于特定的元素看清之后小心爬取,还可使用scrapy的LinkExtractor设定unique参数为True即可或者直接设定爬虫的最大循环次数。

5.针对用户行为:

① cookie禁用:对于一些不需要登录的网站,可以在setting.py文件中设置COOKIES_ENABLED = False

② 自动限速:在setting.py文件中设置DOWNLOAD_DELAY = 1

③判断header:在请求时构造一个header,每次url请求更换一次user-agent。可以百度,也可看看之前的文章

④ 采用代理IP:可以做一个IP代理池,每次运行时随机挑选一个做访问IP。IP代理有收费有免费,看情况使用

免费的代理不一定能用,需要先做一下测试

# testproxy.py

#encoding=utf8

 

import urllib

import requests

import sys

 

if __name__ == "__main__":

    for url in sys.stdin:

        resp = requests.get(url)

        if resp.status_code ==requests.codes.ok:

            print url

然后写个脚本,用crontab设置其定期运行

# updateproxy.sh


set -x


scrapy crawl proxy > tmp


cat tmp > python updateproxy.sh > proxy

6.scrapyredis分布式爬虫:

可以利用多台机器的宽带加速爬取,还有利用多台机器的ip加速爬取

一般步骤如下:

    1.基本的http抓取工具,如scrapy
    2.
避免重复抓取网页,如Bloom Filter
    3.
维护一个所有集群机器能够有效分享的分布式队列
    4.
将分布式队列和Scrapy结合

    5.后续处理,网页析取(python-goose),存储(Mongodb)

7.使用scrapy反爬:

参考这篇文章Scrapy学习笔记(6)-反爬虫与反反爬虫策略

8.加速乐:

将浏览器返回的js代码放在一个字符串中,然后利用nodejs对这段代码进行反压缩,然后对局部的信息进行解密,得到关键信息放入下一次访问请求的头部中。

(未完待续)



猜你喜欢

转载自blog.csdn.net/weixin_41931602/article/details/80679623