使用 CSS 选择器从网页中提取数据
在 R 中,关于网络爬虫最简单易用的扩展包是 rvest。运行以下代码从 CRAN 上安装:
install.packages("rvest")
首先,加载包并用 read_html( ) 读取 data/single-table.html,再尝试从网页中提取表格:
library(rvest)
## Loading required package: xml2
single_table_page <- read_ _html("data/single-table.html")
single_table_page
## {xml_document}
## <html>
## [1] <head>\n <title>Single table</title>\n</head>
## [2] <body>\n <p>The following is a table</p>\n <table i ...
注意到,single_table_page 是一个HTML 解析文档,是HTML 节点的嵌套数据结构。
使用 rvest 函数从网页上爬取信息的典型过程是这样的。首先,定位需要从中提取数
据的 HTML 节点。然后,使用 CSS 选择器或者 XPath 表达式筛选 HTML 节点,从而选择
需要的节点,剔除不需要的节点。最后,对已解析的网页使用合适的选择器,用 html_
nodes( ) 提取节点子集,用 html_attrs( ) 提取属性,用 html_text( ) 提取文本。
rvest 包也提供了一些简单的函数,从网页中直接提取数据并返回一个数据框。例如,
提取网页中所有的 <table> 元素,我们直接调用 html_table( ):
html_ _table(single_table_page)
## [[1]]
## Name Age
## 1 Jenny 18
## 2 James 19
为了提取<table> 中的第 1 个元素,我们在使用 CSS 选择器 table 的时候,调用
html_node( ) 选择第1个节点,再对选择出来的节点调用 html_table( ) 得到一个数据框:
html_ _table(html_ _node(single_table_page, "table"))
## Name Age
## 1 Jenny 18
## 2 James 19
一个很自然的想法便是使用管道操作,就像第 12 章中介绍的 dplyr 包中使用 %>% 管
道操作符。回顾一下,%>% 执行 x %>% f(···) 的基本方法就是 f(x,···),因此,嵌
套调用可以被拆解,从而提高可读性。上述代码可以用 %>% 重写为:
single_table_page %>%
html_ _node("table") %>%
html_ _table()
## Name Age
## 1 Jenny 18
## 2 James 19
现在,读取 data/products.html,并用 html_nodes( ) 匹配 <span class = "name"> 节点:
products_page <- read_ _html("data/products.html")
products_page %>%
html_ _nodes(".product-list li .name")
## {xml_nodeset (3)}
## [1] <span class = "name">Product-A</span>
## [2] <span class = "name">Product-B</span>
## [3] <span class = "name">Product-C</span>
注意到,我们想选择的节点是 product-list 类的 <li> 标签下属于 name 类的节
点。因此,使用.product-list li .name 选择这样的嵌套节点。如果对这些符号不熟
悉,请温习常用的 CSS 表。
之后,再用 html_text( ) 从选择的节点中提取内容,这个函数会返回一个字符向量:
products_page %>%
html_ _nodes(".product-list li .name") %>%
html_ _text()
## [1] "Product-A" "Product-B" "Product-C"
类似地,下面的代码提取出产品价格:
products_page %>%
html_ _nodes(".product-list li .price") %>%
html_ _text()
## [1] "$199.95" "$129.95" "$99.95"
前 面 这 些 代 码 中 , html_nodes( ) 返 回 一 个 包 含 HTML 节 点 的 集 合 ,
而 html_text( ) 则从每个 HTML 节点中智能地提取内部文本,然后返回一个字符向量。
但是,这些价格保留了它们的原生格式,即字符串形式,而不是数字。下面的代码提
取出来相同的数据,并把它转换成更常用的格式:
product_items <- products_page %>%
html_ _nodes(".product-list li")
products <- data.frame(
name = product_items %>%
html_ _nodes(".name") %>%
html_ _text(),
price = product_items %>%
html_ _nodes(".price") %>%
html_ _text() %>%
gsub("$", "", ., fixed = TRUE) %>%
as.numeric(),
stringsAsFactors = FALSE
)
products
## name price
## 1 Product-A 199.95
## 2 Product-B 129.95
## 3 Product-C 99.95
注意到,选择节点的中间结果可以被存储在一个变量中,以便重复使用。后续
的 html_nodes( ) 或 html_node( ) 仅仅匹配内部节点。
既然产品价格是数值,我们便可以用 gsub( ) 从原生价格中移除 $,然后将结果转换
成一个数值向量。管道操作中的 gsub( ) 调用有点特殊,因为前面的结果(用 . 表示)
本该放在第 3 个参数位置,而不是第 1 个。
这个例子中,.product-list li .name 可以缩写为 .name,同理,.product-list
li .price 可以被 .price 代替。在实际应用中,CSS 类被广泛地运用,因此,一个通用
的选择器可能会匹配太多非合意的元素。所以,最好选择一个描述更清晰,限制条件更严
格的选择器去匹配感兴趣的节点。
使用 CSS 选择器从网页中提取数据的更多相关文章
- css注入获取网页中的数据
<style><?php echo htmlspecialchars($_GET['x']);?></style> <br><br>< ...
- 在Scrapy中如何利用Xpath选择器从HTML中提取目标信息(两种方式)
前一阵子我们介绍了如何启动Scrapy项目以及关于Scrapy爬虫的一些小技巧介绍,没来得及上车的小伙伴可以戳这些文章: 手把手教你如何新建scrapy爬虫框架的第一个项目(上) 手把手教你如何新建s ...
- JMETER从JSON响应中提取数据
如果你在这里,可能是因为你需要使用JMeter从Json响应中提取变量. 好消息!您正在掌握掌握JMeter Json Extractor的权威指南.作为Rest API测试指南的补充,您将学习掌握J ...
- 如何使用JMETER从JSON响应中提取数据
如果你在这里,可能是因为你需要使用JMeter从Json响应中提取变量. 好消息!您正在掌握掌握JMeter Json Extractor的权威指南.作为Rest API测试指南的补充,您将学习掌握J ...
- 如何使用JMeter从文件中提取数据
在性能测试方面,重用响应数据至关重要.几乎(如果不是全部!)负载测试场景假设您: 从先前的响应中提取有趣的方面,并在下一个请求中重用它们(也称为相关) 确保实际响应符合预期(又称断言) 因此,如果您是 ...
- [数据科学] 从csv, xls文件中提取数据
在python语言中,用丰富的函数库来从文件中提取数据,这篇博客讲解怎么从csv, xls文件中得到想要的数据. 点击下载数据文件http://seanlahman.com/files/databas ...
- 通过CSS让html网页中的内容不可选
*{ moz-user-select: -moz-none; -moz-user-select: none; -o-user-select:none; -khtml-user-select:none; ...
- Web网页中动态数据区域的识别与抽取 Dynamical Data Regions Identification and Extraction in Web Pages
Web网页中动态数据区域的识别与抽取 Dynamical Data Regions Identification and Extraction in Web Pages Web网页中动态数据区域的识别 ...
- 网页中的数据的4个处理方式:CRUD(Creat, Retrive, Update, Delete)
网页中的数据的4个处理方式:CRUD(Creat, Retrive, Update, Delete) 2018-12-21, 后续完善
随机推荐
- SV中的OOP
OOP:Object-Oriented Programming,有两点个人认为适合验证环境的搭建:1)Property(变量)和Method(function/task)的封装,其实是BFM模型更方便 ...
- 错误源:.net SqlClient data provider
下午在做毕业设计的时候,想删除数据库的一条数据,结果发现删除的时候老是出现 ======错误源:.net SqlClient data provider==== 这样的错误:本来以为是我还在运行着项目 ...
- python 读写压缩文件
gzip 和bz2 模块可以很容易的处理这些文件.两个模块都为open() 函数提供了另外的实现来解决这个问题.比如,为了以文本形式读取压缩文件,可以这样做: # gzip compression i ...
- 大杀器Bodymovin和Lottie:把AE动画转换成HTML5/Android/iOS原生动画
前段时间听部门老大说,Airbnb出了个移动端的动画库Lottie,可以和一个名叫Bodymovin的AE插件结合起来,把在AE上做好的动画导出为json文件,然后以Android/iOS原生动画的形 ...
- Linux服务器配置---ftp限制带宽
限制带宽 ftp服务器可以设置每个用户的带宽,这样根据实际需求来分配,更加充分的利用系统资源.带宽通过参数“anon_max_rate“和”local_max_rate“来设置,这两个参数在配置文件中 ...
- Linux基础命令---diffstat
diffstat 这个程序读取diff的输出,并显示每个文件的插入.删除和修改的直方图.Diffstat是一个用于检查大型复杂修补程序文件的程序.它从包含diff输出的一个或多个输入文件中读取,生成针 ...
- Window下安装npm
Node.js停火各大技术论坛都在讨论,前段时间工作太忙没时间学习,趁着周末空闲玩玩,在网上找了些资料发现Node.js本身有windows版和unix版下载和使用都挺方便但是其扩展模块依赖复杂通过手 ...
- 【读书笔记】SpringBoot读书笔记
整体目录结构: 一.入门 二.开发第一个应用程序 三.自定义配置 四.测试 五.Groovy与Spring Boot Cli 六.在Spring Boot中使用Grails 七.深入Actuator ...
- HCNP学习笔记之子网掩码的计算和划分详细
0x00 子网掩码的计算 TCP/IP网间网技术产生于大型主流机环境中,它能发展到今天的规模是当初的设计者们始料未及的.网间网规模的迅速扩展对IP地址模式的威胁并不是它不能保证主机地址的唯一性,而是会 ...
- 深入浅出JVM
这篇文章简要解析了JVM的内部结构.下面这幅图展示了一个典型的JVM(符合JVM Specification Java SE 7 Edition)所具备的关键内部组件. 上图展示的所有这些组件都将在下 ...