R语言利用rvest包爬虫,主要用到函数:read_html()、html_nodes()、html_text()和html_attrs()。
安装这个包:install.packages('rvest')
- read_html():下载网页;
- html_nodes():获得指定名称的网页元素、节点;
- html_text():获得指定名称的网页元素、节点里面的文本;
- html_attrs():获得指定的网址;
以新浪内地新闻为例
下面是新浪内地新闻网址:http://news.sina.com.cn/china/
我们想要爬取每条新闻的标题、时间和对应的链接,因为点击标题,会触发链接,进入每条新闻内容页。
载入rvest包
library(rvest)
这一页网址为:
url0 <- 'http://news.sina.com.cn/china/'
下载这一页全部网页元素
web <- read_html(url0)
鼠标右键==》"审查元素",可以看到这些信息所位于的网页标签,如下:
我们需要获取:
(1)、新闻标题:"湖南“邵东伤医案”二审宣判 驳回上诉维持原判",位于
标签下面的标签里面的链接文本;
(2)、时间:位于
里面的文本;
(3)、链接:就是href = "http://news.sina.com.cn/o/2017-06-23/doc-ifyhmpew3184730.shtml"这个东西。
它们都位于最外面大的蓝色框:
里面,所以对于这么大的网站页面,我们需要首先定位到
,然后具体定位它下面的新闻标题、时间。这里“class="news-item"”表示网页元素
的类为“news-item”,用“.”表示类(如果遇到< div id="idName">就需要用#,即:div#idName):
div.news-item h2 a
可以理解为class名为news-item下的h2标签下的a标签,直接定位到粉红色框处。
定位到链接标签
News <- web %>% html_nodes('div.news-item h2 a')#把新闻标题定准位。
相当于:News <- html_nodes(web,'div.news-item h2 a')
News下就包含标签的所有信息,包括链接、文本、一些其它样式;前面管道讲过这种传参方法:R语言管道%>%用法
获得链接文本(也就是新闻标题)
Title <- News%>%html_text()
其实,上面分两步获得新闻标题,利用管道传参可以一部完成,不利用管道照样可以一步,只是会有一层一层的括号,可读性不好。就是一个变量等价代换,把News那一部分换下来即可,即:
Title <- web %>% html_nodes('div.news-item h2 a')%>%html_text()
获得的一些新闻标题长这样:
获得新闻时间
为了便于对照查看,图再放一次:
时间位于上图中红色框住的标签:
6月23日 19:17
,虽然它也位于
里面,但是这个标签名唯一,直接定位就好。可以这样理解:查找计算机文件时,两个文件夹下面可能有同名文件,这时就需要定位到各自的文件夹才行;如果,没有相同文件,直接搜索文件名而不需要定位到文件夹就行了。
Time <- web %>% html_nodes('div.time') %>% html_text()
获得的时间是这样的:
获得链接
与第一步定位新闻标题一样:class名为news-item下的h2标签下的a标签,然后用专门函数html_attrs()获得链接。
link <- News %>% html_attrs()
获得的每个元素都是列表,比如第一个元素:
我们就需要,处理一下,每个元素有三个元素,取第一个就行了,于是:
link1 <- c(1:length(link))初始化一个向量
for(i in 1:length(link))
{
link1[i] <- link[[i]][1]
}
最终得到的向量:
保存为csv文件
dat <- data.frame(Title,Time,link1)
setwd('D:\\RWorkSpace')
write.csv(dat,file = 'news.csv',row.names = FALSE)
最终所有程序代码如下:
(3)、链接:就是href = "http://news.sina.com.cn/o/2017-06-23/doc-ifyhmpew3184730.shtml"这个东西。
它们都位于最外面大的蓝色框:
div.news-item h2 a
可以理解为class名为news-item下的h2标签下的a标签,直接定位到粉红色框处。
定位到链接标签
News <- web %>% html_nodes('div.news-item h2 a')#把新闻标题定准位。
相当于:News <- html_nodes(web,'div.news-item h2 a') News下就包含标签的所有信息,包括链接、文本、一些其它样式;前面管道讲过这种传参方法:R语言管道%>%用法
获得链接文本(也就是新闻标题)
Title <- News%>%html_text()
其实,上面分两步获得新闻标题,利用管道传参可以一部完成,不利用管道照样可以一步,只是会有一层一层的括号,可读性不好。就是一个变量等价代换,把News那一部分换下来即可,即:
Title <- web %>% html_nodes('div.news-item h2 a')%>%html_text()
获得的一些新闻标题长这样:
获得新闻时间
为了便于对照查看,图再放一次:
时间位于上图中红色框住的标签:
,虽然它也位于
Time <- web %>% html_nodes('div.time') %>% html_text()
获得的时间是这样的:
获得链接
与第一步定位新闻标题一样:class名为news-item下的h2标签下的a标签,然后用专门函数html_attrs()获得链接。
link <- News %>% html_attrs()
获得的每个元素都是列表,比如第一个元素:
我们就需要,处理一下,每个元素有三个元素,取第一个就行了,于是:
link1 <- c(1:length(link))初始化一个向量 for(i in 1:length(link)) { link1[i] <- link[[i]][1] }
最终得到的向量:
保存为csv文件
dat <- data.frame(Title,Time,link1) setwd('D:\\RWorkSpace') write.csv(dat,file = 'news.csv',row.names = FALSE)
文章评论