在 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 选择器从网页中提取数据的更多相关文章

  1. css注入获取网页中的数据

    <style><?php echo htmlspecialchars($_GET['x']);?></style> <br><br>< ...

  2. 在Scrapy中如何利用Xpath选择器从HTML中提取目标信息(两种方式)

    前一阵子我们介绍了如何启动Scrapy项目以及关于Scrapy爬虫的一些小技巧介绍,没来得及上车的小伙伴可以戳这些文章: 手把手教你如何新建scrapy爬虫框架的第一个项目(上) 手把手教你如何新建s ...

  3. JMETER从JSON响应中提取数据

    如果你在这里,可能是因为你需要使用JMeter从Json响应中提取变量. 好消息!您正在掌握掌握JMeter Json Extractor的权威指南.作为Rest API测试指南的补充,您将学习掌握J ...

  4. 如何使用JMETER从JSON响应中提取数据

    如果你在这里,可能是因为你需要使用JMeter从Json响应中提取变量. 好消息!您正在掌握掌握JMeter Json Extractor的权威指南.作为Rest API测试指南的补充,您将学习掌握J ...

  5. 如何使用JMeter从文件中提取数据

    在性能测试方面,重用响应数据至关重要.几乎(如果不是全部!)负载测试场景假设您: 从先前的响应中提取有趣的方面,并在下一个请求中重用它们(也称为相关) 确保实际响应符合预期(又称断言) 因此,如果您是 ...

  6. [数据科学] 从csv, xls文件中提取数据

    在python语言中,用丰富的函数库来从文件中提取数据,这篇博客讲解怎么从csv, xls文件中得到想要的数据. 点击下载数据文件http://seanlahman.com/files/databas ...

  7. 通过CSS让html网页中的内容不可选

    *{ moz-user-select: -moz-none; -moz-user-select: none; -o-user-select:none; -khtml-user-select:none; ...

  8. Web网页中动态数据区域的识别与抽取 Dynamical Data Regions Identification and Extraction in Web Pages

    Web网页中动态数据区域的识别与抽取 Dynamical Data Regions Identification and Extraction in Web Pages Web网页中动态数据区域的识别 ...

  9. 网页中的数据的4个处理方式:CRUD(Creat, Retrive, Update, Delete)

    网页中的数据的4个处理方式:CRUD(Creat, Retrive, Update, Delete) 2018-12-21, 后续完善

随机推荐

  1. LINQ的左连接、右连接、内连接和Lamda表达式实现Left join

    1.左连接: var LeftJoin = from t1 in l1join t2 in l2on t1.ID equals t2.ID into Joinedt12from t3 in Joine ...

  2. 172. Factorial Trailing Zeroes(阶乘中0的个数 数学题)

    Given an integer n, return the number of trailing zeroes in n!. Example 1: Input: 3 Output: 0 Explan ...

  3. EditPlus 4.3.2502 中文版已经发布(12月5日更新)

    新的版本修复了在之前某版本中键盘 End 键定位位置错误的问题.

  4. EF Code First学习笔记 初识Code First(转)

    Code First是Entity Framework提供的一种新的编程模型.通过Code First我们可以在还没有建立数据库的情况下就开始编码,然后通过代码来生成数据库. 下面通过一个简单的示例来 ...

  5. Hadoop学习之路(二十四)YARN的资源调度

    YARN 1.1.YARN 概述 YARN(Yet Another Resource Negotiator) YARN 是一个资源调度平台,负责为运算程序提供服务器运算资源,相当于一个分布式的操 作系 ...

  6. js如何模拟multipart/form-data类型的请求

    var temp = document.createElement('form'); temp.action = this.data.testURL; temp.method = 'post'; te ...

  7. 利用Python网络爬虫爬取学校官网十条标题

    利用Python网络爬虫爬取学校官网十条标题 案例代码: # __author : "J" # date : 2018-03-06 # 导入需要用到的库文件 import urll ...

  8. 函数指针(pointer to function)——qsort函数应用实例

    一,举例应用 在ACM比赛中常使用 stdlib.h 中自带的 qsort 函数,是教科书式的函数指针应用示范. #include <stdio.h> #include <stdli ...

  9. 09: python基础补充

    1.1 闭包 1.闭包概念 1. 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包 2. 一般情况下,在我们认知当中,如果一个函数 ...

  10. 20145127《java程序设计》第二周学习总结

    本周我又对java程序进行了更进一步的学习.相比与上一周的学习内容的宏观,这一周的所学更加的系统和调理明确. 本周是对java基础语法的学习.首先,我先是认识类型与变量. Java可区分为基本类型和类 ...