使用 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, 后续完善
随机推荐
- LINQ的左连接、右连接、内连接和Lamda表达式实现Left join
1.左连接: var LeftJoin = from t1 in l1join t2 in l2on t1.ID equals t2.ID into Joinedt12from t3 in Joine ...
- 172. Factorial Trailing Zeroes(阶乘中0的个数 数学题)
Given an integer n, return the number of trailing zeroes in n!. Example 1: Input: 3 Output: 0 Explan ...
- EditPlus 4.3.2502 中文版已经发布(12月5日更新)
新的版本修复了在之前某版本中键盘 End 键定位位置错误的问题.
- EF Code First学习笔记 初识Code First(转)
Code First是Entity Framework提供的一种新的编程模型.通过Code First我们可以在还没有建立数据库的情况下就开始编码,然后通过代码来生成数据库. 下面通过一个简单的示例来 ...
- Hadoop学习之路(二十四)YARN的资源调度
YARN 1.1.YARN 概述 YARN(Yet Another Resource Negotiator) YARN 是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操 作系 ...
- js如何模拟multipart/form-data类型的请求
var temp = document.createElement('form'); temp.action = this.data.testURL; temp.method = 'post'; te ...
- 利用Python网络爬虫爬取学校官网十条标题
利用Python网络爬虫爬取学校官网十条标题 案例代码: # __author : "J" # date : 2018-03-06 # 导入需要用到的库文件 import urll ...
- 函数指针(pointer to function)——qsort函数应用实例
一,举例应用 在ACM比赛中常使用 stdlib.h 中自带的 qsort 函数,是教科书式的函数指针应用示范. #include <stdio.h> #include <stdli ...
- 09: python基础补充
1.1 闭包 1.闭包概念 1. 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包 2. 一般情况下,在我们认知当中,如果一个函数 ...
- 20145127《java程序设计》第二周学习总结
本周我又对java程序进行了更进一步的学习.相比与上一周的学习内容的宏观,这一周的所学更加的系统和调理明确. 本周是对java基础语法的学习.首先,我先是认识类型与变量. Java可区分为基本类型和类 ...