R语言数据抓取实战——RCurl+XML组合与XPath解析
优采云 发布时间: 2022-05-10 07:36R语言数据抓取实战——RCurl+XML组合与XPath解析
杜雨,EasyCharts团队成员,R语言中文社区专栏作者,兴趣方向为:Excel商务图表,R语言数据可视化,地理信息数据可视化。个人公众号:数据小魔方(微信ID:datamofang),“数据小魔方”创始人。
经常有小伙伴儿跟我咨询,在使用R语言做网络数据抓取时,遇到空值和缺失值或者不存在的值,应该怎么办。
因为我们大多数场合从网络抓取的数据都是关系型的,需要字段和记录一一对应,但是html文档的结构千差万别,代码纷繁复杂,很难保证提取出来的数据开始就是严格的关系型,需要做大量的缺失值、不存在内容的判断。
如果原始数据是关系型的,但是你抓取来的是乱序的字段,记录无法一一对应,那么这些数据通常价值不大,今天我以一个小案例(跟昨天案例相同)来演示,如何在网页遍历、循环嵌套中设置逻辑判断,适时的给缺失值、不存在值填充预设值,让你的爬虫代码更稳健,输出内容更规整。
加载扩展包:
#加载包:<br />library("XML")<br />library("stringr")<br />library("RCurl")<br />library("dplyr")<br />library("rvest")<br />#提供目标网址链接/报头参数<br />url% xpathSApply(.,"//span[@class='category']/span[2]/span | //p[@class='category']/span[@class='labled-text'] | //div[@class='category']",xmlValue) %>% c(category,.)<br /> ###提取作者/副标题/评论数/评分/价格信息:
author_text=subtitle_text=eveluate_nums_text=rating_text=price_text=rep('',length)<br /> for (i in 1:length){<br /> ###提取作者
author_text[i]=content %>% xpathSApply(.,sprintf("//li[%d]//p[@class]//span/following-sibling::span/a | //li[%d]//div[@class='author']/a",i,i),xmlValue) %>% paste(.,collapse='/')<br /> ###考虑副标题是否存在
if (content %>% xpathSApply(.,sprintf("//ol/li[%d]//p[@class='subtitle']",i),xmlValue) %>% length!=0){
subtitle_text[i]=content %>% xpathSApply(.,sprintf("//ol/li[%d]//p[@class='subtitle']",i),xmlValue)
}<br /> ###考虑评价是否存在:
if (content %>% xpathSApply(.,sprintf("//ol/li[%d]//a[@class='ratings-link']/span",i),xmlValue) %>% length!=0){
eveluate_nums_text[i]=content %>% xpathSApply(.,sprintf("//ol/li[%d]//a[@class='ratings-link']/span",i),xmlValue)
}<br /> ###考虑评分是否存在:
if (content %>% xpathSApply(.,sprintf("//ol/li[%d]//div[@class='rating list-rating']/span[2]",i),xmlValue) %>% length!=0){
rating_text[i]=content %>% xpathSApply(.,sprintf("//ol/li[%d]//div[@class='rating list-rating']/span[2]",i),xmlValue)
}<br /> ###考虑价格是否存在:
if (content %>% xpathSApply(.,sprintf("//ol/li[%d]//span[@class='price-tag ']",i),xmlValue) %>% length!=0){
price_text[i]=content %>% xpathSApply(.,sprintf("//ol/li[%d]//span[@class='price-tag ']",i),xmlValue)
}
}<br /> #拼接以上通过下标遍历的书籍记录数
author=c(author,author_text)
subtitle=c(subtitle,subtitle_text)
eveluate_nums=c(eveluate_nums,eveluate_nums_text)
rating=c(rating,rating_text)
price=c(price,price_text)
#打印单页任务状态
print(sprintf("page %d is over!!!",page))
}<br /> #构建数据框
myresult=data.frame(title,subtitle,author,category,price,rating,eveluate_nums)<br /> #打印总体任务状态
print("everything is OK")<br /> #返回最终汇总的数据框
return(myresult)
}
提供url链接并运行我们构建的抓取函数:
myresult=getcontent(url)
[1] "page 0 is over!!!"
[1] "page 1 is over!!!"
[1] "page 2 is over!!!"
[1] "page 3 is over!!!"
[1] "everything is OK"
查看数据结构:
str(myresult)
规范变量类型: <p>myresult$price% sub("元|免费","",.) %>% as.numeric()
myresult$rating