R爬虫必备基础—rvest为什么不用于动态网页?
上一期R爬虫必备—httr包抓取动态网页(一)主要介绍了httr包如何进行POST请求类爬虫,什么是POST?POST是一种HTTP 请求,根据 HTTP 标准,共有六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
序号 | 方法 | 描述 |
1 | GET | 请求指定的页面信息,并返回实体主体。 |
2 | HEAD | 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 |
3 | POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。 |
4 | PUT | 从客户端向服务器传送的数据取代指定的文档的内容。 |
5 | DELETE | 请求服务器删除指定的页面。 |
6 | CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。 |
7 | OPTIONS | 允许客户端查看服务器的性能。 |
8 | TRACE | 回服务器收到的请求,主要用于测试或诊断。 |
9 | PATCH | 是对 PUT 方法的补充,用来对已知资源进行局部更新 。 |
在请求模式中,最常用的请求方法是GET和POST方法,在爬虫过程中至关重要。这两个方法都是从服务器请求一个资源,但是在正文的使用上有所不同。GET方法是网络请求最通用方法,可理解为直接请求。POST则有所区别,需要提交表单信息才能请求到信息。
之前咱们写过R爬虫必备——rvest包的使用,它的网页请求方式就很简单,直接用read_html()即可获取网页,完全没有涉及这些请求方法。怎么看这个包更简单更方便,那为什么不用rvest进行爬取呢?
read_html():获取并解析网页
html_nodes():定位并获取节点信息
html_text():提取节点文本信息
html_attr():提取节点属性信息
首先,rvest的确是个很好的爬虫工具,但它的强项在于网页解析,有两套解析语法可选(Xpath、css), 可以快捷的提取取所需数据,但是它的网页请求功能很脆弱,在实际操作中,特别是动态网页,明明数据就在网页源码中,通过css或者xpath路径,可就是没有返回值,或者总是返回chracter(0)、list(0)或者NULL,代码检查也没任何错误,就是爬取失败。这是因为rvest包提供的read_html()这种访问方式是很脆弱的,因为没有任何伪装措施和报头信息,直接访问存在着很大的隐患。
此外,对于那些异步加载的网页来说,请求的网络资源分成了html纯文档和js脚本,浏览器可以通过解析并执行js脚本来更新关键数据,而通过其他非浏览器终端发送的请求,通常情况下只能拿到纯文档(你可以看到一些script标签中引用的的.js脚本),并不具备解析js脚本的能力。
当然,这并不妨碍rvest包(read_html函数)直接从某些静态网站的URL中解析数据,因为很多静态网页并不会对网络请求做过多限制,比如不检查User-Agent,不做任何的数据隐藏,不限制数据权限等。
当你有权限直接通过URL获取完整网页(注意是完整网页,大家直接理解为静态网页吧),或者已经通过其他请求库(比如httr)获取了完整的网页,下面就交给rvest,读取网页,解析并提取数据。总结来说:httr(请求网页)+rvest(解析网页),这是一对较为经典的工具搭配。还有一组更为复杂的:RCurl(请求网页)+XML(解析网页)。
read_html
read_html函数其实直接调用的是xml2包中的read_html方法,rvest包作为请求器的脆弱性便在于此,它是一个I/0函数。通俗一点说就是文件导入导出的操纵函数,与read_csv、read_xlsx、read_table属于同类。在XML包中与之功能一致的函数是xmlParse/xmlTreeParse。xmlParse/xmlTreeParse函数也是仅仅作为RCurl请求包的解析函数使用的,很少有单独使用xmlParse请求并解析网页,它太脆弱了,尽管它是支持直接从url获取并解析网页的。当然,对于那些对网络请求没有过多限制的网页来说,可以直接使用read_html函数获取并解析网页。
html_nodes
html_nodes函数是rvest包中非常关键的函数,提供有两套网页解析语法:xpath、css,可以非常便利的提取自己想要的节点信息。在html_nodes函数中,最终的解析函数是xml2中的xml_find_all函数,它的功能类似于XML包中的XpathAapply函数或者getNodest函数。在html_nodes函数中,一切都是xpath,即便你提供的是css路径,也会先被转化为xpath之后再使用xml_find_all函数进行处理。
html_attrs
该函数直接调用的xml2包中的xml_attrs函数,就是从节点中批量提取属性值。
html_text
该函数调用的xml2包中的xml_text函数,提取节点文本。
httr+rvest与RCurl+XML两种工具搭配的比较
包 | RCurl | httr | |
请求 | GET请求 | getURL/getFrom getBinaryURL/writeBin(二进制 | GET writeBin(二进制) |
POST请求 | postFrom 支持四种常规参数编码类型 | POST 支持四种常规参数编码类型) | |
解析(html/xml) | XML::xmlParse/XML::htmlParse | rvest::read_html/xml xml2::read_html/xml | |
Xpath | XML::xpathSApply/XML::getNodeSet XML::xmlGetAttr XML::xmlValue | rvest::html_nodes/xml2::xml_find_all rvest::html_attrs/xml2::xml_attrs rvest::html_text/xml2::xml_text | |
CSS | selectr::querySelectorAll | selectr::querySelectorAll | |
json返回值 | jsonlite::fromJSON | jsonlite::fromJSON |
四种常规参数编码类型:application/x-www-form-urlencoded ;multipart/form-data;application/json;text/xml。
总结:rvest包的高级请求功能依托于httr(当然你可以直接使用httr来构造请求)。解析器依托于xml2包中的xml_find_all函数实现。解析语法有css和xpath可选,但是最终都会转换为xpath进行解析。借助magrittr包来做管道优化,实现代码简化与效率提升。
参考:https://cloud.tencent.com/developer/article/1092915
R爬虫系列|工作需要衍生的笔记
R爬虫必备基础——HTML和CSS初识
R爬虫必备基础——静态网页+动态网页
R爬虫必备——rvest包的使用
R爬虫必备基础——CSS+SelectorGadget
R爬虫必备基础—Chrome开发者工具(F12)
R爬虫必备基础—HTTP协议
R爬虫必备—httr包抓取动态网页(一)
长按识别二维码,关注"YJY技能修炼"