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

作者: 天善智能 | 来源:发表于2017-11-27 15:09 被阅读35次

感谢关注天善智能,走好数据之路↑↑↑

欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!

本文作者:天善智能社区专家dwzb

天善智能社区地址:https://www.hellobi.com/

第一篇戳: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:

#实际请求的url

url<-"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\": \"微信支付...

从结果中可以看出,微信好友列表的信息就被抓取下来了,数据信息非常杂乱,需要进一步清洗整理,小编这里重在展示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语言爬虫系列6|动态数据抓取范例

    感谢关注天善智能,走好数据之路↑↑↑ 欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领...

  • R爬虫实践—抓取国自然基金信息【下篇】

    R爬虫实践—抓取国自然基金信息【上篇】和R爬虫实践—抓取国自然基金信息【中篇】都是对国自然数据的局部抓取,突然发现...

  • 无标题文章

    一、"大数据时代",数据获取的方式: 二、什么是爬虫? 爬虫:就是抓取网页数据的程序。 三、爬虫怎么抓取网页数据:...

  • 人人都会数据分析大纲

    -实现数据分析需要有哪些东西? -有数据 --数据从何而来? ---自有数据 ---爬虫抓取 ----爬虫抓取的步...

  • 浅谈爬虫

    1.什么是爬虫? 爬虫:就是抓取网页中的数据 2.为什么选择python做爬虫? 可以做爬虫的语言有很多,如PHP...

  • spider(爬虫)

    spider(爬虫) 推荐抓取工具:火车采集器\火车头采集器 爬虫抓取网页 jsdom.js 爬虫抓取数据

  • 链接 | 左手用R右手Python系列

    这个知乎系列不错 左手用R右手Python系列之——表格数据抓取之道 看篇幅 python 比 R 的确要简洁好多...

  • R数据可视化-动态、交互式地图神器(三)符号标记

    Leaflet/LeafletCN 系列 R数据可视化-动态、交互式地图神器(一)概述与实现R数据可视化-动态、交...

  • 爬虫——Web Scraper

    1.认识爬虫 2.利用Excel抓取数据 3.爬虫入门 4.爬虫进阶 5.反爬虫及高阶玩法 6.制作新爬虫步骤 7...

  • Python 爬虫_动态网页抓取

    挖坑____ 理解静态网页 理解动态网页 爬虫的基本原理 爬虫与网页内容之间的关系 使用爬虫抓取动态网页内容

网友评论

    本文标题:R语言爬虫系列6|动态数据抓取范例

    本文链接:https://www.haomeiwen.com/subject/ttldbxtx.html