使用 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, 后续完善
随机推荐
- [LeetCode] 181. Employees Earning More Than Their Managers_Easy tag: SQL
The Employee table holds all employees including their managers. Every employee has an Id, and there ...
- 基于androidstudio3.0的build文件配置问题
最近,在研究APP自动化相关的东西,在搭建环境的时候,遇到的坑以及最后解决的方法,不过目前很多东西了解得还不是很细,暂时先简单的记录一下一.build配置文件 主要分为两种: 1.工程下的build配 ...
- html04
web的三要素:HTML:搭建页面的基本结构css: 对页面进行修饰-让页面更美观JavaScript:让页面可以有交互行为(用户和界面)1.js是什么:JavaScript :页面的脚本语言,运行在 ...
- 持续集成之二:搭建SVN服务器(subversion)
安装环境 Red Hat Enterprise Linux Server release 7.3 (Maipo) jdk1.7.0_80 subversion-1.10.3.tar.gz apr-1. ...
- Linux命令: 结束命令
1)ctrl+c,退出命令 2)q,退出文件
- MySQL Crash Course #07# Chapter 15. 关系数据库. INNER JOIN. VS. nested subquery
索引 理解相关表. foreign key JOIN 与保持参照完整性 关于JOIN 的一些建议,子查询 VS. 联表查询 我发现MySQL 的官方文档里是有教程的. SQL Tutorial - W ...
- Python入门之面向对象编程(四)Python描述器详解
本文分为如下部分 引言——用@property批量使用的例子来引出描述器的功能 描述器的基本理论及简单实例 描述器的调用机制 描述器的细节 实例方法.静态方法和类方法的描述器原理 property装饰 ...
- ImageLoader作用 AAAA
https://github.com/nostra13/Android-Universal-Image-Loader ImageLoader作用 1.多线程下载图片,图片可以来源于网络,文件系统,项目 ...
- 作为从业人员,如果一定要学一门新的编程语言,那么它一定是c++
作为从业人员,如果一定要学一门新的编程语言,那么它一定是c++. 无论各种编程语言排行榜如何变化,什么语言最赚钱,想成为真正的程序员,那么c/c++是必修课,因为几乎所有的底层都是c/c++编写的,各 ...
- bzoj 1179 [APIO 2009]Atm(APIO水题) - Tarjan - spfa
Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一 ...