近期在写一份关于大数据相关的作业,需要搜索近年来市面上关于大数据的书籍信息和课程信息。其中一位同学负责在当当网上爬取书籍信息,我就负责爬取MOOC网的课程信息。

刚开始的时候,以为MOOC网作为一个公益性网站,安全性不会那么高,因此会比较好爬。然而我还是太天真了,网站上一大批JavaScript让我不知所措。好在经过一段时间的探索,终于能够成功爬取了。

1. 网站分析

打开MOOC官网,在搜索框输入“大数据”关键词,发现返回了99条数据(当时的情况),也就是说,有99个关于大数据的课程。

但是,只有课程列表是不行的。就像爬取淘宝网站的时候,获取到了商品列表,还需要进入到商品的详情页面,然后抓取我们需要的信息。在这里,我们同样需要这样的方法。

但是,通过Google浏览器的检查功能可以发现,你几乎无法在课程页面获取什么东西——因为几乎都是动态变化的。我试图获取每个课程上面的超链接,然后进入到具体的详情页面,但是很显然直接使用requests方法是不行的。

后来经过同学指点发现此处需要通过post方法,获取到response,返回的response里面才具有我们需要的详情页面的信息(其实也就是每个课程的id,通过该id可以构造详情页面)

2. 代码设计

2.1 获取课程id

经过上面的分析,我首先找到了商品id存储的页面,如下图所示,我发现当我点击下一页的时候,会多出图中红色方框部分的网址,说明该网址是我请求的response,点击preview查看预览也印证了我的猜测。

问题搞清楚了,下面使用requests包的post函数发送请求,然后分析获取到的response。

import requests
import urllib.parse as up#准备进行搜索的关键词
keywords = ['大数据','机器学习','数据挖掘','数据科学','人工智能']#转换成URL编码
def quote(x):return up.quote(x)
#转换编码
keywords = list(map(quote,keywords))#URL前缀
startUrl = "http://www.icourse163.org/search.htm?search="#构造URL
urls = []
for kws in keywords:urls.append(startUrl+kws)#post的URL
jsurl = "http://www.icourse163.org/dwr/call/plaincall/MocSearchBean.searchMocCourse.dwr"#请求头
headers = {"Accept":"*/*","Accept-Encoding":"gzip,deflate","Accept-Language":"zh-CN,zh;q=0.9","Connection":"keep-alive","Content-Length":"522","Content-Type":"text/plain","Host":"www.icourse163.org","Origin":"http://www.icourse163.org"#Refere是我们查询的时候对应的URL,也需要根据不同的关键词进行调整#"Referer":"http://www.icourse163.org/search.htm?search=%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0"}
#发送的数据
payload = {"callCount":"1","scriptSessionId":"${scriptSessionId}190","httpSessionId":"907805e60a6540c4a268164e9e89ac4c","c0-scriptName":"MocSearchBean","c0-methodName":"searchMocCourse","c0-id":"0",#c0-e1的string是我们查询的关键词,需要根据不同的关键词进行更改#"c0-e1":"string:%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0",#c0-e2的number表示获取的是第几页数据,需要动态变化#"c0-e2":"number:1","c0-e3":"boolean:true","c0-e4":"null:null","c0-e5":"number:0","c0-e6":"number:30","c0-e7":"number:20","c0-param0":"Object_Object:{keyword:reference:c0-e1,pageIndex:reference:c0-e2,highlight:reference:c0-e3,categoryId:reference:c0-e4,orderBy:reference:c0-e5,stats:reference:c0-e6,pageSize:reference:c0-e7}","batchId":"1511830181483"}#构造一个空字典,用于存储课程列表中每一门课程的id
courses = {}
#分析response
for i in range(0,len(urls)):headers["Referer"] = urls[i]string = "string:" + keywords[i]payload["c0-e1"] = stringfor j in range(1,20):  #大致查询了一下,课程数量不会超过20页page = "number:" + str(j)payload["c0-e2"] = page#目前为止,上面请求的部分已经做完response = requests.post(data=payload,url=jsurl,headers = headers)courseid = re.findall(pattern=r'courseId=([0-9]{0,20})',string=response.text)if(len(courseid) == 0):break;else:kw = up.unquote(keywords[i])if not kw in courses.keys():courses[kw] = courseidelse:courses[kw].extend(courseid)

2.2 获取详情

上面已经获取到了课程的id,我们只需要使用该id构造课程详情页的URL就行了。

上图展示了课程详情页的URL信息,总结可以发现,前面的部分"http://www.icourse163.org/course/“ 都是一样的,只有后面的大学简称和id是变化的。而且大学简称可以使用任何非空值……利用上面的信息,构造好需要的URL,然后就可以使用selenium进行爬取了。

#使用无头浏览器phantomjs获取页面信息
browser = webdriver.PhantomJS('C:/phantomjs/bin/phantomjs.exe')
#data用来存储我们获取到的数据
data = None
data = pd.DataFrame({"course_name":"","start_times":"","lasting":"","start_date":"","end_date":"","rollnum":"","coursehrs":"","outline":"","key_word":""},index=["0"])
#data frame的行索引
index = 0for k in courses.keys():  #k是键for v in courses[k]:  #v是值#page是构造的课程详情页URLpage = "http://www.icourse163.org/course/ABC-" + str(v)#get数据browser.get(page)#每个页面之间停顿3秒,否则有可能还没有渲染成功,获取不到数据#这应该是一种隐式等待time.sleep(3)#info是我们需要的一系列信息,根据id(j-center)返回info = browser.find_element_by_id('j-center').textinfo = re.sub(re.compile("\n"),"",info)info = re.sub(re.compile(r'[0-9]{2}:[0-9]{2}'),"",string=info)#1.课程名称course_name = browser.find_element_by_tag_name('h1').text#2.第几次开课start_times = re.search(pattern="第([0-9])次开课",string=info)if not start_times is None:start_times = start_times.group(1)else:start_times = "NA"#3.持续时长lasting = re.search(pattern="课程已进行至([0-9]{0,2}\/[0-9]{0,2})周",string=info)if not lasting is None:lasting = lasting.group(1)else:lasting = "NA"#4.开始日期start_date = re.search(pattern= r"开课:([0-9]{0,4}[年]{0,1}[0-9]{0,2}月[0-9]{0,2}日)",string=info)if not start_date is None:start_date = start_date.group(1)else:start_date = "NA"#5.结束日期end_date = re.search(pattern = r"结束:([0-9]{0,4}[年]{0,1}[0-9]{0,2}月[0-9]{0,2}日)",string=info)if not end_date is None:end_date = end_date.group(1)else:end_date = "NA"#6.参与人数rollnum = re.search(pattern = r"([0-9]{0,9})人参加",string = info)if not rollnum is None:rollnum = rollnum.group(1)else:rollnum = "NA"#7.课程时长coursehrs = re.search(pattern=r"课程时长(.*?)周",string=info)if not coursehrs is None:coursehrs = coursehrs.group(1)else:coursehrs = "NA"#8.课程概述outline = browser.find_element_by_id('j-rectxt2').textif outline is None:outline = "NA"data.loc[index] = {"course_name":course_name,"start_times":start_times,"lasting":lasting,"start_date":start_date,"end_date":end_date,"rollnum":rollnum,"coursehrs":coursehrs,"outline":outline,"key_word":k}index = index + 1print("已经获取第%d个课程数据!"%(index))

3. 结果展示

数据获取完毕以后,把存储在内存中的数据输出到Excel

from pandas import  ExcelWriter
writer = ExcelWriter("MOOC.xlsx")
data.to_excel(writer,"mooc")
writer.save()

最终展示在Excel中的数据如下图:

转载于:https://www.cnblogs.com/f-young/p/7911840.html

Selenium爬取MOOC网课程信息相关推荐

  1. xpath爬取mooc网课程

    要求: 爬取的链接:http://www.imooc.com/course/list 爬取的内容:课程链接,课程的图片url,课程的名称,学习人数,课程描述 爬取的内容如何存储: 文件(csv): m ...

  2. selenium爬取珍爱网用户信息

    近期接到一个任务,爬取珍爱网上的用户信息,这个对单身的我来说瞬间提起了兴趣,这有可能是我脱单的开始,哼哼,不装逼了,先来看看怎么帮我脱单,嘻嘻嘻 import requests import time ...

  3. python抓取文献关键信息,python爬虫——使用selenium爬取知网文献相关信息

    python爬虫--使用selenium爬取知网文献相关信息 写在前面: 本文章限于交流讨论,请不要使用文章的代码去攻击别人的服务器 如侵权联系作者删除 文中的错误已经修改过来了,谢谢各位爬友指出错误 ...

  4. python-scapy爬取mooc网保存在数据库中并下载图片

    爬取的步骤 - 确定url地址; - 获取页面信息;(urllib, requests); - 解析页面提取需要的数据: (正则表达式, bs4, xpath) - 保存到本地(csv, json, ...

  5. 利用Selenium爬取淘宝商品信息

    文章来源:公众号-智能化IT系统. 一.  Selenium和PhantomJS介绍 Selenium是一个用于Web应用程序测试的工具,Selenium直接运行在浏览器中,就像真正的用户在操作一样. ...

  6. python+selenium爬取智联招聘信息

    python+selenium爬取智联招聘信息 需求 准备 代码 结果 需求 老板给了我一份公司名单(大概几百家如下图),让我到网上看看这些公司分别在招聘哪些岗位,通过分析他们的招聘需求大致能推断出我 ...

  7. Python2 Python3 爬取赶集网租房信息,带源码分析

    *之前偶然看了某个腾讯公开课的视频,写的爬取赶集网的租房信息,这几天突然想起来,于是自己分析了一下赶集网的信息,然后自己写了一遍,写完又用用Python3重写了一遍.之中也遇见了少许的坑.记一下.算是 ...

  8. python爬虫scrapy爬取新闻标题及链接_python爬虫框架scrapy爬取梅花网资讯信息

    原标题:python爬虫框架scrapy爬取梅花网资讯信息 一.介绍 本例子用scrapy-splash爬取梅花网(http://www.meihua.info/a/list/today)的资讯信息, ...

  9. Python 爬虫第三步 -- 多线程爬虫爬取当当网书籍信息

    XPath 的安装以及使用 1 . XPath 的介绍 刚学过正则表达式,用的正顺手,现在就把正则表达式替换掉,使用 XPath,有人表示这太坑爹了,早知道刚上来就学习 XPath 多省事 啊.其实我 ...

最新文章

  1. 《评人工智能如何走向新阶段》后记(再续4)
  2. 实战并发编程 - 01多线程读写同一共享变量的线程安全问题深入剖析
  3. 深度学习 占用gpu内存 使用率为0_你了解GPU吗?为什么说深度学习需要GPU?
  4. 实现微信朋友圈动态列表
  5. lintcode433 岛屿的个数
  6. oracle备份和还原
  7. 一次oracle大量数据删除经历
  8. 实用的无锁队列(一)
  9. 从零开始学Koa2(一)
  10. [安卓] 2、使用2中方法做按钮监听和图片按钮使用
  11. listview拖动优化问题
  12. OpenGL基础28:模型
  13. 2020计算机二级vb考试题库,2020年计算机二级VB题库计算机二级考试题库.docx
  14. jQuery cdn加速
  15. Rabbitmq 安全账号管理方案
  16. 用 .pth 文件附加 Python 模块搜索路径
  17. leetcode495. 提莫攻击
  18. 文章阅读统计php,WordPress博客统计文章阅读次数及访客数并刷访问数
  19. android的wifi网卡移植详细过程已经通用驱动的问题
  20. 设施网络选址的基本方法,网络设施选址的方法

热门文章

  1. 不属于jsp构成元素_下列不属于JSP内置对象的是()。
  2. 布谷鸟算法求解车间调度问题(书籍摘录版)
  3. 决策报表里使用延时函数实现某些js效果
  4. js判断手机端还是电脑PC端(以及注意事项)
  5. 把SWF打回原形Imperator FLA v1.6.9.8
  6. 谷歌正式开放「Bard」试用,很遗憾。。
  7. 详解 TCP 和 UDP的概念、特点和区别
  8. 解决LEDE无线做中继不成功问题
  9. Java 性能调优 概念详解 小白教程
  10. 简述计算机视觉中的单眼线索,单眼深度线索