那些年,我爬过的北科(六)——反反爬虫之js渲染

反爬虫和反反爬虫?

从本章开始,咱们将要进入反反爬虫篇的内容。javascript

感受若是是第一听到这个名字的读者确定是懵逼的状态。如今咱们先来介绍一下什么是爬虫、反爬虫、反反爬虫。html

爬虫其实就是咱们前面所学的代码,直接使用requests.get("http://xxx.com")就能拿到网站的源码。java

可是不少时候,咱们获取的都是有价值的数据,而网站开发者就不想让咱们拿到他们的数据,就有了不少反爬虫的策略,不让咱们那么容易的爬取到数据。反爬虫的策略其实其实主要就是三个方面:python

  • ①JS加密:HTML是用js代码生成的,不让咱们拿到html。
  • ②禁IP:咱们写爬虫的时候,通常用一个ip爬取,若是访问频率太高,网站开发者能够不让咱们这个ip访问网站。
  • ③验证码:获取数据以前要先输入验证码。

固然,除了这三个,还有些别的东西,好比说User-Agent识别这样的就属于比较基本的了,咱们这里就不展开了。web

而反反爬虫,其实就是针对上面的三个方面给出解决方案:chrome

  • ①针对JS加密:咱们可使用无头浏览器渲染js,再解析渲染后的html代码。
  • ②针对禁IP:咱们可使用代理ip等方式,用不一样的ip访问网站。
  • ③针对验证码:咱们能够对验证码进行识别,也可使用云打码这种人工验证码平台。

关于爬虫、反爬虫、反反爬虫的故事,知乎上的这个回答描绘的很是形象。windows

如何应对网站反爬虫策略?如何高效地爬大量数据? - 申玉宝的回答 - 知乎 www.zhihu.com/question/28…浏览器

本章内容

经过上面的介绍,读者应该对反反爬虫有了一个基本的认识了。本章将要对反爬虫的第一个方案:JS加密,进行反反爬虫。bash

尝试爬取 baidu.com

在介绍反反爬虫方法以前,咱们先拿百度测试一下。这里假设咱们想爬一爬百度搜索美女的搜索结果,也就是这个连接: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

咱们首先下载安装PhantomJS,下载连接为:phantomjs.org/download.ht…

下载后解压能够看到在bin目录下面有一个phantomjs的可执行文件。(若是是windows的话就是phantomjs.exe

安装selenium

接下来咱们须要安装selenium,直接使用pip命令便可。

pip install selenium
复制代码

selenium是一个用于Web应用程序测试的工具。它兼容各类浏览器,包括:PhantomJS、Chrome、FireFox等。

phantomjs默认的话要用JavaScript写代码。安装了selenium,咱们就可使用python进行操做了。

使用PhantomJS爬取百度

以上安装好了以后,咱们再尝试使用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的UA

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)
复制代码

Chrome的无头模式

PhantomJS访客检测

固然,有的时候,你会发现有些网站你用了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(事实证实,其余全部现代浏览器)有一些微妙的不一样:

  • 主机(host) 出现最后一行
  • 链接头(Connection)是大小写混合
  • 惟一的 接受编码 值是gzip

在服务器上检查这些HTTP头的变化,它应该能够识别PhantomJS浏览器。

Selenium+Chrome

若是读者真的碰到这种状况的话,就能够考虑用别的无头浏览器了,好比说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

这里还有一款工具叫Splash,它是一个JavaScript渲染服务,基于Twisted和QT5,提供了Http的API。

相比PhantomJS和Chrome的无头模式,Splash的性能会好不少,并且能够支持并发渲染,不过须要跑Docker。

两个比较火的Python爬虫框架:Scrapy以及PySpider就是使用Splash做为JS渲染引擎。

这里笔者只是简单进行介绍,若是读者对这个感兴趣,能够查阅自行百度查找教程。

Reference

相关文章
相关标签/搜索