抓取前端渲染的页面

随着AJAX技术不断的普及,以及现在AngularJS这种Single-page application框架的出现,现在js渲染出的页面越来越多。对于爬虫来说,这种页面是比较讨厌的:仅仅提取HTML内容,往往无法拿到有效的信息。那么如何处理这种页面呢?总的来说有两种做法:

在抓取阶段,在爬虫中内置一个浏览器内核,执行js渲染页面后,再抓取。这方面对应的工具有Selenium、HtmlUnit或者PhantomJs。但是这些工具都存在一定的效率问题,同时也不是那么稳定。好处是编写规则同静态页面一样。

因为js渲染页面的数据也是从后端拿到,而且基本上都是AJAX获取,所以分析AJAX请求,找到对应数据的请求,也是比较可行的做法。而且相对于页面样式,这种接口变化可能性更小。缺点就是找到这个请求,并进行模拟,是一个相对困难的过程,也需要相对多的分析经验。

对比两种方式,我的观点是,对于一次性或者小规模的需求,用第一种方式省时省力。但是对于长期性的、大规模的需求,还是第二种会更靠谱一些。对于一些站点,甚至还有一些js混淆的技术,这个时候,第一种的方式基本是万能的,而第二种就会很复杂了。

对于第一种方法,webmagic-selenium就是这样的一个尝试,它定义了一个Downloader,在下载页面时,就是用浏览器内核进行渲染。selenium的配置比较复杂,而且跟平台和版本有关,没有太稳定的方案。感兴趣的可以看我这篇博客:使用Selenium来抓取动态加载的页面

这里我主要介绍第二种方法,希望到最后你会发现:原来解析一个前端渲染的页面,也没有那么复杂。这里我们以AngularJS中文社区http://angularjs.cn/为例。

如何判断前端渲染

判断页面是否为js渲染的方式比较简单,在浏览器中直接查看源码(Windows下Ctrl+U,Mac下command+alt+u),如果找不到有效的信息,则基本可以肯定为js渲染。

这个例子中,在页面中的标题“有孚计算机网络-前端攻城师”在源码中无法找到,则可以断定是js渲染,并且这个数据是AJAX得到。

分析请求

下面我们进入最难的一部分:找到这个数据请求。这一步能帮助我们的工具,主要是浏览器中查看网络请求的开发者工具。

以Chome为例,我们打开“开发者工具”(Windows下是F12,Mac下是command+alt+i),然后重新刷新页面(也有可能是下拉页面,总之是所有你认为可能触发新数据的操作),然后记得保留现场,把请求一个个拿来分析吧!

这一步需要一点耐心,但是也并不是无章可循。首先能帮助我们的是上方的分类筛选(All、Document等选项)。如果是正常的AJAX,在XHR标签下会显示,而JSONP请求会在Scripts标签下,这是两个比较常见的数据类型。

然后你可以根据数据大小来判断一下,一般结果体积较大的更有可能是返回数据的接口。剩下的,基本靠经验了,例如这里这个"latest?p=1&s=20"一看就很可疑…

对于可疑的地址,这时候可以看一下响应体是什么内容了。这里在开发者工具看不清楚,我们把URLhttp://angularjs.cn/api/article/latest?p=1&s=20复制到地址栏,重新请求一次(如果用Chrome推荐装个jsonviewer,查看AJAX结果很方便)。查看结果,看来我们找到了想要的。

同样的办法,我们进入到帖子详情页,找到了具体内容的请求:http://angularjs.cn/api/article/A0y2。

编写程序

回想一下之前列表+目标页的例子,会发现我们这次的需求,跟之前是类似的,只不过换成了AJAX方式-AJAX方式的列表,AJAX方式的数据,而返回数据变成了JSON。那么,我们仍然可以用上次的方式,分为两种页面来进行编写:

数据列表

在这个列表页,我们需要找到有效的信息,来帮助我们构建目标AJAX的URL。这里我们看到,这个_id应该就是我们想要的帖子的id,而帖子的详情请求,就是由一些固定URL加上这个id组成。所以在这一步,我们自己手动构造URL,并加入到待抓取队列中。这里我们使用JsonPath这种选择语言来选择数据(webmagic-extension包中提供了JsonPathSelector来支持它)。 if (page.getUrl().regex(LIST_URL).match()) {

//这里我们使用JSONPATH这种选择语言来选择数据

List ids = new JsonPathSelector("$.data[*]._id").selectList(page.getRawText());

if (CollectionUtils.isNotEmpty(ids)) {

for (String id : ids) {

page.addTargetRequest("http://angularjs.cn/api/article/"+id);

}

}

}

目标数据

有了URL,实际上解析目标数据就非常简单了,因为JSON数据是完全结构化的,所以省去了我们分析页面,编写XPath的过程。这里我们依然使用JsonPath来获取标题和内容。 page.putField("title",new JsonPathSelector("$.data.title").select(page.getRawText()));

page.putField("content",new JsonPathSelector("$.data.content").select(page.getRawText()));

总结

在这个例子中,我们分析了一个比较经典的动态页面的抓取过程。实际上,动态页面抓取,最大的区别在于:它提高了链接发现的难度。我们对比一下两种开发模式:

后端渲染的页面

下载辅助页面=>发现链接=>下载并分析目标HTML

前端渲染的页面

发现辅助数据=>构造链接=>下载并分析目标AJAX

对于不同的站点,这个辅助数据可能是在页面HTML中已经预先输出,也可能是通过AJAX去请求,甚至可能是多次数据请求的过程,但是这个模式基本是固定的。

但是这些数据请求的分析比起页面分析来说,仍然是要复杂得多,所以这其实是动态页面抓取的难点。

本节这个例子希望做到的是,在分析出请求后,为这类爬虫的编写提供一个可遵循的模式,即发现辅助数据=>构造链接=>下载并分析目标AJAX这个模式。

PS:

WebMagic 0.5.0之后会将Json的支持增加到链式API中,以后你可以使用:

page.getJson().jsonPath("$.name").get();

这样的方式来解析AJAX请求了。

同时也支持

page.getJson().removePadding("callback").jsonPath("$.name").get();

这样的方式来解析JSONP请求。

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

小编个人微信号 jb51ccc

喜欢与人分享编程技术与工作经验,欢迎加入编程之家官方交流群!

webmagic保存html页面,WebMagic抓取前端Ajax渲染的页面相关推荐

  1. webmagic ajax,【WebMagic】抓取前端渲染的页面

    随着AJAX技术不断的普及,以及现在AngularJS这种Single-page application框架的出现,现在js渲染出的页面越来越多.对于爬虫来说,这种页面是比较讨厌的:仅仅提取HTML内 ...

  2. java爬取验证码图片_JAVA HttpClient实现页面信息抓取(获取图片验证码并传入cookie实现信息获取)...

    JAVA HttpClient实现页面信息抓取(获取图片验证码并传入cookie实现信息获取) 发布时间:2018-05-18 16:41, 浏览次数:632 , 标签: JAVA HttpClien ...

  3. 免费网站数据抓取插件,可视化页面数据抓取插件

    网站页面数据抓取插件,允许我们将数据从网站直接抓取到我们的本地或者页面.网站网页数据抓取(也称为ScreenScraping.WebDataExtraction.WebHarvesting等)是一种用 ...

  4. 网易新闻页面信息抓取(htmlagilitypack搭配scrapysharp)

    转自原文 网易新闻页面信息抓取(htmlagilitypack搭配scrapysharp) 最近在弄网页爬虫这方面的,上网看到关于htmlagilitypack搭配scrapysharp的文章,于是决 ...

  5. 网易新闻页面信息抓取 -- htmlagilitypack搭配scrapysharp

    网易新闻页面信息抓取 -- htmlagilitypack搭配scrapysharp 最近在弄网页爬虫这方面的,上网看到关于htmlagilitypack搭配scrapysharp的文章,于是决定试一 ...

  6. JAVA综合面试题 页面的抓取 解析 保存数据库和生成HTML的页面展示

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 次例子可 ...

  7. database2sharp mysql_C# NetCore使用AngleSharp爬取周公解梦数据 MySql数据库的自动创建和页面数据抓取...

    这一章详细讲解编码过程 那么接下来就是码代码了,GO 新建NetCore WebApi项目 空的就可以 NuGet安装 Install-Package AngleSharp 或者界面安装 using. ...

  8. htmlunit+quartz定时抓取博文并生成jsp页面

    前言 分析网页 页码分析 文章链接分析 文章内容分析 io流生成jsp页面 squarz设置定时抓取 前言 看视频看的累了 写写博文~ 很久以前就想有个自己的博客.csdn很好,可是我不是专家啊,还是 ...

  9. php登录页面后抓取页面内容,PHP模拟登陆抓取页面内容

    平时开发中经常会遇到抓取某个页面内容, 但是有时候某些页面需要登陆才能访问, 最常见的就是论坛, 这时候我们需要来使用curl模拟登陆. 大致思路:需要先请求提取 cookies 并保存,然后利用保存 ...

  10. python数据库抓取并保存_python:微信消息抓取、转发和数据库存储及源码

    前言 python的强大在于丰富的类库,经常会看到几行代码就可以实现非常强大的功能.它可以做爬虫.AI.自动化测试.小工具(抢票.抓包.微信消息抓取)等等. 本次我们来讲讲怎么来抓取微信消息?抓取微信 ...

最新文章

  1. 号召一下,看有多少人能响应!
  2. [YTU]_2475( C++习题 多重继承)
  3. 8、web入门回顾/ Http
  4. 【Python面试】 说说Python面向对象三大特性?
  5. 图书管理系统活动图和时序图
  6. 全国数据中心分布图上线 轻轻松松找机房
  7. hibernate 懒加载_Hibernate懒/急加载示例
  8. python 滚动字幕_Python pygame绘制文字制作滚动文字过程解析
  9. 区别js中的3/2(结果1.5))与 java 中的 2/3(结果:0)
  10. 计算机专业黑板报迎新,迎新学期黑板报图
  11. android 预约挂号代码_还在医院苦苦排队挂号?Python定时自动挂号和快捷查询化验报告!...
  12. 金橙子打标卡二次开发应用
  13. 计算机sci期刊 周期短,周期短的SCI期刊有哪些
  14. 使用百度地图API实现地图生成、标记以及标注
  15. (MIUI)小米手机录音丢失找回
  16. The first GAN——Generative Adversarial Nets
  17. 第三篇 香橙派的外设开发基础(中)— 串口篇
  18. table固定首行首列
  19. 课程学习:让神经机器翻译模型像人类一样学习
  20. 一些开源书籍下载地址汇总

热门文章

  1. C#山寨版本【天翼拨号客户端】---内含详细抓包,模拟数据---万事俱备,只欠东风。
  2. 干掉卫星、无人机?只用气球就能获取10厘米分辨率遥感影像
  3. oracle create table parallel,使用oracle parallel
  4. Python正则表达式(网址正则/超链接正则)
  5. Python四大神兽(迭代器生成器闭包装饰器)
  6. seo整站优化到底该从哪些方面进行着手(干货分享)
  7. 中国石油大学奥鹏《大学英语三》第一次在线作业
  8. 【Html】 Html写静态淘宝页面
  9. 2021-07-12淘宝首页首次尝试
  10. 怎样制作中阿拉伯文网页