反爬虫 的技术大概分为四个种类:
注: 文末有福利!
一通过 User-Agent 来控制访问:
无论是浏览器还是爬虫程序, 在向服务器发起网络请求的时候, 都会发过去一个头文件: headers, 比如知乎的 requests headers:
Referer:Ehco - 知乎
- Upgrade-Insecure-Requests:1
- User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
- Query String Parameters
- view source
- view URL encoded
这里面的大多的数的字段都是浏览
这里面的大多数的字段都是浏览器向服务器表明身份用的
对于爬虫程序来说, 最需要注意的字段就是: User-Agent
很多网站都会建立 user-agent 白名单, 只有属于正常范围的 user-agent 才能够正常访问
比如知乎:
- import requests
- import bs4
- import random
- def get_html(url):
- try:
- r = requests.get(url, timeout=30)
- r.raise_for_status
- r.encoding = r.apparent_encoding
- return r.text
- except:
- return "Someting Wrong!"
- print(get_html('https://zhuanlan.zhihu.com'))
- # OUT:
- '''
- <html><body><h1>500 Server Error</h1>
- An internal server error occured.
- </body></html>
- '''
可以看到, 这里的请求被拒绝了, 并且返回了一个 500 的错误码:
这里就是因为 requests 库本身的 headers 是这样的:
- {'Date': 'Tue, 09 May 2017 12:13:00 GMT', 'Content-Type': 'text/html', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Set-Cookie': 'aliyungf_tc=AQAAAPDDXQnf6AEAHaBXcP1tHo5z1uta; Path=/; HttpOnly, acw_tc=AQAAAAM
- 89GeptQMAHaBXcJiyTK3l8c5g; Path=/; HttpOnly','Cache-Control':'no-cache'}
这里面并没有 user-agent 字段, 自然不被知乎的服务器所接受了
解决方法:
可以自己设置一下 user-agent, 或者更好的是, 可以从一系列的 user-agent 里随机挑出一个符合标准的使用, 代码如下:
- def get_agent():
- '''
模拟 header 的 user-agent 字段,
返回一个随机的 user-agent 字典类型的键值对
- '''agents = ['Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;','Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv,2.0.1) Gecko/20100101 Firefox/4.0.1','Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11','Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11','Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)']
- fakeheader = {}
- fakeheader['User-agent'] = agents[random.randint(0, len(agents))]
- return fakeheader
- # 注意看新的请求函数:
- def get_html(url):
- try:
- r = requests.get(url, timeout=30,headers=get_agent())
- r.raise_for_status
- r.encoding = r.apparent_encoding
- return r.status_code
- except:
- return "Someting Wrong!"
- '''
- OUT:
- 200
- '''
二通过 IP 限制来反爬虫:
如果一个固定的 ip 在短暂的时间内, 快速大量的访问一个网站, 那自然会引起注意, 管理员可以通过一些手段把这个 ip 给封了, 爬虫程序自然也就做不了什么了
解决方法:
比较成熟的方式是: IP 代理池
简单的说, 就是通过 ip 代理, 从不同的 ip 进行访问, 这样就不会被封掉 ip 了
可是 ip 代理的获取本身就是一个很麻烦的事情, 网上有免费和付费的, 但是质量都层次不齐如果是企业里需要的话, 可以通过自己购买集群云服务来自建代理池
这里实现了一个简单的代理转换, 代码如下:
- def get_proxy():
- '''
简答模拟代理池
返回一个字典类型的键值对,
- '''proxy = ["http://116.211.143.11:80","http://183.1.86.235:8118","http://183.32.88.244:808","http://121.40.42.35:9999","http://222.94.148.210:808"]
- fakepxs = {}
- fakepxs['http'] = proxy[random.randint(0, len(proxy))]
- return fakepxs
三通过 JS 脚本来防止爬虫:
这个可以说是终极的办法了, 因为, 爬虫终归只是一段程序, 它并不能像人一样去应对各种变化, 如验证码, 滑动解锁之类的
举个例子: 如果想爬取某个网站, 但是在进入网站之前, 它会有一个验证页面来验证你是不是机器
它是怎么验证的呢:
他会通过 js 代码生成一大段随机的数字, 然后要求浏览器通过 js 的运算得出这一串数字的和, 再返回给服务器.
可想而知, 这么简单和最基础的一个验证步骤, 会是写的代码完成不了的
解决方法:
这里就要请出一个大杀器: PhantomJS
PhantomJS 是一个 Python 包, 他可以在没有图形界面的情况下, 完全模拟一个浏览器, js 脚本验证什么的再也不是问题了
四通过 robots.txt 来限制爬虫:
世界上做爬虫最大最好的就是 Google 了, 搜索引擎本身就是一个超级大的爬虫, Google 开发出来爬虫 24h 不间断的在网上爬取着新的信息, 并返回给数据库, 但是这些搜索引擎的爬虫都遵守着一个协议: robots.txt
robots.txt(统一小写) 是一种存放于网站根目录下的 ASCII 编码的文本文件, 它通常告诉网络搜索引擎的漫游器 (又称网络蜘蛛), 此网站中的哪些内容是不应被搜索引擎的漫游器获取的, 哪些是可以被漫游器获取的因为一些系统中的 URL 是大小写敏感的, 所以 robots.txt 的文件名应统一为小写 robots.txt 应放置于网站的根目录下如果想单独定义搜索引擎的漫游器访问子目录时的行为, 那么可以将自定的设置合并到根目录下的 robots.txt, 或者使用 robots 元数据 (Metadata, 又称元数据)
robots.txt 协议并不是一个规范, 而只是约定俗成的, 所以并不能保证网站的隐私注意 robots.txt 是用字符串比较来确定是否获取 URL, 所以目录末尾有与没有斜杠 / 表示的是不同的 URLrobots.txt 允许使用类似 "Disallow: *.gif" 这样的通配符 [1][2]
wiki 上说的已经很清楚了, 这实际上只是一个君子协议, 遵守与否, 都在于爬虫的编写者
来看一下京东的'robots.txt':
- User - agent: *Disallow: /?*
- Disallow: /pop
- /*.html
- Disallow: /pinpai/*.html?*
- User-agent: EtaoSpider
- Disallow: /
- User-agent: HuihuiSpider
- Disallow: /
- User-agent: GwdangSpider
- Disallow: /
- User-agent: WochachaSpider
- Disallow: /*/
可以看到, 京东的 robots 协议里明确的指出四个 user-agent 是禁止访问的,
事实上, 这四个 user-agent 也是四个臭名昭著的恶性爬虫
所以最好遵守这个规则!, 互联网上的很多资源都是免费的, 但是如果因为个人的利益, 而损害到别人, 这是很不对的!
当然有种情况是例外的, 比如说我们爬虫的获取网页的速度, 和人类浏览网页是差不多的, 这并不会给服务器造成太大的性能损失, 在这种情况下, 我们是可以不用恪守 robots 协议的
来源: https://www.cnblogs.com/Lovebugs/p/8687329.html