本文是天善智能签约讲师 杜雨老师的课程Hellobi Live |2018年1月15日 R语言爬虫实战案例分享:网易云课堂、知乎live、今日头条、B站视频 课件,未经允许,禁止转载。
推荐课程:
R语言爬虫实战案例分享:网易云课堂、知乎live、今日头条、B站视频
•天善商业智能和大数据社区——讲师(数据可视化方向) – 杜雨
•天善社区 ID - datamofang
•https://www.hellobi.com – 学习过程中有任何相关的问题都可以提到技术社区R语言板块(或者个人主页)。
一、爬虫基础概念及基本流程 «««
二、网络请求基本类型及其详解 «««««
三、网页解析基本内容及语法详解 «««««
四、四大实战案例 ««
五、学习进阶建议 ««
基本概念:代替浏览器完成本地客户端与远程服务器端之间的信息交互
一般流程:构造并发送请求——接收并解析响应——数据转换与本地存储
2.1.1、URL结构
protocol :// hostname[:port] /path / [;parameters][?query]#fragment
Protocol(协议类型)网络协议类型,最常用得如http/https、ftp等
hostname(主机名)
port(端口号)默认80端口,一般不会显示出来
path(路径)表示主机上的一个目录或文件地址
query(查询)传递参数,可有多个参数,用“&”符号隔开,每个参数的名和值用“=”符号隔开。
http://music.163.com/store/newalbum/detail?id=37084145
2.1.2、URL特征
query(查询) URL中的参数对,以?开始,以&号隔开的键值对,键与值之间以=号相连
•GET请求中的URL有字符长度限制
•GET请求在构造时,查询参数可以直接携带在URL中,也可以单独添加在参数体中
•查询参数中若含有多字节字符串(如中文字符)需要进行编码(urlencode过程)
http://study.163.com/courses-search?keyword=%E5%88%98%E5%87%AF
2.1.3、URL编码
浏览器中发送请求使用的url必须进行百分号转码,web服务器端才能成功识别,所以在发送请求时,针对url我们需要了解其转码机制,知道如何进行编码/逆编码
library("magrittr")
library("xml2")
URL<-"https://www.aqistudy.cn/historydata/monthdata.php?city=北京"%>% url_escape(reserved ="][!$&'()*+,;=:/?@#")
url_unescape("https://www.aqistudy.cn/historydata/monthdata.php?city=%E5%8C%97%E4%BA%AC")
2.1.4、一个典型的GET请求构成
•指定请求方式:——GET
•指定请求的目标——URL【若查询参数包含在url中且含有非asci字符,需要执行urlencode】
•指定请求的报头
请求报头中一般包含有本地客户端的属性信息、提交请求参数的类型,请求的目标资源以及期望获取的内容格式,以及cookies登录信息等。
•请求的参数体(可选)
请求的查询参数,可以直接携带在url中,但是通常可以单独构造在查询请求体中,这样对于循环中遍历比较方便
POST请求的构成与GET请求比较相似,但也有不同
•请求的URL没有字符串长度限制
•请求的查询参数不包含在url中,一般需要构造单独的参数体中(区别于GET请求)
•请求的报头参数与GET请求格式一致(具体参数可能略有差异)
常见的POST的请求类型:
•application/x-www-form-urlencoded 原生 form 表单,浏览器的默认数据提交方式
•multipart/form-data 将本地文件作为请求的参数提交
•application/json 以json字符串序列的格式上传表单参数
•text/xml 以xml格式上传表单参数
2.3.1、Chrome后台开发者工具
目标url——hellobi.com
进入Chrome浏览器后台开发者工具的方式
按F12或者在目标页面右键单击,进入检查元素菜单
2.3.1、Chrome后台开发者工具
2.3.1、Chrome后台开发者工具
核心要点1——如何区分动态网页与静态网页?
•观察目标网站上的页面布局,如果含有下拉菜单、滚动条、页面底部滑动加载、多页标签,很可能是异步加载方式。
•异步加载的动态网页,点击下一页,只会更新页面局部数据,不会引起整个网页重新载入。
•点击下一页,网页位从新加载,且url链接始终不变,仅有局部模块展示区内容更新。
核心要点2——如何发现数据抓取的目标链接?
•通常情况下,在network模块的all页面内,你可以找到所有的资源请求目录。
•倘若资源太多,不易察觉,过滤掉所有的js脚本文件、css层叠样式,只关注那些带有命名参数对的链接(?name1=value1&name2=value2)
•如果确定数据存放在html文档中(普通的静态网页),直接去doc模块找,如果确定是xhr模式加载,直接在xhr模块查找
2.3.1、Chrome后台开发者工具
核心要点3——如何确定查找的目标请求是否正确?
情形1——如果要找的是一个html文档,那么直接鼠标点开,
查看右侧文档预览,使用Ctrl+F查找网站页面元素,确认是否存在。
情形2——如果要找的是一个XHR链接,那么在xhr模块查找符合条件的资源链接,在右侧预览窗口查看是否存在目标内容。
http://study.163.com/courses-search?keyword=刘凯
2.3.1、Chrome后台开发者工具
核心要点4——异步加载链接的一般特征(可以在all模块查找,或者直接去xhr模块查找)?
情形1:链接中带有键值对的参数结构,以?号开始,以&号隔开,键值对用等号表示。
情形2:链接中含有关键词API或链接以.json结尾
核心要点5——get/post请求与普通静态加载/异步加载方式之间是否存在一一对应关系?
没有必然联系,也就是说静态网页可以是以get请求发送,也可以是以post请求格式发送。
但是通常来讲,静态网页多以get请求方式发送,异步加载链接多以post请求发送。
一个典型的GET请求结构信息
一个典型的POST请求结构信息
2.4.1、GET请求构造(RCurl+httr)
请求url ——https://www.hellobi.com/jobs/search
请求报头参数:
headers <- c(
"Referer"="https://www.hellobi.com/jobs/search",
"User-Agent"="Mozilla/5.0(Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/61.0.3163.79 Safari/537.36"
)
请求查询参数
params <- list(
"page" = 1
)
Rcurl——getForm(url,.params = params,.opts=list(httpheader=headers), curl=handle ,.encoding="utf-8")
httr ——GET(url, query = params, add_headers(.headers =header), handle=h)
2.4.2、POST请求构造(RCurl+httr)
请求url ——http://study.163.com/p/search/studycourse.json
请求报头参数:
headers <- c(
"Content-Type" = "application/json",
"edu-script-token" ="73d073acfeea4d89aeb3b9f4eb991497",
"Origin" = "http://study.163.com",
"User-Agent" = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/61.0.3163.79 Safari/537.36"
)
请求查询参数
Payload=list(
"activityId" = 0,
"keyword" = "刘凯",
"orderType" = 5,
"pageIndex" = 1,
"pageSize" = 20,
"priceType" = -1,
"searchTimeType" = -1
)
Rcurl—— postForm(url,.opts = list(postfields=toJSON(Payload,auto_unbox=TRUE),httpheader=headers),curl=handle ,.encoding="utf-8")
httr ——POST(url,add_headers(.headers =headers),body =Payload,encode="json",verbose())
3.1、json与xml数据结构
3.2、Xpath公式\css表达式
3.3、快捷高阶函数(readtable、readlists、getlinks)
3.4、二进制文件下载(pdf\jpg\mp3\mp4)
3.5、关系表入库(MYSQL)
3.6、list解析与非结构化数据存储(mongoDB)
3.7、显式循环、向量化函数、并行运算在数据爬取中的效率对比
3.8、异常处理与循环跳出
•Xpath是专门从xml/html文档中提取内容或者数据信息的通用语言,常用在解析xml/html解析、动态页面中的网页元素操控等场合。
•CSS原本是用于html代码中的元素修饰和页面优化的样式层叠表,相当于一个专门美化html页面的美容宝典,这里提到的仅仅是CSS表达式,通过css路径表达式来定位网页元素,实现各种元素风格和布局的自定义。
这两种方式都可以从HTML文档中提取出有效信息,其中在R语言目前的现有的爬虫工具中,Xpath语法的支持度更广、更普遍,比较经典的解析包XML包只支持Xpath语法,而比较年轻的解析xml2包则增加了对css表达式的支持(内部是通过selectr包中转换函数将css表达式转化为Xpath之后再执行解析的),也可以说R语言现有的爬虫工具中,几乎没有公开的支持CSS表达式的包。
关于Xpath\CSS表达式基本语法介绍
解析HTML/XML文档时,我们仅仅对其中的三个对象感兴趣:
1、节点(或者节点集合)
2、节点内文本值
3、节点标签值
所以无论是使用XML包作为解析工具还是使用xml2包进行解析,核心要点都是掌握以上三种需求的表达式写法:
关于工具组合:
Xpath/CSS语法讲解(2):
Xpath/CSS语法讲解(3):
数据抓取中如何处理异常
•tryCatch
for(i in 1:length(urls)){
tryCatch({
download.file(i,basename(i), mode = "wb")
cat(sprintf("正在下载文件【%s】",i),sep = “\n”)
},error = function(e) {
cat(sprintf("文件【%s】地址无效,继续下一个!",i),sep = “\n”)
})
Sys.sleep(runif(1))
}
sessionInfo()
#R version 3.4.3 (2017-11-30)
#Rstudio version 1.1.383
#Platform: x86_64-w64-mingw32/x64(64-bit)
#Running under: Windows >= 8 x64(build 9200)
Plantomjs: Plantomjs V2.1
Selenium:selenium-server-standalone-3.3.1.jar