【R分享|实战】利用rvest包编写简单的静态网页爬虫

把梦想藏在秋风中,闯过灯火阑珊。"R实战"专题·第21篇编辑 | 明允  5160字 |13分钟阅读本期推送内容一次有趣的尝试:在学习《基于R语言的自动数据收集》过程中,对HTML文件与各类R语言爬虫包(XML包、rvest包、Rcrawler包、Rseleuium包)有了大致的了解。在浏览知乎的一个专栏时,我发现里面的图片都很有意思,但手动一张一张地下载未免太过麻烦,便着手写一个爬虫程序批量下载这些图片,刚好rvest包就可以满足这个需求。实际上,只要设定好正确的抓取取规则,爬虫便可以自动的抓取网页上的各类信息数据,可以极大地提高我们的工作效率。今天的主要内容便是介绍爬虫的基本知识,并通过两个小案例介绍R语言如何爬取静态网页中的信息、图片内容。01什么是网络爬虫1)网络爬虫:网络爬虫又叫网页蜘蛛,网页机器人,是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本,我们可以把它理解成一种自动搜索引擎。它可在多种编程语言中实验,例如Java、Python、R语言等等。2)爬取静态网页的基本流程:在这之前,我们要了解:什么是静态网页,如何分辨静态网页?顾名思义,静态网页可以理解为内容基本固定,不会改变的网页。它的网页中没有程序代码,每个静态网页都是一个独立的HTML文件,所有的内容都储存在服务器中原始的HTML文件里,网页URL多以.htm、.html、.xml、.xhtml等形式为后缀。与之对立的便是动态网页了,所谓 “ 动态 ” ,并不是指网页上简单的 GIF 动态图片或是 Flash 动画。制作者在动态网页中嵌套了程序,将更新较快的信息内容与网页框架分离并储存在数据中,方便网页根据需求进行调用。这样,我们浏览的每一个界面,自然不能与服务器中的某个HTML文件相对应。迄今为止,动态网页仍缺少一个统一的标准,我们可以观察到的是,动态网页URL多以.asp、.jsp、.php、.cgi等姓氏为后缀。通常来说,抓取动态网页内容的操作比抓取静态网页的内容更为繁琐复杂,正确的区分网页的类型十分重要。

在编写爬虫程序之前,我们要明确爬虫程序的步骤:a. 需要爬取的网页:起始URLb. 分析网页内容 :自己感兴趣的内容在网页中的哪个位置c. 提取感兴趣的部分d. 数据内容清洗 :爬取的数据容易带有多余的空格或"\n\t"等字符,需要后续整理02简单介绍rvest包rvest包是目前R用户中最流行的爬虫包,可以解决大部分的爬虫问题。主要函数:read_html()读取目标网页中的html文档,可以是线上的url,也可以是本地的html文件html_nodes()选择并提取html文档中目标元素html_attar()抓取指定属性的内容html_text()抓取标签内的文本html_table()解析网页数据表的数据到R的数据框中html_form( )抓取表单repair_encoding( ) 用来修复html文档在R读入后的乱码问题(在读取中文内容时特别常见)使用rvest抓取信息十分简单粗暴,一般分为三步:url<- "#网页网址" read_html(url) %>% #明确要抓取的内容与位置,并读入相应的html文件   html_nodes() %>% #通过相应的标签名,属性定位到该内容的位置   html_attar() 或 html_text() 提取目的信息,随后可以根据需求进行部分处理03爬取知乎专栏中的猫猫图现在让我们开始抓取知乎某个回答中的图片内容,指路:https://zhuanlan.zhihu.com/p/156799430library(rvest)library(downloader)library(tidyverse)url1<-"https://zhuanlan.zhihu.com/p/156799430"抓取的第一步是确定目标图片在网页文件中的定位,我们可以通过对比每张图片在html文件里的位置来找到他们整体的规律。首先,我们把鼠标光标放在第一张图片上,右键-检查:

可以发现,这张图片实际上位于右边第二个红色框<img src="https://pic1.zhimg.com/80/v2-3a8073d_1440w.jpg"......(等)>的节点中,这个节点分别提供了src与data-actualsrc两个链接,复制到浏览器中分别可以打开正常图片和原始图片。接下来,我们要确定第二张以及之后全部图片的位置,并取得所有图片的链接。

通过比对可以发现,几乎所有图片都储存在图中蓝框标出的<figure data-size="normal"></figure>中,而且图片链接都储存在src和data-actualsrc下。往上溯源,可以发现,所有的<figure></figure>都位于红框中的<div class="RichText ztext Post-RichText css-hnrfcf" option="[object Object]"></div>,就这样我们就定位到了所有图片链接的位置,就可以批量获得图片链接并下载它们了。link<- read_html(url1) %>%      html_nodes("div.RichText.ztext.Post-RichText.css-hnrfcf")%>% #所有图片的父级节点     html_nodes("img")%>% #通过img属性进一步定位     html_attr("data-actualsrc") #提取图片的下载链接

但这样获得的链接集合存在每隔一个都是空值的问题,需要进行相应的处理。link<-link[seq(2,length(link),by=2)] #按空值出现的规律去除所有的空值for(i in 1:length(link)){ download(link[i],paste0("猫猫",i,".gif"), mode = "wb")}

运行后就可以自动下载啦!(实际上并没有400张,只有119张图片)04爬取网页中的信息(以当当网为例)用rvest包爬取当当中R语言相关图书的基本信息(包括书名、作者、价格、出版日期、简介)。网址:http://search.dangdang.com/?key=R%D3%EF%D1%D4&act=inputgoods_url<- list()name<- list()author<- list()price<- list()press_date<- list()abstract<- list() #建立清单list通过比对翻页后的网址,我们可以发现,每页的网址都有一定的规律可言: 在 "index= "后填写一个数字就能跳转到相应的页数。

而经过对比,也能发现商品子网页链接储存在<p class=name></p>中的"a href"处,在爬虫中我们需要定位到这一级。for(i in c(1:5)){  url<-paste0("http://search.dangdang.com/?key=R%D3%EF%D1%D4&act=input&page_index=",i)  url1 <- read_html(url, encoding="GBK") %>%  html_nodes("div#search_nature_rg ul.bigimg p.name a") %>%   ##属性class一般用.代替,div class=a 写作 div.a  ##而id则用#代替, div id=a 写作 div#a  html_attr("href") #提取指定的子网页链接  goods_url<- c(goods_url, url1) #合并每一次循环的链接组}goods_url<- gsub("//","http://",goods_url) %>% data.frame() #因为得到的链接均不完整,因此用gsub()函数补齐: #将goods_url组里的“//”替换为“http://”由于html文件为嵌套式架构,在上文中的html_nodes()中,越靠前的节点范围越大。即<div id="search_nature_rg"></div>这一层嵌套了<ul class="bigimg"></ul>,而后者又嵌套了<p class="name"></p>。最终我们需要定位定位到p.name a,实际上因为所有子网页链接都储存在一系列的<p class="name"></p>中,使用html_nodes("p.name a")或html_nodes("p[class="name] a")均可定位到所需要的链接。运行后便可得到前5页中所有的子网页链接。

进入一个图书界面,找到储存书名、作者、出版时间、简介、价格这些信息的节点:

for(i in c(1:30)){  #当当网会检测访问者是否已登录,R语言想要下载全部内容需要用Rseleuinm包模拟登陆。  good<- as.character(goods_url[i,1]) book_name<- read_html(good, encoding = "GBK") %>% html_nodes("div.name_info h1") %>% html_text()book_author<- read_html(good, encoding = "GBK") %>% html_nodes("div.messbox_info span.t1#author") %>% html_text() book_price<- read_html(good, encoding = "GBK") %>% html_nodes("div.price_d p#dd-price") %>% html_text()book_press_date<- read_html(good, encoding = "GBK") %>% html_nodes("div.messbox_info span.t1:nth-child(2):nth-child(2)") %>% html_text() book_press_date<- data.frame(book_press_date)[1,1]book_abstract<- read_html(good, encoding = "GBK") %>% html_nodes("div.name_info h2 span.head_title_name") %>% html_text()name<- c(name, book_name) author<- c(author, book_author) price<- c(price, book_price) press_date<- c(press_date, book_press_date) abstract<- c(abstract, book_abstract)}name<- gusb("\n\t","",name) %>% as.vector(unlist())author<- gusb("\n\t","",author) %>% as.vector(unlist())price<- gusb("\n\t","",price) %>% as.vector(unlist())press_date<- gusb("\n\t","",press——date) %>% as.vector(unlist())abstract<- gusb("\n\t","",abstract) %>% as.vector(unlist())data<- data.frame(name,author,price,press_date,abstract)作者唠叨:rvest包操作比较简便,因此面对一些检测登陆或者是动态网页时会显得力不从心。实际上,想要完整的将当当网中的信息完全爬取出来需要在后台模拟浏览器登陆(用Rseleuinm或者Rwebdriver包可以实现这个过程),后期我们将再出一期如何搭建jdk与seleuinm框架,并利用RSelenium包或者Rwebdriver模拟登陆或爬取动态网页等难爬取的网页信息的推文。

(0)

相关推荐

  • 爬虫最怕遇到JavaScript依赖性的动态网页

    静态网站内容爬取,rvest.RCurl.XML这几个包都可以实现这个功能.比如下面的网页: http://vip.stock.finance.sina.com.cn/q/go.php/vInvest ...

  • 爬虫写完了,运行了,然后呢?

    爬虫这个东西,不是刚需,但是好玩,而且也是很多朋友圈彻底走入编程圈的第一推动力,我也亲自示范过很多有趣的爬虫示例: peerJ期刊探索  这个里面我介绍了R爬虫 生信职位拉勾网爬取-附生信行业职业发展 ...

  • 静态网页和动态网页

    本节我们了解一下静态网页和动态网页的相关概念.如果您熟悉前端语言的话,那么您可以快速地了解本节知识. 当我们在编写一个爬虫程序前,首先要明确待爬取的页面是静态的,还是动态的,只有确定了页面类型,才方便 ...

  • 如何批量采集网页表格数据?

    Comming Soon! Python&Stata数据分析课寒假工作坊 我们最想要的数据格式就是表数据,但这表格并不是excel文件,而是存在于网页上的表数据.比如本教程实验网站 http: ...

  • 伪静态

    URL伪静态通常是为了满足更好的SEO效果,ThinkPHP支持伪静态URL设置,可以通过设置URL_HTML_SUFFIX参数随意在URL的最后增加你想要的静态后缀,而不会影响当前操作的正常执行.例 ...

  • selenium爬虫操作网页(实战篇)

    前面我们遇到了一个爬虫难题:爬虫最怕遇到JavaScript依赖性的动态网页,选择了[在R里面配置selenium爬虫环境](),仅仅是安装和配置好了在R里面使用selenium爬虫,打开一个Java ...

  • 【R分享|实战】 新手福利~R包的安装与使用

    " 也许那是过去的你,你无法改变,但现在的你能够变得强大."   --科白君 "R实战"专题·第2篇   编辑 | 科白维尼   4445字 | 7分钟阅读 本 ...

  • 【R分享|实战】科白君浅谈ggplot2包学习逻辑

    " 量变学习,过程深思,总结完善,突破创新."   --科白君 "R分享实战"专刊·第11篇   编辑 | 科白维尼   2671字 | 7分钟阅读 本期推文内 ...

  • 【R分享|实战】如何用meta包实现meta分析

    " 不求做的最好,但求做的更好."   --科白君 "R实战"专题·第14篇   编辑 | 科白维尼   2742字 |5分钟阅读 本期推送内容 最近我正在收集 ...

  • 【R分享|实战】利用R绘制全球样点的地理信息图

    " 不求做的最好,但求做的更好."   --科白君 "R实战"专题·第18篇   编辑 | 科白维尼   1470字 | 3分钟阅读 本期推送内容 在做meta ...

  • 【R分享|实战】 跟着科白君学画散点图就对了~

    " 夯实基础,持之以恒."   --科白君 "R实战"专题·第1篇   编辑 | 科白维尼   5311字 | 9分钟阅读 本文推送内容 利用ggplot2包及 ...

  • 【R分享|实战】 科白君教你如何给散点图添加最优拟合曲线和相关性~

    " 每期小积累,分析学得美."   --科白君 "R实战"专题·第3篇   编辑 | 科白维尼   5854字 | 10分钟阅读 本期推送内容 只有空荡荡的散点 ...

  • 【R分享|实战】 新手福利~认识数据集的内在

    " 勤奋不是嘴上说说的.学习面前,主动是最基本的保证."   --科白君 "R实战"专题·第4篇   编辑 | 科白维尼   3811字 | 6分钟阅读 本期推 ...

  • 【R分享|实战】参数分析~T检验与方差分析

    " 只要感兴趣,学习就是快乐的."   --科白君 "R分享实战"专刊·第6篇   编辑 | 科白维尼   3348字 | 5分钟阅读 本期推送内容 上一期与大 ...

  • 【R分享|实战】科白君教你相关性分析及其绘图

    "R实战"专题·第7篇   编辑 | 科白维尼   1898字 | 4分钟阅读 本期推送内容 相关性分析通常用来定量描述两个变量之间的联系,正相关?负相关?不存在相关?等.常见相关 ...