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

综合技术 2018-12-08 阅读原文

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

感觉如果是第一听到这个名字的读者肯定是懵逼的状态。现在我们先来介绍一下什么是爬虫、反爬虫、反反爬虫。

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

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

  • ①JS加密: Html是用js代码生成的,不让我们拿到html。
  • ②禁IP: 我们写爬虫的时候,一般用一个ip爬取,如果访问频率过高,网站开发者可以不让我们这个ip访问网站。
  • ③验证码: 获取数据之前要先输入验证码。

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

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

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

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

如何应对网站反爬虫策略?如何高效地爬大量数据? - 申玉宝的回答 - 知乎

https://www.zhihu.com/question/28168585/answer/74840535

本章内容

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

尝试爬取baidu.com

在介绍反反爬虫方法之前,我们先拿百度测试一下。这里假设我们想爬一爬百度搜索美女的搜索结果,也就是这个链接: https://www.baidu.com/s?wd=%E7%BE%8E%E5%A5%B3 (注:这里URL进行了url编码)

我们先用之前超级好用的requests库试一下。

稍微懂点儿html的就知道,这里没看到所谓的美女图,反而还让我们跳转回 http://www.baidu.com/

什么是无头浏览器?

但我们用浏览器访问 https://www.baidu.com/s?wd=%E7%BE%8E%E5%A5%B3 的时候,的的确确看到了搜索结果的。

用requests不行,明显是百度的后台识别出来我们是低劣的爬虫程序,鄙视我们,什么都不给我们。

既然用浏览器可以,我们是不是可以通过Api调用我们的浏览器然后爬取搜索结果呢?

确实是可以,而且还有种浏览器叫:Headless Browser,也就是无头浏览器,没有界面的浏览器。如果有界面的话,我们可能还要用显卡去渲染图形页面,非常耗费字段,这简直是专门为爬虫开发者设计的。

Phantomjs

我们这里主要介绍的一款无头浏览器名叫:PhantomJS。虽然它现在已经不更新了,但不妨碍我们继续使用它。

下载PhantomJS

我们首先下载安装PhantomJS,下载链接为: http://phantomjs.org/download.html

下载后解压可以看到在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 = "/Users/kalen/Programfiles/phantomjs-2.1.1-macosx/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建立在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浏览器。

如果读者真的碰到这种情况的话,就可以考虑用别的无头浏览器了,比如说 Chrome的无头模式 。这里笔者只是简单进行介绍,如果读者对这个感兴趣,可以查阅自行百度查找教程。

Chrome的无头模式和selenium也可以结合在一起使用。

另一个工具:Splash

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

相比PhantomJS和Chrome的无头模式性能会好很多,而且可以支持并发渲染,不过需要Docker进行安装。

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

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

责编内容by:叁公子的博客 【阅读原文】。感谢您的支持!

您可能感兴趣的

用 PhantomJS 让邮件报表图文并茂(一) 在部门日常业务中,每天都会产生各种各样的数据。为了让抽象的数据,更加调理方便人阅读,就需要将数据整理成表格、图表等形式,以更生动的面貌展示在人们眼前。 通常 Web 端可以采用 ECharts 等方案来实现丰富的图表效果,...
Arquillian Drone Extension 2.5.0 发布,组件升级... Arquillian Drone Extension 2.5.0 发布了,Arquillian 可让你在远程或者嵌入式的容器里测试业务逻辑,同时可作为一个压缩包发布到容器中,并通过客户端来进行交互测试。 此次更新内容: 组件升级:...
Running PhantomJS & node.js together on Ubuntu So l have recently been using phantomjs-node using the 1.7 fix on my Mac with no problems. ...
踏入 headless Chrome 新世界,使用 Puppeteer 抓取網頁截圖囉... 之前使用 PhantomJS 的時候,遇到好多莫名其妙的 Bug,實在很雷啊,所以我就寫了篇文章,記錄當時的使用心得、分享網頁截圖的方法。 雖然當時 Google 已經推出了 headless Chrome ,也提供網頁截圖的範例程...
xssValidator 本文记录一下xss Validator的使用方法 0x00 前言 xss Validator是一个Burp商店的一个高分插件,该插件依赖于 phantomjs 项目以及Burp的Intruder模块。 0x01 安装...