中国⼤学MOOC课程信息爬取与数据存储
10⽉18⽇更:
9⽉2⽇更:
9⽉1⽇更:关于MOOC的课程信息数据分析,参看:
注意:当前代码已过时(⽹站有所改动),仅做思路参考。
写在前⾯
暑假没事玩玩爬⾍,看到中国⼤学MOOC便想爬取它所有课程信息。⽆奈,它不是静态⽹页,课程数据都是动态加载的。⽽爬取动态页⾯⽬前来说有两种⽅法:
1. 分析页⾯Ajax请求
2. selenium模拟浏览器⾏为
可能⽅法不正确,我尝试了前者发现⾏不通,便采⽤了后者。由于第⼀次写博客且⾃⼰编程能⼒有限,⽂中有不⾜或需要改进的地⽅请不吝赐教。
环境配置及模块安装
编译环境: Python3.6 、Spyder
依赖模块:pymysql,selenuim,bs4,re等
另外还要下载chromedriver并配置,参考
简要分析流程
1. 主页分析
主页上便有课程类别,可以将其保存为字典,通过不同课程类别便可到达相应课程类别界⾯。
subjects={'全部':'all_sub','计算机':'computer','经济管理':'management','⼼理学':'psychology',
'外语':'language','⽂学历史':'literary_history','艺术设计':'art','⼯学':'engineering',
'理学':'science','⽣命科学':'biomedicine','哲学':'philosophy','法学':'law',
'教育教学':'teaching_method','⼤学先修课':'advanced_placement','职业教育课程':'TAFE'}
for i,subject in enumerate(subjects):python 爬虫教学
subject_Eng=subjects[subject]
mooc_crawl(subject,subject_Eng)
每个页⾯都有都可到多个这样的课程信息。
点击下⼀页可实现翻页。
2.⽹页解析
加载Chrome⽹页
url = '/category/all'
driver = webdriver.Chrome()
driver.set_page_load_timeout(50)
<(url)
driver.maximize_window() # 将浏览器最⼤化显⽰
driver.implicitly_wait(5) # 控制间隔时间,等待浏览器反应
选择课程类别,模拟点击;获取⽹页源码,Beautifulsou解析
ele=driver.find_element_by_link_text(subject)
ele.click()
htm_const = driver.page_source
soup = BS(htm_const,'xml')
返回soup对象,便可看到动态加载好的⽹页源码。由于是txt⽂档,虽然不好查看,但并不妨碍我们到需要的信息。从上⾯截图可以看到了⼀些课程的课程名、开课⽼师、⽹页链接、参与⼈数等。因此从这⾥⼊⼿,我们便可得到该页⾯的课程信息!
c_names=soup.find_all(name='img',attrs={'height':'150px'})
c_schools=soup.find_all(name='a',attrs={'class':'t21 f-fc9'})
c_teachers=soup.find_all(name='a',attrs={'class':'f-fc9'})
c_introductions=soup.find_all(name='span',attrs={'class':'p5 brief f-ib f-f0 f-cb'})
c_stunums=soup.find_all(name='span',attrs={'class':'hot'})
c_start_times=soup.find_all(name='span',attrs={'class':'txt'})
c_links=soup.find_all(name='span',attrs={'class':' u-course-name f-thide'})
for i in range(len(c_names)):
kc_names.append(c_names[i]['alt'])
kc_schools.append(c_schools[i].string)
kc_teachers.append(c_teachers[i].string)
if c_introductions[i].string ==None:
c_introduction=''
else:
c_introduction=c_introductions[i].string
kc_introductions.append(c_introduction)
c_stunum=repile('[0-9]+').findall(c_stunums[i].string)[0]
kc_stunums.append(int(c_stunum))
kc_start_times.append(c_start_times[i].string)
kc_links.append('http:'+c_links[i].parent['href'])
c_id_num=repile('[0-9]{4,}').findall(c_links[i].parent['href'])[0]
kc_id_nums.append(int(c_id_num))
kc_info=[kc_names,kc_schools,kc_teachers,kc_introductions,kc_stunums,kc_start_times,kc_links,kc_id_nums]
如下:
接下来,便是数据存储啦。
数据存储
由于mysql功能强⼤,操作简便,python对其⽀持性较好,我就选⽤了mysql。不过其他数据库皆可,数据存储原理⼤同⼩异。在
实现过程中,遇到了很多问题(SQL语句报错,主键的设置让每次插⼊数据都不重复,以变量为表单名的表单建⽴等等),好在花了⼀些功
夫后,最终得以解决。下⾯是存⼊数据库函数:
def save_mysql(subject,kc_info):
db = t(host='localhost',user='root',passwd='root',db='mooc_courses',charset='utf8')
cur = db.cursor()
try:
results=cur.fetchall()
ori_len=len(results)
except:
#建⽴新表
sql = "create table %s"% subject+"(order_num int(4) not null,\
course varchar(50),\
school varchar(20),\
teacher varchar(20),\
start_time varchar(20),\
stu_num int(6),\
introduction varchar(255),\
link varchar(50),\
id int(11) not null,\
primary key(id)\
)"
dbmit()
ori_len=0
print('已在mooc_course数据库中建⽴新表'+subject)
for i in range(len(kc_info[0])):
cur = db.cursor()
sql = "insert into %s"% subject+"(order_num,course,school,teacher,introduction,stu_num,start_time,li
nk,id) VALUES ('%d','%s','%s','%s','%s','%d','%s','%s','%          (ori_len+i,kc_info[0][i],kc_info[1][i],kc_info[2][i],kc_info[3][i],kc_info[4][i],kc_info[5][i],kc_info[6][i],kc_info[7][i])#执⾏数据库插⼊操作
try:
# 使⽤ cursor() ⽅法创建⼀个游标对象 cursor
except Exception as e:
# 发⽣错误时回滚
print('第'+str(i+1)+'数据存⼊数据库失败!'+str(e))
else:
dbmit()  # 事务提交
print('第'+str(i+1)+'数据已存⼊数据库')
db.close()
当当当!修成正果,部分数据展⽰如下:
执⾏整个程序⼀共花了:726s,效率有待提⾼。不过对于我来说,还过得去。(实在不⾏,加多线程撒)。当然,数据爬取了,必须利⽤嘛,不然放在那⾥养⽼不?有空,我做做数据分析,看看什么课最受欢迎,哪些院校开课最多等等。。。。。。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。