美文网首页
R爬虫必备基础—动态异步加载

R爬虫必备基础—动态异步加载

作者: Clariom | 来源:发表于2020-08-14 12:22 被阅读0次

    上一期简单说明了rvest为什么不用于动态网页的抓取,其中简单提及异步加载的动态网页,它属于动态网页的一种加载形式。一般来说,网页加载模式主要有两种:同步加载和异步加载。

    同步加载

    同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止了后续的解析,因此停止了后续的文件加载(如图像)、渲染、代码执行。js 之所以要同步执行,是因为 js 中可能有输出 document 内容、修改dom、重定向等行为,所以默认同步执行才是安全的。 以前的一般建议是把<script>放在页面末尾</body>之前,这样尽可能减少这种阻塞行为,而先让页面展示出来。 简单说:加载的网络 timeline 是瀑布模型,而异步加载的 timeline 是并发模型。

    <script src="http://yourdomain.com/script.js"></script>
    

    异步加载

    异步加载又叫非阻塞,浏览器在下载执行 js 同时,还会继续进行后续页面的处理。这种方法是在页面中<script>标签内,用 js 创建一个 script 元素并插入到 document 中。这样就做到了非阻塞的下载 js 代码。async属性是HTML5中新增的异步支持,加上好(不加也不影响)。此方法被称为** Script DOM Element 法**,不要求 js 同源。将js代码包裹在匿名函数中并立即执行的方式是为了保护变量名泄露到外部可见,这是很常见的方式,尤其是在 js 库中被普遍使用。

    (function() { 
    var s = document.createElement('script'); 
    s.type = 'text/javascript'; 
    s.async = true; 
    s.src = 'http://yourdomain.com/script.js'; 
    var x = document.getElementsByTagName('script')[0]; 
    x.parentNode.insertBefore(s, x); 
    })();(function() { 
    

    今天呢,主要介绍有关动态异步加载的一些基本知识。异步加载,即AJAX,全称为异步JavaScript和XML(Asynchronous JavaScript and XML),它是一组技术,不同的浏览器有自己的AJAX实现组件,有了AJAX技术之后,就不需要对整个网页进行刷新了,局部更新既不占用宽带又可以提高加载速。比如,当你访问一个网页时,鼠标向下滑,数据不断的更新而http网址没有变化,那么这个网页就利用了异步加载技术。

    从HTML到DHTML

    HTML、CSS和JavaScript是前端技术的三驾马车,其中,JavaScript主要起到一些效果渲染的作用。在当前浏览器显示中对HTML信息进行修改称为DOM操作(文档对象模型),这些操作构成了产生动态浏览器行为的基本过程。JavaScript可供支持的修改操作有很多,HTML元素和属性可以添加移动删除,CSS样式也可以修改。JavaScript对HTML的改进方法主要有以下三种:

    • 以HTML中的<script>标签为固定位置进行代码内嵌;
    • 对<script>元素中的src属性路径引用一个存放外部的JavaScript代码文件;
    • JavaScript代码直接出现在特定HTML元素属性里,也叫事件处理器。

    网页动态加载中数据的获取机制

    如果说JavaScript是将HTML变成DHTML的话,那么XHR就是将传统的HTTP协议同步请求通信变成异步发起HTTP请求。异步通信支持在浏览器与Web服务器之间进行持续的信息交换的方法就是所谓的XHR(XMLHttpRequest)。在XHR的实际使用过程中,一般可以加载HTML/XML和JSON等数据类型。

    XHR在DHTML中的数据获取机制如下:

    (1)用户开始通过任何浏览器可识别的事件发起一个AJAX请求,比如说点击一个按钮,下拉一个菜单之类的,然后JavaScript会将这个请求作为一个实例化的XHR对象;
    (2)这个XHR对象会向服务器发起一个对特定文件的请求,请求一般从后台发出,所以不影响用户与网页的交互;
    (3)请求在服务器端会被接受和处理,相应的数据就会通过XHR对象发回给浏览器客户端;
    (4)数据到了客户端会被接受,该事件就会被触发然后被某个事件处理器所捕获。

    浏览器开发工具辅助动态爬取

    对于通过AJAX改进后的DHTML而言,在用R进行抓取时只是去查看源代码肯定是不够的,R语言没有提供必要的网页结构分析功能,这时还是要借助于浏览器本身的Web开发者工具来进行分析。目前任意一款浏览器基本上都具备这个功能,只要在浏览的网页上使用鼠标右键点击审查元素即可,界面最上面一栏显示包括元素、控制台、来源、网络、时间线、运行概况、资源、安全和审计8个面板,对于网络数据抓取而言只需要重点关注元素和网络这两大面板即可。这部分其实在R爬虫必备基础—Chrome开发者工具(F12)做过比较详细的介绍,今天主要就XHR面板做深入说明。如下图,XHR面板显示共有请求到6个资源,包括文件名、状态码和类型等信息。

    image

    如果要获取自己想要的信息,就需要通过对XHR请求多试几次,即可找到真实要请求的URL,并掌握其构造信息,如下图。

    image

    通过字符串的拼接即可构造准确的URL资源请求,然后按照批量下载的方式利用RCurl/httr包进行网页抓取解析即可。通过参数信息可以获得URL构造信息。

    image

    总结来说,通过AJAX构造的DHTML网站的探索方法第一步就是要准确找出我们要抓取的数据资源是来自于哪个请求,包括一些地址和参数信息,之后才能考虑如何对定位到的数据进行抓取。

    PubMed举例说明

    为了更加方便理解异步加载,我们以Pubmed为例。打开网站,输入lncRNA关键词,得到如下检索界面,网址为:https://pubmed.ncbi.nlm.nih.gov/?term=lncRNA&filter=ds1.y_1,共计显示10条记录。从下图我们发现该网页请求带有Query String Parameters 参数,而rvest包功能简单,不提供参数设置,对于这类请求有限制的网页,rvest的请求功能太脆弱了,不建议用rvest包进行pubmed网页爬取。其实从网址格式也可以看出来,它不是以html/htm等格式结尾的网页,是个动态网页。

    image

    这个时候考虑动态网页抓取R包(httr包)。首先查看网页规律。通过https://pubmed.ncbi.nlm.nih.gov/?term=lncRNA&filter=ds1.y_1这个网址可以获取前10条信息,但其实共计有7481条信息,需要完全获取该怎么办?先尝试点击more后,发现展示了page2(共计10条),将鼠标往下拉,网址会添加&page=2,最终网址:https://pubmed.ncbi.nlm.nih.gov/?term=lncRNA&filter=ds1.y_1&page=2,Ctrl+R刷新开发工具后台,预览的结果是11-20条。按照如此规律,就可以构建有规律的网址https://pubmed.ncbi.nlm.nih.gov/?term=lncRNA&filter=ds1.y_1&page=数字 ,共计7481条记录,每页显示10条,那需要749页。按照这个思路就可以爬取所有信息。

    image

    但是,还有另一种方式,回到首页,打开开发后台,定位到XHR面板。然后点击more,一直more,注意这个过程不要刷新页面****,发现XHR面板上每点击一次more,就会生成一个more,同时你主网页网址维持不变。这就是个通过点击more激发异步加载的典型案例

    image

    查看这几个more的Headers信息,会发现明显的规律,都是向https://pubmed.ncbi.nlm.nih.gov/more/发起请求,通过POST提交表单信息,只要修改page即可。按照这个思路也可以爬取所有文章信息。

    image

    往期回顾
    R爬虫在工作中的一点妙用
    R爬虫必备基础——HTML和CSS初识
    R爬虫必备基础——静态网页+动态网页
    R爬虫必备——rvest包的使用
    R爬虫必备基础——CSS+SelectorGadget
    R爬虫必备基础—Chrome开发者工具(F12)
    R爬虫必备基础—HTTP协议
    R爬虫必备—httr+POST请求类爬虫(网易云课堂)
    R爬虫必备基础—rvest为什么不用于动态网页?

    相关文章

      网友评论

          本文标题:R爬虫必备基础—动态异步加载

          本文链接:https://www.haomeiwen.com/subject/majvrktx.html