作者:鲁伟,热爱数据,坚信数据技术和代码改变世界。R语言和Python的忠实拥趸,为成为一名未来的数据科学家而奋斗终生。个人公众号:数据科学家养成记 (微信ID:louwill12)

第一篇戳:R语言爬虫系列1|HTML基础与R语言解析

第二篇戳:R语言爬虫系列2|XML&XPath表达式与R爬虫应用

第三篇戳:R语言爬虫系列3|HTTP协议

第四篇戳:R语言爬虫系列4|AJAX与动态网页介绍

第五篇戳:R语言爬虫系列5|正则表达式与字符串处理函数

通过前面几期的推送,小编基本上已经将R语言爬虫所需要的基本知识介绍完了。R虽然是以一门统计分析工具出现在大多数人印象中的,但其毕竟本质上是一门编程语言,对于爬虫的支持虽不如Python那样多快好省,但悉心研究一下总能做出一些让你惊喜的效果。

大约很早之前,小编就写过关于R语言爬虫新贵rvest的抓取介绍,之前说rvest+SelectGadgetor是结构化网页抓取的实战利器,大家的溢美之词不断。详情可见推文:

R语言爬虫利器:rvest包+SelectorGadget抓取链家杭州二手房数据

但网络爬虫这个江湖太险恶,单靠一招rvest行走江湖必然凶多吉少,一不小心碰到什么AJAX和动态网页凭仅掌握rvest的各位必定束手无策。本文小编就简单介绍下在用R语言进行实际的网络数据抓取时如何将动态数据给弄到手。

所谓动态网页和异步加载,在之前的系列4的时候小编已通过AJAX介绍过了,简单而言就是我明明在网页中看到了这个数据,但到后台HTML中却找不到了,这通常就是XHR在作祟。这时候我们就不要看原始的HTML数据了,需要进行二次请求,通过web开发者工具找到真实请求的url。下面小编就以两个网页为例,分别通过GET和POST请求拿到动态网页数据,全过程主要使用httr包来实现,httr包可谓是RCurl包的精简版,说其短小精悍也不为过。httr包与RCurl包在主要函数的区别如下所示:

GET请求抓取微信好友列表数据


很早之前圈子里就看到过用Python抓取自己微信好友数据的案例分享,今天便以微信网页版为例,探一探其网页结构。首先登录个人微信网页版,右键打开web开发者工具,下来一大堆请求:

简单找一下发现网页中的微信好友列表信息并没有呈现在HTML 中,大概可以断定微信好友数据是通过动态加载来显示的,所以直接定位到XHR中,经过几番尝试,结合右侧的preview,我们会发现大量整齐划一的数据,所以二次请求的url真的就是它了:

找到真正的url之后,接下来就是获取请求信息了,切换到Headers版块,Header版块下的4个子信息我们都需要关注,它们是我们构造爬虫请求头的关键。

从Header中我们可以看到该信息是通过GET方法请求得到的,General信息下的Request URL,Request Method, Status Code; Response Headers信息下的Connection, Content-Type; Request Headers信息下的Accept, Cookie, Referer, User-Agent以及最后的Query String Parameters都是我们需要重点关注的。

找到相应的信息之后,我们便可以直接利用httr包在R中构建爬虫请求:

#传入微信cookie信息Cookie <- “我的微信cookie”#构造请求头headers <- c('Accept'='application/json',             'Content-Type'='text/plain',                       'User-Agent'='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.  36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X Met aSr 1.0',                       'Referer'='https://wx.qq.com/',              'Connection'='keep-alive',             'cookie'=Cookie)

二次请求实际的url:

#实际请求的urlurl<-"https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?r=1507597918348&seq=0&skey=@crypt_ee7cd3e3_70091604da65a07600cfdca47b81cfaf"

GET方法单次执行请求:

#执行请求louwill <- GET(url,add_headers(.headers =headers))

响应结果如下:

-> GET /cgi-bin/mmwebwx-bin/webwxgetcontact?r=1507597918348&seq=0&skey=@crypt_ee7cd3e3_70091604da65a07600cfdca47b81cfaf HTTP/1.1-> Host: wx.qq.com-> Accept-Encoding: gzip, deflate-> Accept: application/json-> Content-Type: text/plain-> User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0-> Referer: https://wx.qq.com/-> Connection: keep-alive-> cookie: 我的微信cookie-> <- HTTP/1.1 200 OK<- Connection: keep-alive<- Content-Type: text/plain<- Content-Encoding: gzip<- Content-Length: 90977<- 

响应状态码为200,okay。

从响应中提取原始字符内容:

content(louwill)[1] "{\n\"BaseResponse\": {\n\"Ret\": 0,\n\"ErrMsg\": \"\"\n}\n,\n\"MemberCount\": 658,\n\"MemberList\": [{\n\"Uin\": 0,\n\"UserName\": \"weixin\",\n\"NickName\": \"微信团队\",\n\"HeadImgUrl\": \"/cgi-bin/mmwebwx-bin/webwxgeticon?seq=570002&username=weixin&skey=@crypt_ee7cd3e3_70091604da65a07600cfdca47b81cfaf\",\n\"ContactFlag\": 1,\n\"MemberCount\": 0,\n\"MemberList\": [],\n\"RemarkName\": \"\",\n\"HideInputBarFlag\": 0,\n\"Sex\": 0,\n\"Signature\": \"微信团队官方帐号\",\n\"VerifyFlag\": 56,\n\"OwnerUin\": 0,\n\"PYInitial\": \"WXTD\",\n\"PYQuanPin\": \"weixintuandui\",\n\"RemarkPYInitial\": \"\",\n\"RemarkPYQuanPin\": \"\",\n\"StarFriend\": 0,\n\"AppAccountFlag\": 0,\n\"Statues\": 0,\n\"AttrStatus\": 4,\n\"Province\": \"\",\n\"City\": \"\",\n\"Alias\": \"\",\n\"SnsFlag\": 0,\n\"UniFriend\": 0,\n\"DisplayName\": \"\",\n\"ChatRoomId\": 0,\n\"KeyWord\": \"wei\",\n\"EncryChatRoomId\": \"\",\n\"IsOwner\": 0\n}\n,{\n\"Uin\": 0,\n\"UserName\": \"@34c5cc09db0a616522f7ccc7309b1d29\",\n\"NickName\": \"微信支付... <truncated>

从结果中可以看出,微信好友列表的信息就被抓取下来了,数据信息非常杂乱,需要进一步清洗整理,小编这里重在展示GET请求获取动态网页数据(主要是懒)就不往下整理啦。

POST请求抓取网易云课堂数据


虽说动态网站数据请求也有GET方法的,但小编发现POST方法才是动态网页的主要的请求方式。受杜老师小魔方文章启发,小编也试一下这个网页上的效果。登录网易云课堂账号,右键开发者工具,直接定位到XHR,查找课程数据属于哪个url。通过尝试和preview,可以发现课程信息都被封装在一个studycourse.json的文件中:

跟GET请求方法一样,切换到Header版块后继续关注General等四个子信息,但POST请求下我们需要注意的一点是:POST请求下没有像GET请求一样的Query String Parameters,而是由Request Payload来构造请求头表单参数,这一点和GET方法大不相同。总而言之,在动态网页的HTTP请求中,如果是GET请求,请求头表单参数以name=value&name1=value1的形式直接附在url后面,如果是POST请求,请求头表单参数以相同的形式放在构造的表单体中,所以对于网易云课堂的数据请求在R中构造如下:

#构造请求头#这里小编没有登录账号,cookie就不要了headers <- c('Accept'='application/json',             'Content-Type'='application/json',                       'User-Agent'='ozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0',                       'edu-script-token'= '37aa682d1473455c8a77e6a4476e8f9e',             'Referer'='http://study.163.com/courses',              'Connection'='keep-alive')#POST请求需要构造请求头表单参数payload<-list(  'pageIndex'=1,  'pageSize'=50,   'relativeOffset'=0,  'frontCategoryId'=-1)

二次请求实际的url:

url <- "http://study.163.com/p/search/studycourse.json"

POST方法单次执行请求:

louwill2<-POST(url,add_headers(.headers =headers),body =payload, encode="json")

结果如下:

-> POST /p/search/studycourse.json HTTP/1.1-> Host: study.163.com-> Accept-Encoding: gzip, deflate-> Cookie: EDUWEBDEVICE=5d0eadccd2314c4d8bc6e758b8b23d4e; NTESSTUDYSI=d3d36984547a43d6924334ee6a184a08-> Accept: application/json-> Content-Type: application/json-> User-Agent: ozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0-> edu-script-token: 83de95a25f5d45eb84bfeff8ec334e15-> Referer: http://study.163.com/courses-> Connection: keep-alive-> cookie: 网易云课堂cookie-> Content-Length: 69-> >> {"pageIndex":1,"pageSize":50,"relativeOffset":0,"frontCategoryId":-1}

<- HTTP/1.1 200 OK<- Server: nginx<- Date: Tue, 10 Oct 2017 08:29:51 GMT<- Content-Type: application/json;charset=UTF-8<- Transfer-Encoding: chunked<- Connection: keep-alive<- Vary: Accept-Encoding<- Server-Host: hzayq-study-platform7<- Content-Encoding: gzip<- Response [http://study.163.com/p/search/studycourse.json]  Date: 2017-10-10 08:29  Status: 200  Content-Type: application/json;charset=UTF-8  Size: 71 kB

请求状态码200,也okay。

从响应中提取原始字符内容:

head(content(louwill2))$result$list[[39]]$result$list[[39]]$productId[1] 1002971001$result$list[[39]]$courseId[1] 1002971001$result$list[[39]]$productName[1] "英语知识点解析及小学单词带读"$result$list[[39]]$productType[1] 0$result$list[[39]]$startTime[1] -1$result$list[[39]]$endTime[1] 9.223372e+18$result$list[[39]]$description[1] "通过几分钟的微课片段,精讲中小学的英语知识点,让学生通过比较学习,把这些知识点编织成有系统的知识网。"$result$list[[39]]$provider[1] "中小学英语语法王"

跟前面一样,后续的数据处理与清洗小编就懒得弄啦。POST方法与GET方法略有区别,就是需要构造请求头表单参数。R语言针对动态网页抓取,使用RCurl/httr包,认真分析网页结构,一般都能搞定。

参考资料:

Automated Data Collection with R

R语言自动数据采集

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

公众号后台回复关键字即可学习

回复 R              R语言快速入门免费视频 
回复 统计          统计方法及其在R中的实现
回复 用户画像   民生银行客户画像搭建与应用 
回复 大数据      大数据系列免费视频教程
回复 可视化      利用R语言做数据可视化
回复 数据挖掘   数据挖掘算法原理解释与应用
回复 机器学习   R&Python机器学习入门

R语言爬虫系列6|动态数据抓取范例相关推荐

  1. R语言实现简单的网页数据抓取

    在知乎遇到这样一个问题. https://www.zhihu.com/question/26385408/answer/147009602 这是要爬取的内容的网页: R语言的代码的实现方式如下: #安 ...

  2. python中国大学排名爬虫写明详细步骤-Python爬虫--2019大学排名数据抓取

    Python爬虫--2019大学排名数据抓取 准备工作 输入:大学排名URL连接 输出:大学排名信息屏幕输出 所需要用到的库:requests,bs4 思路 获取网页信息 提取网页中的内容并放到数据结 ...

  3. 网络爬虫——中国大学排名数据抓取

    网络爬虫--中国大学排名数据抓取 目标网址 中国大学排名网:http://www.zuihaodaxue.com/zuihaodaxuepaiming2019.html 全球有很多份大学排名,这里以上 ...

  4. 如何用python抓取文献_浅谈Python爬虫技术的网页数据抓取与分析

    浅谈 Python 爬虫技术的网页数据抓取与分析 吴永聪 [期刊名称] <计算机时代> [年 ( 卷 ), 期] 2019(000)008 [摘要] 近年来 , 随着互联网的发展 , 如何 ...

  5. Python学习笔记——爬虫原理与Requests数据抓取

    目录 为什么要做网络爬虫? 通用爬虫和聚焦爬虫 HTTP和HTTPS 客户端HTTP请求 请求方法 HTTP请求主要分为Get和Post两种方法 常用的请求报头 1. Host (主机和端口号) 2. ...

  6. python实现食品推荐_通过Python语言实现美团美食商家数据抓取

    首先,我们先来打开美团美食商家页面,来分析一下. 如上面所提供的URL即为美团美食商家页面.或者我们通过美团官网打开一个美团美食商家页面,打开步骤如下:1.打开浏览器,输入 即可打开美团北京首页 2. ...

  7. 基于Python爬虫的股票成交量数据抓取分析系统

    目录 数据获取 2 1.1. 实验环境搭建 2 1.2. 抓取数据 2 1.2.1. 新浪财经 3 1.2.2. 网易财经 6 1.2.3. 东方财富 12 1.2.4. TuShare (挖地兔) ...

  8. 爬虫_app 4 app数据抓取入门

    一.python实现app数据抓取需求 1.分析豆果美食数据包 2.通过python多线程-线程池抓取数据 3.通过使用代理ip隐藏爬虫 4.将数据保存到 mongodb 中 handle_mongo ...

  9. 爬虫的原理和数据抓取

    为什么要做爬虫? 都说现在是"大数据时代",那数据从何而来? 企业产生的用户数据:百度指数.阿里指数.TBI腾讯浏览指数.新浪微博指数 数据平台购买数据:数据堂.国云数据市场.贵阳 ...

  10. R语言爬虫系列(1)XML抓取表格数据

    使用XML抓取表格数据 install.packages("XML") trying URL 'https://cran.rstudio.com/bin/windows/contr ...

最新文章

  1. Android仿QQ列表滑动弹出按钮、长按提示、刷新列表
  2. 如何使用加密的Payload来识别并利用SQL注入漏洞
  3. 设备 esp32_ESP32-S2 SoC、模组、开发板全面上市
  4. linux网络编程系列-select和epoll的区别
  5. 面象对象设计6大原则之二:开放封闭原则
  6. iscsi-分区类型
  7. python使用大漠插件进行脚本开发的尝试(一)
  8. c#操作access,update语句不执行的解决办法
  9. Ant Design Pro引入Echarts 报错Unexpected token
  10. 洛谷P1982 小朋友的数字
  11. 【证明】两个自变量的二阶线性方程经过可逆变换后方程的类型不会改变
  12. 用单片机c51电子秤的c语言,原创基于51单片机的电子秤设计 带源代码,原理图毕业设计论文...
  13. TIA WinCC Professional入门经典
  14. uni-app实现问卷调查试卷
  15. ADSL拨号代理服务器实现HTTP代理的搭建过程
  16. 微信小程序用户隐私保护指引设置怎么填?
  17. 马云被骗十亿?最后却被百倍奉还。
  18. Redis解决高并发(秒杀抢红包)
  19. win10添加打印机--无法访问指定设备,路径或文件。。
  20. python常见几种设计模式

热门文章

  1. 这封“领导痛批95后下属”的邮件,句句扎心!
  2. 成都女学霸高考 692 分想当“程序媛”,网友:快劝劝孩子
  3. Java 9 新特性,看这里就明白了
  4. 为什么领导们总是劝大家不要只盯着工资?
  5. 2万亿市值公司的网络运营技术解密
  6. 数据库高可用实战案例——架构优化之清爽一夏
  7. 虚拟机克隆后没有IP
  8. better-scroll插件 api
  9. sql server concat()函数
  10. UPDATE INNER JOIN 两表联合更新