R语言网络数据抓取的又一个难题,终于攻破了!

转载 2018年01月03日 00:00:00


本文作者:杜雨,EasyCharts团队成员,R语言中文社区专栏作者。
兴趣方向:Excel商务图表,R语言数据可视化,地理信息数据可视化。
个人公众号:数据小魔方(微信ID:datamofang) ,“数据小魔方”创始人。



往期案例数据请移步本人GitHub:
https://github.com/ljtyduyu/DataWarehouse/tree/master/File

单纯从数据抓取的逻辑来讲(不谈那些工程上的可用框架),个人觉得R语言中现有的请求库中,RCurl和httr完全可以对标Python中的urllib和reuqests(当然py中在错误处理和解析框架上显得更为专业!)。

我们经常使用的网络数据抓取需求,无非两种:

  • 要么伪造浏览器请求

  • 要么驱动浏览器请求

对于伪造浏览器请求而言,虽然请求定义里有诸多类型,但是实际上爬虫用到的无非就是GET请求和POST请求。

而驱动浏览器就几乎没有什么门槛了,所见即所得,R语言中的RSelenium/Rwebdriver和Python中的Selenium都可以完成(配置比较麻烦一些)。

实习僧招聘网爬虫数据可视化

GET请求的参数允许写在URL里,但是通常参数较多的情况下,直接拼url显得非常不优雅,而RCurl,httr都提供了可选的GET请求提交方式。在RCurl里,getURL通常用来完成不含参数的GET请求(或者参数直接拼在了URL里),而getForm()函数通常用来完成含有参数的GET请求。(参数写在param参数体中)。

左右用R右手Pyhon系列——趣直播课程抓取实战

R语言爬虫实战——知乎live课程数据爬取实战

httr中的GET函数同样完成GET请求,query参数作为指定的请求参数提交方式(同样可以选择写在URL里)。

针对POST请求而言,作为API的普遍请求方式(也有一部分API是通过GET请求发送的),POST请求灰常复杂,它的查询参数必须含在请求体(body)中,而且参数发送前需要做指定的编码方式(就是request header中的content-type)。

长见的编码方式有4种:

  • application/x-www-form-urlencoded

  • application/json

  • multipart/form-data

  • text/xml

如果你想深入理解这四种方式,可以参考以下两篇文章,或者去看专业的http协议与浏览器相关内容。

http://www.cnblogs.com/111testing/p/6079565.html
https://bbs.125.la/thread-13743350-1-1.html


以上四种参数,我只实践过前两种,第三种需要上传文件,暂未遇到,第四种很少见。在RCurl包的POST函数中,只针对第一种、第三种做了显式的参数声明
style=httppost、post,但是第二种、第四种style参数中没有列举到。而httr在参数处理上显得非常友好,直接指定了以上常见的四种方式:

左手用R右手Python系列——模拟登陆教务系统

R语言爬虫实战——网易云课堂数据分析课程板块数据爬取

要知道如今web前端中,使用json作为数据包返回的api实在是太普遍了,这个问题一直困扰着我,甚至一度认为RCurl包的POST方法不支持上传json参数(可是RCurl是直接对接liburl这个通用的爬虫C语言库的,urllib也是,httr底层是用了RCurl的,httr能做到的RCurl自然不在话下)。

一定是作者把上传json参数的方式隐藏了起来,或者是还没有来得及封装成高级函数,放在了底层,否则解释不通。直到今天,浏览了linkedlin上面的一个大神写的小品文,突然灵光乍现,赶紧一试,果然成功了!验证了之前的想法,可能RCurl刚出道的时候,json还没有成主流吧,所以json传参没有明显的放在style这个POST方法的参数里。而httr包则很讨巧的把所有POST参数的编码方式都声明了(哈德利大神就是快人一步,造福人类)。http://www.linkedin.com/pulse/web-data-acquisition-structure-rcurl-request-part-2-roberto-palloni

以下是写作本篇推送的目地,把利用RCurl包构造POST请求,以及提交json字符串参数的案例及代码分享给大家。RCurl库与httr相比,偏底层,函数多且繁琐,httr更灵巧、轻便、简洁。这种关系,像极了Python中的urllib和request。

构建报头和查询参数:

library("RCurl")
library("jsonlite")
library("magrittr") headers<-c(  "User-Agent"="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36",  "Content-Type"="application/json;charset=UTF-8",  "Origin"="http://study.163.com",  "edu-script-token"="3de0ac05e45a4c9693f2a3605fbfaede") Cookies<- 'EDUWEBDEVICE=0e88ed7a9b8b4fc4bfc615e251aa8863; _ntes_nnid=833311d30eccaa9f26425affae2cfef1,1509630974190; _ntes_nuid=833311d30eccaa9f26425affae2cfef1; STUDY_CP_ENTRANCE_CLOSE=1; STUDY_MIND_TELBIND_CLOSE=1; promTips=1; NTESSTUDYSI=3de0ac05e45a4c9693f2a3605fbfaede; STUDY_INFO=oP4xHuM9V1uY_TRID1ZzHOm5mkJY|6|12769628|1510452481337; STUDY_SESS="ryW1kbDYUPDpeexx7xnRK3cGH1nUulhhGJ9D1qIzrgCuSgHl96KRz9xVAwMO6jui9A7L4BJ6hUaaPXVtLf+pWBMHJEw6UtuJtXPjl2yhevq6wVYQtAaJ+N+2maA3kITUrUnNZE+nE0TmYBoQFSEgOKEjUu22o4FQQjD/GeyPrqJsX8TS4muhOF/kd9duGihHABYarJu/gx1XyYYhTqa89g=="; STUDY_PERSIST="8e2epkzTa+8Xy6agY2FPkUzktd9F+8CZ1rZxShzQSSRJ6RbRK2pSzoTqPic7hOB7dYsCtyfpIAD9Ue4S1oRerMBML+fd8iksmANh7THsUTBAXY6WM4kHXJFcNuERKuWuDeHOMilu1y+7T3/a7Jav0QPXrTaWx6YerFKJia2+3rEucY6CQ9waCFR9bhYObYkE6X9kJ71ahCvMYtkr9eXcE6s1rFdKOIgMEtQwxl1Jb8oli9XIBhsosLWHLIUZIfzGwHfmjuVpkfHAfiCIxUJfLiv82sP6EP+Q6n6O/pIeGx0="; STUDY_MIND_TELBIND=1; NETEASE_WDA_UID=12769628#|#1451204764916; NTES_STUDY_YUNXIN_ACCID=s-12769628; NTES_STUDY_YUNXIN_TOKEN=da46d92b7a9504736f2534ed1d366296; STUDY_NOT_SHOW_PROMOTION_WIN=true; utm="eyJjIjoiIiwiY3QiOiIiLCJpIjoiIiwibSI6IiIsInMiOiIiLCJ0IjoiIn0=|aHR0cDovL3N0dWR5LjE2My5jb20vY291cnNlcy1zZWFyY2g/a2V5d29yZD0lRTUlODglOTglRTUlODclQUY="; __utma=129633230.621520113.1509630968.1510452483.1510452504.13; __utmb=129633230.12.9.1510455608393; __utmc=129633230; __utmz=129633230.1509630968.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)'headers['Cookie']<-Cookies Payloads=list(
       "pageIndex"=1,
       "pageSize"=50,
       "relativeOffset"=0,
       "frontCategoryId"="400000000158033",       "searchTimeType"=-1,
       "orderType"=0,
       "priceType"=-1,
       "activityId"=0        )

构建自动抓取函数:

GetCourses<-function(url,header=headers,Payload=Payloads){
    fullinfo <- data.frame()
    d <- debugGatherer()
    handle <- getCurlHandle(debugfunction=d$update,followlocation=TRUE,cookiefile="",verbose = TRUE)
   for (i in 1:17){        Payload[['pageIndex']]=i        Payload[['relativeOffset']]=50*i-50        tryCatch({        content  <- postForm(url,.opts=list(postfields=toJSON(Payload,auto_unbox=TRUE),httpheader=header),.encoding="utf-8",curl=handle)
       ###通过将post需求提交的参数编码为json字串,封装在postForm函数的配置参数.opts中,完成json查询参数的传递!,
###竟然不写在style里,搞得人晕头转向的!注意使用toJSON序列化的时候,auto_unbox要设置为TRUE,否则默认为TRUE,单值都会被包括成列表!
       response <- content  %>% fromJSON() %>% `[[`(3) %>% `[[`(2)        fullinfo <- response %>% rbind(fullinfo,.)          cat(sprintf("第【%d】页已抓取完毕!",i),sep = "\n")        },error = function(e){        cat(sprintf("第【%d】页抓取失败!",i),sep = "\n")        })        Sys.sleep(runif(1))    }    cat("all page is OK!!!")
   return (fullinfo) }
#运行函数
url<-'http://study.163.com/p/search/studycourse.json'
myresult<- GetCourses(url)

#预览数据
DT::datatable(myresult)

至此,R语言中的两大数据抓取神器(请求库),RCurl+httr,针对主流的GET请求、POST请求(常用的)都已经完成探索和案例输出。以后的案例会不断补充一些高级的反反爬技巧!

备注:以上header中的cookie是防止请求被浏览器屏蔽,edu-script-token参数是进程的token,你可以理解为类似秘钥的东西,所以如果想要实践本篇内容,以上两个参数需要你从自己的Chrome中提取,直接运行本篇代码估计不大可能出数据!

相关课程推荐


R语言爬虫实战案例分享:

网易云课堂知乎live、今日头条、B站视频


分享内容:本次课程所有内容及案例均来自于本人平时学习练习过程中的心得和笔记总结,希望借此机会,将自己的爬虫学习历程与大家分享,并为R语言的爬虫生态改善以及工具的推广,贡献一份微薄之力,也是自己爬虫学习的阶段性总结。

☟☟☟ 戳阅读原文,即刻加入课程。

R语言blotter包及相关工具

1 blotter简介 (a) 简介 blotter依然是一个正在开发中的包,是TradeAnalytics项目的一部分,主要作者是Peter Carl,Brian Peterson。 http...
  • troubleisafriend
  • troubleisafriend
  • 2015年08月26日 19:02
  • 1407

R语言爬虫实战:知乎live课程数据爬取实战

杜雨,EasyCharts团队成员,R语言中文社区专栏作者,兴趣方向为:Excel商务图表,R语言数据可视化,地理信息数据可视化。个人公众号:数据小魔方(微信ID:datamofang) ,“数据小魔...
  • kMD8d5R
  • kMD8d5R
  • 2017年12月21日 00:00
  • 298

今晚我准备用R语言爬下这几个视频网站!

今晚20:00~22:00R语言带你飞!导言网络数据抓取是数据科学中获取数据中的重要途径,但是一直以来受制于高门槛,都是专业程序员的专属技能。直到R语言和Python这种函数式编程语言的兴起,爬虫技能...
  • kMD8d5R
  • kMD8d5R
  • 2018年01月15日 00:00
  • 641

网络数据抓取

http://www.dataguru.cn/article-3717-1.html   炼数成金《数据分析,展现与R语言》课程 http://blog.sina.com.cn/s/blog_4...
  • TheoGo
  • TheoGo
  • 2016年02月10日 10:29
  • 2227

钻木取火完全攻略——不再是纸上谈兵…

本文转自:http://potmot.blog.sohu.com/90801153.html        在真正成功地钻木取火之前,从许多资料上面见到许多有用没用的方法。许多方法在动手实践之前就...
  • rxm1989
  • rxm1989
  • 2014年09月25日 13:31
  • 604

全球最火的R工具包一网打尽,超过300+工具,立马收藏!

最近在网上到处了解和爬一些R的资料,看着看着就入迷了,这就是个大宝库了,以前怎么没发现,看来还是太狭隘了。直到前几天我看到这个Awesome R文档,我就静不下来了,对比了目前自己的工作和以后的方向,...
  • chenjunji123456
  • chenjunji123456
  • 2017年02月16日 16:59
  • 1056

左手用R右手Python系列——模拟登陆教务系统

杜雨,EasyCharts团队成员,R语言中文社区专栏作者,兴趣方向为:Excel商务图表,R语言数据可视化,地理信息数据可视化。个人公众号:数据小魔方(微信ID:datamofang) ,“数据小魔...
  • kMD8d5R
  • kMD8d5R
  • 2017年12月01日 00:00
  • 54

R金融数据分析之quantmod包抓取股票行情数据小例子

本博文是利用quantmod包中的ETL函数下载Apple,Microsoft,Oracle,Google四家公司全票行情数据,并进行简要...
  • jiabiao1602
  • jiabiao1602
  • 2014年09月08日 09:33
  • 7464

R语言:网页抓取之get the data

前言            题记–任何一个数据挖掘工程师都应该有对数据的热情   网络上的数据是免费的,是无限的,是有无穷价值的,关键看你怎么去挖掘。为了财富,为了生活,要挖,在挖之前要先爬。  ...
  • yujianmin1990
  • yujianmin1990
  • 2015年09月12日 18:21
  • 4061

用R语言进行复杂网络可视化

复杂网络简介 现实世界中,网络世界大量存在,铁路线路网络,航空网络,人际关系网络。复杂网络是大量真实复杂系统的拓扑关系。借助复杂网络分析,我们期望可以化繁为简,找到隐藏的拓扑关系新结构,找到节点与节...
  • u010560831
  • u010560831
  • 2016年11月07日 19:34
  • 3678
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:R语言网络数据抓取的又一个难题,终于攻破了!
举报原因:
原因补充:

(最多只允许输入30个字)