rvest是Hadley大神开发的包,使用非常简单,不需要懂得太多的HTML和CSS知识,
当然对于反爬虫的web,基本上就力不从心了,这种情况还是使用Python吧,毕竟术业有专攻。
首先安装SelectorGadget
如果不懂HTML和CSS,最好安装,如果懂,还是用Python吧。
常用函数:
1.文本提取
我们以boss直聘
然后我们单击SelectorGadget插件按钮以开启该功能,再次点击可关闭。
单击后,鼠标指针悬浮于web上任意的tags元素,都会出现黄色的高亮框。如下图所示:
选中需要的元素后,右击,然后“检查”就能打开源代码并定位到该元素,如下图:
通过浏览器,发现左侧的岗位tags为.info-primary.name,公司名称为.info-company.name。
其中的句点.表示类对象,多级类对象用空格隔开。
然后用read_html()打开该web。
1library(rvest)
2library(magrittr)
3
4#打开网页
6web_1<-read_html(x=site_1)
7
8tag_job<-".info-primary.name.job-title"#岗位名字
9tag_rev<-".info-primary.name.red"#薪水
10tag_com<-".info-company.company-text.name"#公司名字
11
12#开始抓取
13job_1<-html_nodes(x=web_1,css=tag_job)
14rev_1<-html_nodes(x=web_1,css=tag_rev)
15com_1<-html_nodes(x=web_1,css=tag_com)
16
17#从tags中提取文本内容
18job_1%<>%html_text()
19rev_1%<>%html_text()
20com_1%<>%html_text()
21
22#合并向量为数据框
23job_com<-data.frame(job=job_1,
24revenue=rev_1,
25company=com_1,
26stringsAsFactors=FALSE)
27head(job_com)
28rm(site_1,web_1,job_1,com_1)
提取web中的文本,就采用这种方法,很多时候,文本内容复制,
无法直接用html_text()将文本提取出来,
这时候就需要用正则表达式和stringr包。
2.多重页面
很多时候,一个web项目中,有多重页面,即下一页。
这就需要找到每一页的url规律,找到规律后,增加循环就能搞定了。
这里我们发现第2页开始,url就出现变化了,从第2页到最后一页(最后1页还没找到),每一页都只改变url末尾的page=n。事实上,大多数网页都有这个page=n。
通过不断点击下一页,发现最后一页是第10页,
接下来我们爬取第2页到第10页
5
6
7for(nin2:10){
8myurl<-paste0(url_begin,n)
9page_n<-read_html(x=myurl)
10
11#开始抓取
12job_n<-html_nodes(x=page_n,css=tag_job)%>%html_text()
13rev_n<-html_nodes(x=page_n,css=tag_rev)%>%html_text()
14com_n<-html_nodes(x=page_n,css=tag_com)%>%html_text()
15
16#合并向量为数据框
17job_com_n<-data.frame(job=job_n,
18revenue=rev_n,
19company=com_n,
20stringsAsFactors=FALSE)
22
23job_com<-rbind(job_com,job_com_n)#添加到job_com内
24}
25
26rm(job_n,rev_n,com_n,job_com_n)
27str(job_com)
28DT::datatable(job_com)#交互式表格输出
1##'data.frame':300obs.of3variables:
2##$job:chr"数据分析""数据分析专家""数据分析""数据分析(洛阳)"...
3##$revenue:chr"6k-9k""12k-18k""3k-5k""6k-7k"...
4##$company:chr"腾讯""中国石油规划总院""万声""哈啰出行"...
3.表格提取
首先打开该网站,然后我们选择一个城市,如选择“成都”,寻找url变化规律。
发现新增url后缀:chengdu。使用SelectorGadget审查元素,发现表格的类为“table”。
下面我们同时提取10个大城市的表格。
4city_name<-c("beijing","shanghai","guangzhou","shenzhen","hangzhou",
5"tianjin","chengdu","nanjing","xian","wuhan")
8for(nin1:length(city_name)){
9
10#提取表格
11pm_city<-read_html(x=url_cites[n])%>%
12html_nodes(css=".aqis_live_data.container.table")%>%
13.[[2]]%>%#注意这里的点
14html_table()
16#批量生成变量
17assign(x=paste0("pm_",city_name[n]),value=pm_city)
18
19}
20rm(url_cites,pm_city)
22DT::datatable(pm_chengdu)
23DT::datatable(pm_beijing)
(截屏预览不全)
4.图片提取
这里我们打开觅元素
可以发现url跳转到
同样使用SelectorGadget审查元素,发现图片都有类:.img-wrap.lazy。
我们点击一张图片,发现跳转到另一个url,将这个url复制,在审查元素中搜索,
可以发现该url类为img-wrap或i-title-wrap。
1rm(list=ls());gc()#清空内存
2library(rvest)
3library(stringr)
4
5#提取nodes
7flower_nodes<-read_html(x=url_first)%>%
8html_nodes(css=".img-wrap")
10#查看字符串,以使用正则表达式
11flower_nodes[[1]]
1##used(Mb)gctrigger(Mb)maxused(Mb)
2##Ncells71703638.3119792064119792064
3##Vcells135624510.4838860864261615220
4##{xml_node}
2library(stringr)
3library(magrittr)
4library(rlist)
6flower_nodes%<>%
8unlist()
10flower_nodes[1]
提取图片的url链接
4image_url<-vector()#生成空向量
6for(nin1:length(flower_nodes)){
7image_url[n]<-read_html(x=flower_nodes[n])%>%
8html_nodes(css=".img-wrap.show-image")%>%
10unlist()
12}
13
14image_url[1]
读取url图片并保存
1library(magick)
2
3file_path<-"E:/R_input_output/images_output/scrapt_collection/"
5for(nin1:length(image_url)){
6image_read(path=image_url[n])%>%#读取url图片
7image_write(path=paste0(file_path,n,".jpg"))#保存图片
8}
10#动画展示保存到文件夹中的图片
11image_animate(image=
12image_read(path=paste0(file_path,as.character(1:length(image_url)),".jpg")))
(原为动图)
5.模拟对话
函数:
html_session(),jump_to(),follow_link(),back(),forward(),submit_form(),
可以用来模拟网上浏览行为,这里我们使用豆瓣网来模拟。
使用html_session()来创建会话。
6session<-html_session(u)#创建会话
什么是表单HTML中的表单被用来搜集用户的不同类型的输入。
HTML表单包含表单元素,表单元素是指不同类型的input元素、复选框(box)、
单选(radio)、提交按钮(submit)等。
穿越表单分为以下3步:
3forms<-session%>%html_form()
4forms
2form<-forms[[1]]#forms中的第一个列表是我们的目标列表
3form
在上面的结果中,只有‘search_text’:的冒号后为空,
这表明‘search_text’还没有填充任何值,而我们的填充任务就是把它填上。
比如说我要搜索“流浪地球”,
那么我就在set_values()中指定一个search_text参数,令它的值为“流浪地球”。
那么,现在我们的表单已经填充好了,只需要把它提交给服务器了。
3filled_form<-set_values(form,search_text="流浪地球")#填写表单
4session2<-submit_form(session,form=filled_form)#提交表单
6session2$url#查看提交表单后,返回的新会话session2的url
7iconv(URLdecode(session2$url),"UTF8")#重新编码
6.项目
6.1
因为豆瓣网页元素层数比较多,所以必须使用SelecorGadget,审查元素后,右击进行复制,
通常可以选择selector或xpath,如图所示:
6path_comments<-paste0("#comments>div:nth-child(",
7as.character(1:20),
8")>div.comment>p>span")
10text_comments<-vector()#创建空向量
13comments_n<-read_html(x=url_movie)%>%
14html_nodes(css=path_comments[n])%>%
15html_text()%>%
16unlist()
17
18text_comments[n]<-comments_n
20
21print(text_comments[1])
爬取所有页,
通过手动点击下一页,发现页面url的规律,那就是start=n,n步长为20,初始值为20。
3as.character(seq(from=20,to=200,by=20)),
4"&limit=20&sort=new_score&status=P&percent_type=")
5for(min1:length(url_pages)){
8comments_mn<-read_html(x=url_pages[m])%>%
9html_nodes(css=path_comments[n])%>%
10html_text()%>%
11unlist()
12
13text_comments[m*20+n]<-comments_mn
14}
16}
19#保存为txt文件
20write.table(x=text_comments,
22quote=FALSE,sep="n",row.names=TRUE,
23qmethod="double",fileEncoding="UTF-8")
6.2
分词并计算词频
2library(jiebaR)
3library(dplyr)
4library(readr)
5library(magrittr)
7#读取要分词的文本
9encoding="UTF-8")
11#分词
12##导入停止词
13setwd("E:/R_input_output/data_input/jiebaR_documents")
14wk<-worker(stop_word="sea.txt")
15split_1<-segment(text_comments,wk)
16split_combined<-sapply(split_1,function(x){paste(x,collapse="")})#空格分割
18#计算词频
19comments_freq<-freq(split_combined)
20##去除数字
21comments_freq<-comments_freq[!grepl(pattern="^d$",comments_freq$char),]#逻辑索引
22##排序并取前300个
23comments_freq%<>%arrange(desc(freq))%>%.[1:300,]
6.3
词云图
安装方式:
devtools::install_github("lchiffon/wordcloud2")。
目前wordcloud2()绘制的图自动保存比较困难,还是截图吧。
1library(wordcloud2)
3letterCloud(comments_freq,word="6",wordSize=4,color="red")