从本章开始,咱们将要进入反反爬虫篇的内容。javascript
感受若是是第一听到这个名字的读者确定是懵逼的状态。如今咱们先来介绍一下什么是爬虫、反爬虫、反反爬虫。html
爬虫其实就是咱们前面所学的代码,直接使用requests.get("http://xxx.com")
就能拿到网站的源码。java
可是不少时候,咱们获取的都是有价值的数据,而网站开发者就不想让咱们拿到他们的数据,就有了不少反爬虫的策略,不让咱们那么容易的爬取到数据。反爬虫的策略其实其实主要就是三个方面:python
固然,除了这三个,还有些别的东西,好比说User-Agent
识别这样的就属于比较基本的了,咱们这里就不展开了。web
而反反爬虫,其实就是针对上面的三个方面给出解决方案:chrome
关于爬虫、反爬虫、反反爬虫的故事,知乎上的这个回答描绘的很是形象。windows
如何应对网站反爬虫策略?如何高效地爬大量数据? - 申玉宝的回答 - 知乎 www.zhihu.com/question/28…浏览器
经过上面的介绍,读者应该对反反爬虫有了一个基本的认识了。本章将要对反爬虫的第一个方案:JS加密,进行反反爬虫。bash
在介绍反反爬虫方法以前,咱们先拿百度测试一下。这里假设咱们想爬一爬百度搜索美女的搜索结果,也就是这个连接:www.baidu.com/s?wd=%E7%BE…(注:这里URL进行了url编码)服务器
咱们先用以前超级好用的requests库试一下。
稍微懂点儿html的就知道,这里没看到所谓的美女图,反而还让咱们跳转回www.baidu.com/。
上面咱们用requests.get
什么都没看到,但咱们用浏览器访问www.baidu.com/s?wd=%E7%BE…的时候,的的确确看到了搜索结果的。
用requests不行,明显是百度的后台识别出来咱们是低劣的爬虫程序,鄙视咱们,什么都不给咱们。
既然用浏览器能够,咱们是否是能够经过Api调用咱们的浏览器而后爬取搜索结果呢?
确实是能够,并且还有种浏览器叫:Headless Browser,也就是无头浏览器,没有界面的浏览器。若是有界面的话,咱们可能还要用显卡去渲染图形页面,很是耗费字段,这简直是专门为爬虫开发者设计的。
咱们这里主要介绍的一款无头浏览器名叫:PhantomJS。虽然它如今已经不更新了,但不妨碍咱们继续使用它。
咱们首先下载安装PhantomJS,下载连接为:phantomjs.org/download.ht…。
下载后解压能够看到在bin目录下面有一个phantomjs
的可执行文件。(若是是windows的话就是phantomjs.exe
)
接下来咱们须要安装selenium,直接使用pip
命令便可。
pip install selenium
复制代码
selenium是一个用于Web应用程序测试的工具。它兼容各类浏览器,包括:PhantomJS、Chrome、FireFox等。
phantomjs默认的话要用JavaScript写代码。安装了selenium,咱们就可使用python进行操做了。
以上安装好了以后,咱们再尝试使用phantomjs爬取一下百度。代码以下:
from selenium import webdriver
exe_path = "/usr/bin/phantomjs"
driver = webdriver.PhantomJS(executable_path=exe_path)
driver.get("https://www.baidu.com/s?wd=%E7%BE%8E%E5%A5%B3")
driver.save_screenshot("screenshot.png") # 截个图
print(driver.page_source) # 打印源码
driver.quit()
复制代码
这里须要根据本身phantomjs的下载路径配置exe_path
。而后首先建立一个driver对象,调用get
访问页面,就会自动渲染内部的js,显示出结果。
注意:在不使用了以后,要调用driver.quit()退出,要否则后台会有不少phantomjs进程。
这里咱们调用selenium的截图方法看下结果。
能够看到咱们连网页的截图都弄出来了。selenium除了截图以外,还支持不少使用js才能完成的操做,好比说:模拟点击、滚动等等。若是读者感兴趣能够本身去研究。
PhantomJS默认的User-Agent使用的是:PhantomJS。若是咱们带着这个会很容易被网站检测出来,咱们能够在建立driver的时候加入配置修改PhantomJS的UA,让它假装成Chrome浏览器。代码实现以下:
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap['phantomjs.page.settings.userAgent'] = ('Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36')
exe_path = "/usr/bin/phantomjs"
driver = webdriver.PhantomJS(executable_path=exe_path, desired_capabilities=dcap)
复制代码
固然,有的时候,你会发现有些网站你用了PhantomJS仍是爬不了,笔者就遇到过这样的场景。这是由于PhantomJS创建在Qt框架。而Qt实现HTTP栈的方式使它和其余现代浏览器不同。
在Chrome中,发出Http请求的head以下:
GET / HTTP/1.1
Host: localhost:1337
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8,ru;q=0.6 复制代码
然而在PhantomJS,相同的HTTP请求是这样的:
GET / HTTP/1.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.9.8 Safari/534.34
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Connection: Keep-Alive Accept-Encoding: gzip Accept-Language: en-US,* Host: localhost:1337 复制代码
你会注意到PhantomJS头是不一样于Chrome(事实证实,其余全部现代浏览器)有一些微妙的不一样:
在服务器上检查这些HTTP头的变化,它应该能够识别PhantomJS浏览器。
若是读者真的碰到这种状况的话,就能够考虑用别的无头浏览器了,好比说Chrome的无头模式。
Chrome的无头模式和selenium也能够结合在一块儿使用。这里首先须要下载chromedriver
,而后经过selenium的API使用便可。如下为简单的示例,若是读者对这个感兴趣,能够查阅自行百度查找教程。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
driver = webdriver.Chrome(chrome_options=chrome_options, executable_path='/usr/bin/chromedriver')
复制代码
这里还有一款工具叫Splash,它是一个JavaScript渲染服务,基于Twisted和QT5,提供了Http的API。
相比PhantomJS和Chrome的无头模式,Splash的性能会好不少,并且能够支持并发渲染,不过须要跑Docker。
两个比较火的Python爬虫框架:Scrapy以及PySpider就是使用Splash做为JS渲染引擎。
这里笔者只是简单进行介绍,若是读者对这个感兴趣,能够查阅自行百度查找教程。