基于selenium+phantomJS的动态网站全站爬取

 

更新 7月16日18点

由于需要在公司的内网进行神经网络建模试验(https://www.cnblogs.com/NosenLiu/articles/9463886.html),为了更方便的在内网环境下快速的查阅资料,构建深度学习模型,我决定使用爬虫来对深度学习框架keras的使用手册进行爬取。

现在不会自己写代码调用API的同志们可以直接访问咯

地址 datastack.cc/design
更新一张预览图:

图片 1

图片 2

keras中文文档的地址是 http://keras-cn.readthedocs.io/en/latest/ ,是基于英文原版使用手册https://keras.io/,由国内众多学者进行翻译所得,方便大家在学习和工作中快速的进行查阅。

更新 7月16日12点

 

现在我们可以愉快的使用了,flask API和后台服务已经部署在了服务器上(新加坡)!!!

地址 http://api.datastack.cc

恩,更新一下,目前已经可以在HTML页面进行数据展示了:

图片 3

web界面运行效果图

图片 4

配图纯属为了好看

在编写爬虫之前,我们需要对网站的源码进行分析,以确定抓取策略。

我在说什么

声明:
1.我不是一个标题党
2.我一般只提供干货

事实上,我实在干这样一件事,他大概分为如下几个步骤:

首先,网页分为左右两个部分,并且网站的大部分有效地址基本上都是集中在页面左侧的索引中,以<li class="toctree-l1 "></li>标签进行包围。

一、获取一些优秀的设计素材的数据

图片 5

二、存储和筛选这些数据

根据网站的这个特征,我们可以不使用传统的 URL管理器+网页下载器+解析器 的传统递归爬取模式,化繁为简,一次性的获取索引中所有的待爬取url。

三、编写一套API提供数据

其次,该页面的url不同于我们平时所浏览的.html或.jsp文件,通过浏览器的查看元素操作,可以知道该url所对应的是一个事件。应该是类似于一个action指令,服务器根据这个传入参数,来动态的返回页面。

四、编写一个网页调用API 展现数据

图片 6

五、编写iso和android客户端展现数据

应用场景:
当你在闲暇的时候,打开手机或者网页,查看一下最近有没有什么好的设计素材或者比较感兴趣的HTML页面。
恩,你可能看到很多,突然发现一个让你眼前一亮的,然后你手藏了他。
有一天你正在写一个HTML页面或者设计产品原型,突然,你的脑子里闪过一些东西,于是你打开了你的手机查看了一下收藏夹......

接下来,我们就来看看,如何实现:

为了正确的获取动态页面的内容,我们设计使用基于selenium+phantomJS的python语言爬虫来完成全站爬取任务。

数据获取

首先,数据主要是从各大免费的设计素材资源网站拿到的,这需要用到python爬虫。
其次,这类网站大量的使用了JS来加载内容,我选择selenium+phantomJS渲染JS。
最后,从爬取到的内容内获取想要的,我选择用pyquery来获取html节点(不要问为什么,因为我习惯用jquery!)

selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等[1]。

存储数据

phantomJS是一个基于 WebKit(WebKit是一个开源的浏览器引擎,Chrome,Safari就是用的这个浏览器引擎) 的服务器端 JavaScript API,python可以使用selenium执行javascript,selenium可以让浏览器自动加载页面,获取需要的数据。

数据结构

数据结构很简单,我不过就是想获取一张预览图,一个预览地址(或者下载地址),还有标题!
一条数据大概会是这样:

{
  "download": "http://www.doooor.com/thread-2762-1.html",
  "preview": "http://img.doooor.com/img/forum/201404/16/173909sczpof6sf26eckcf.jpg.thumb.jpg",
  "title": "STARS TOUCH 完全扁平化网页设计"
}

关于selenium与phantomJS的用法在网上有很多讲解,本文不再赘述,仅针对该全站爬取任务进行阐述。

数据持久化

我们对数据的存储要求不是很高,因为最近在学习redis,所以就用redis,利用快照持久化!

动态页面与静态页面的分析

爬虫的框架

一、我不懂什么框架,而且总体来说,要爬取得网站就那几个。自己编写一下规则就好了。
二、避免重复工作,用redis来存储待爬和爬过的url。
三、分布式? 哈哈,也许,可能大概是支持的吧。
四、效率?使用了selenium和phantomJS,貌似不用谈效率了,不过有些优化的小知识啦!
五、我是怎么实现的:
首先,我定义了一个爬虫服务 service.py,主要作用是连接redis,开始爬取工作,记录工作内容和工作结果。
然后,我写了一个爬虫工具 servicetools.py, 主要作用是模拟浏览器访问url,查找需要的元素和内容。

不同于单个网页的下载,全站爬取的难点在于如何在爬取之后保存网页之间的正确调用关系(即点击超链接能够正确的进行页面跳转)。在目标网站 keras中文文档中,服务器通过传递进来的action,使用servlet进行应答,返回对应的页面(笔者web开发的功底不牢固,只能描述大概流程,服务器运行具体细节难以描述清楚  =。=#  )。而将这些动态页面的信息以静态方式进行存储后,只有把它们放在正确的相对路径下,才能够在流量器中正常使用,因此在下载页面的时候,需要完成以下两个工作: 

service.py 管理者-劳动者模式 (管理者Master发布任务,劳动者Work进行具体工作.)

管理者维护一个Redis 的 List 按照先进先出的模式, 每次发布一个url出去
劳动者接收到管理者的url,开始执行网页爬取工作,工作完成后 管理者pop掉这个url
劳动者如果获取的数据是url,则封装成list 提交给管理者, 管理者挨个push url.

工作1.获取页面所在的相对路径,并且给页面命名。通过对页面的源代码进行浏览,我们可以发现,每个页面的url就是它以/latest/为根目录的相对路径。

servicetools.py(具体的网页爬取工作)

使用phantomJS和selenium结合,使用pyquery进行节点和内容的获取,不同的网站需要不同的规则。

图片 7

目前实现的功能 和存在问题:

总体来说,运行良好,效率足够(根本不是实时系统嘛)!
额,比较费内存,可以在晚上睡觉之前执行,偶尔会出现假死,主要是phantomJS的优化没做!
如果程序异常推出,再次启动依旧能够继续工作,且不重复之前工作!

图1 网站主页面上的序贯模型url (相对路径)

API的实现

上面的爬虫运行半个小时之后,大概就会有500多条有效数据,这些数据全部被存在redis里面(hset)。
可以参见我之前的文章快速入门 基于Flask实现Restful风格API,比较详细的介绍了如何使用flask来实现一个restful的API。

这里的flask程序需要从redis拿数据,我自己定义了一个数据源(连接redis分发数据)。

图片 8

目前已经完成的工作

目前已经基本实现API获取数据,爬虫还正在努力的运行,稳定以后,将会设置系统任务,在每天半夜3点开始,五点结束。

看一张效果图吧:

图片 9

API 可以返回简洁有用的数据

图片 10

随便点击一个,预览图片也很不错呢

图2 序贯模型页面的真实url (绝对路径)

下一步的工作

根据这个特征,我们可以设计相对的函数,来获取所有待爬取页面的真实url。此外,为了能够对页面进行正确的保存,需要给文件进行命名,这里将所有页面名称定位info.html。例如,序贯模型的页面在本地就存储在  ./latest/getting_started/sequential_model/info.html 文件中。

继续发现和修补爬虫的bug

工作2.将页面存储到本地时,将其中的超链接地址改为目标静态页面的相对路径。例如,对于主页 http://keras-cn.readthedocs.io/en/latest/,它的序贯模型索引的url如下:

增加用户系统和认证机制,这样大家就可以收藏了

图片 11

租一个云主机(求有需求的伙伴打赏)

而对于我们所爬取下来的静态主页 ./latest/info.html 来说,它的序贯模型索引的url如下:

编写客户端

图片 12

公开源代码

github地址

最后,如果你对这个项目感兴趣,请发我简信,或者直接在下面评论!
还有,服务器好贵,真希望有人能打赏,让我早点把API公开。

我们需要精确的指向该页面在本地目录中所保存的地址。

注意:我们只修改以<li class="toctree-l1 "></li>标签进行环绕的超链接<a>,其他类似href=”#keras-cn”的链接只是JavaScript的一个位置移动操作,并不会对新的页面进行加载(这一点我花了好久时间才看懂,之前一直以为需要对 #keras-cn新建一个路径,再对其页面进行静态保存……)。

 

做完了上述工作,就可以对网页进行爬取了,但此时,爬取出的网页大概是这个样子:

图片 13

这是因为我们此时并没有下载网页的样式文件.css与.js文件,导致一片白板。继续观察网页源码,发现该网站下所有的页面,其.css文件与.js文件路径都在页面的<head>标签内进行规定,且均指向/lastest/css/文件夹与/latest/js/文件夹。因此我们只要在存储网站主页的时候,对.css与.js文档存储一次即可。

 

整个网站爬取的流程如下:

①使用selenium+phantomJS打开根页面,获取页面左侧索引的全部url,将其存储在url_list中。

②调用页面保存函数,对根页面进行保存。

③下载<head>标签内的 .css 与 .js 文件。

④循环遍历url_list中的页面地址,使用selenimu的webdriver进行打开,调用页面保存函数对页面内容进行保存。

 

注意事项:

本文由金沙官网线上发布于编程,转载请注明出处:基于selenium+phantomJS的动态网站全站爬取

您可能还会对下面的文章感兴趣: