前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >网易云课堂Excel课程爬虫思路

网易云课堂Excel课程爬虫思路

作者头像
数据小磨坊
发布2018-04-11 17:34:32
1.9K0
发布2018-04-11 17:34:32
举报
文章被收录于专栏:数据小魔方数据小魔方

由于即将毕业,马上进入职场,想来是时候需要巩固一下基本职场技能了,特别是Excel这种杀手级职场应用。

可是如今网络这么发达,到处都充斥着Excel课程、视频、教程,真的很容易让人眼花缭乱,不知所措。

看书来的太慢了,还是直接看视频吧,简单粗暴,学习之前总要熟悉一下Excel教学行业的大致情况吧,今天就拿网易云课堂的Excel板块作为目标,在练习数据爬取的同时,顺便了解一下Excel培训行业的行情,知己知彼才能百战不殆,才能更加集中精力的学习那些精品课程。

url<-"http://study.163.com/category/excel#/"

#Excel板块首页网址

url<-"http://study.163.com/category/excel#/?p=2"

#加载第二页之后的网址

网易云课堂的网页不是很复杂,而且URL是很规律的参数拼接,反倒最底部可以看到,它是点击翻页,一共只有9页,而且页面是顺序加载,OK,可以直接手动拼接遍历网址了。

url<-paste0("http://study.163.com/category/excel#/?p=",1:9)

library("rvest") library("XML") library("RCurl") postForm(url[1],) web<-read_html(url[1],encoding="UTF-8")%>% html_nodes("div.uc-ykt-coursecard-wrap_tit > h3") %>% html_text()

but以上尝试都失败了!

当我想当然的以为网易云课堂用R可以轻松搞定的时候,猛然发现他用的XHR技术,奔溃……

首先我们再次分析网页,打开云课堂Excel模块首页,按F12翻到XHR菜单

在底部你可以看到studycourse.json文件,点开之后可以看到右侧的Preview栏目里面全部都是课程信息,是一个json文件。

这个模块是Chrome的开发者工具后台,就是我们常说的抓包工具,现在切换到Headers栏目,可以看到云课堂所有的课程信息都是在一个.josn网页里面存放着,这里便是阻碍我们使用普通方法爬取数据的困难之源。

仔细看你会发现General里面用到的Request Method 是Post,Post方法在 提交网址和参数的同时,要提交表单数据,这时候我们需要详细的查看Request Headers里面的参数信息。

因为POST方法涉及到传递表单参数,所以构造报头一定要添加Content-Type参数,这里的Content-Type参数是application/json,需要传递json字符串。

看来今天这个案例用R语言有些困哪了(使用 webdriver除了偷懒,并不能锻炼你什么能力),本案例POST要传递json表单参数,R里面没有很多的处理json的方式,再加上RCurl里面的POST方法资料太少,没有什么可参考资料。(还是R语言的爬虫生态太弱了)。

所以今天用Pyhton来演示本案例:

import json import requests import pandas as pd import os

第一步:分析XHR中POST方法的表单规律:

使用POST方法爬取数据,需要重点关注Request Headers中的User-Agent、Content-Type以及最后面的表单体。

本例的网页,虽然看上去分了9个子页面,但是实际上其调用的json仅有一个主页:http://study.163.com/p/search/studycourse.json

而不同子页面主要是用过表单体中的参数来确定到的。

{"pageIndex":1,"pageSize":50,"relativeOffset":0,"frontCategoryId":"400000000149040","searchTimeType":-1,"orderType":0,"priceType":-1,"activityId":0} {"pageIndex":2,"pageSize":50,"relativeOffset":50,"frontCategoryId":"400000000149040","searchTimeType":-1,"orderType":0,"priceType":-1,"activityId":0} {"pageIndex":3,"pageSize":50,"relativeOffset":100,"frontCategoryId":"400000000149040","searchTimeType":-1,"orderType":0,"priceType":-1,"activityId":0} …… {"pageIndex":9,"pageSize":50,"relativeOffset":400,"frontCategoryId":"400000000149040","searchTimeType":-1,"orderType":0,"priceType":-1,"activityId":0}

以上我给出了9个页面的表单体信息中的前三个和最后一个,通过找规律你会发现,差异仅在pageIndex和relativeOffset参数上,其他参数都是一样的。pageIndex和relativeOffset分别代表页面id和主页中信息条目的偏移量。偏移量间隔50,也就是我们在网页上看到的单页展示课程数目。

构造表单体:

payload = { "pageIndex":1, "pageSize":50, "relativeOffset":100, "frontCategoryId":"400000000149040" }

一共9个子页面,通过表单体参数进行页面遍历控制

构造报头信息:

headers = { 'Accept':'application/json', 'content-type':'application/json', 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36' }

第二步:构造网页爬取函数:

url = 'http://study.163.com/p/search/studycourse.json'

r=requests.post(url,data=json.dumps(payload),headers=headers);r

<Response [200]>

状态码OK!

content=r.json();content

type(content)

dict ###返回内容类型为字典

返回的是一个字典,里面嵌套有很多层,仔细观察你会先发,我们需要的内容都存放在content['result']['list']里面

content['result']['list']

type(content['result']['list'])

list ###返回类型是列表

OK,构造一个循环,将每一次请求返回提取的内容拼接在一个列表里面:

fullinfo=[]

for i in list(range(1,10)):

payload['pageIndex']=i

payload['relativeOffset']=50*i-50

r=requests.post(url,data=json.dumps(payload),headers=headers)

content=r.json()

fullinfo=fullinfo+content['result']['list']

print("第{}部分已加载".format(i))

df1=pd.DataFrame(fullinfo)

df1.columns ###返回所有列信息

Index(['activityIds', 'bigImgUrl', 'courseCardProps', 'courseId', 'description', 'discountPrice', 'discountRate', 'displayType', 'endTime', 'forumTagLector', 'gmtModified', 'imgUrl', 'isPromStatus', 'learnerCount', 'lectorName', 'originalPrice', 'productId', 'productName', 'productType', 'provider', 'published', 'schoolShortName', 'score', 'scoreLevel', 'startTime', 'tagIap', 'tagLectorTime'], dtype='object')

###提取我们需要的列:

mydata=df1[["productName","discountPrice","discountRate","lectorName","originalPrice","description","provider","score","scoreLevel"]]

存储本地:

os.chdir('D:/Python/Data') mydata.to_csv('yunketang.csv',index=False)

存储到本地硬盘,搞完收工!一共421条Excel课程信息,和后台的信息一致。

下一篇针对这一次爬虫结果做可视化分析!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据小魔方 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云课堂
云课堂聚焦教培机构 OMO 转型,为机构提供在线及混合式课堂解决方案,极速开课、多向互动、智能沉淀、一键分发,是教培课堂便捷、稳定的教学助手。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档