原文地址:爬取慕课网用户学习记录
1. 引言
由于毕业论文研究的是在线学习的相关问题,需要有用户在线学习的数据进行分析。逛了一圈,发现比较好的数据集就是KDD CUP2015的比赛数据集,不过时间有点久就弃用了,就决定还是自己一点点爬吧。
国内外有很多慕课网平台,例如国外的coursera、edx以及国内慕课网(IMOOC)、网易云课堂等。逛了一圈下来发现用户信息最丰富的就是慕课网(IMOOC)了,除了用户本身的信息如性别、位置、职业、简介、学习时长等,还有用户所学课程的学习记录,如学习进度、笔记、问答、代码分享等,最适合作为分析对象,因此本篇所述爬虫的目标就是要爬取慕课网(IMOOC)的所有用户学习记录。
2. 页面分析
以上就是我们爬取的页面,从上到下,我们可以爬取的信息有:
用户信息:
姓名:慕女神
性别:女
地点:北京
职业:全栈工程师
学习时长:39h
经验:806
积分:135
关注:99
粉丝:9999999
学习记录:
最近学习时间 | 课程名称 | 学习进度 | 笔记 | 代码 | 问答 |
---|---|---|---|---|---|
2018/06/15 | Flutter开发第一步-Dart编程语言入门 | 4% | 0 | 0 | 0 |
2018/01/18 | 新一代构建工具gradle | 10% | 0 | 0 | 0 |
… … | … … | … … | … … | … … | … … |
用chrome的开发者工具查看数据,发现在开发者工具的Elements可以显式看到数据元素,说明数据可以直接通过下载html页面来获取。(有的数据是AJAX动态加载,这种情况就用其他方法来获取,这里不说)
再看页面的URL形式:
头尾固定,中间ID只需要通过ID自增长的方式遍历下去就可以获得所有用户的课程学习信息。
3. 爬虫设计
3.1 工具介绍
- python 3.7
- requests 2.21.0 下载页面
- lxml 解析页面
- mysql-connector-python 8.0.13 (另外下载,pip或anaconda)数据持久化
3.2 爬取用户信息
In [1]:
#所需要用到的包
import requests
import time
import pandas as pd
from lxml import etree
import mysql.connector
from multiprocessing import Pool as ThreadPool
import socket
socket.setdefaulttimeout(10)
In [2]:
#生成待爬取的URL
urls = []
for i in range(100000, 7194872):
url = 'http://www.imooc.com/u/' + str(i) +'/courses'
urls.append(url)
In [3]:
#模拟浏览器访问请求
head = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
}
html = requests.get(url,headers=head,timeout=(3,7))
In [4]:
#通过XPath解析请求
selector = etree.HTML(html.text)
content = selector.xpath("//html")[0]
user_id = int(url.replace('http://www.imooc.com/u/', '').replace('/courses',''))
user_name = content.xpath('//h3[@class="user-name clearfix"]/span/text()')
#若用户名为空,则说明页面不存在,因此后面的操作都需要判断用户是否存在
if user_name:
user_name = user_name[0]
user_sex = content.xpath('//p[@class="about-info"]/span/text()')
if user_sex:
user_sex = user_sex[0]
else:
user_sex = r'/'
user_time = content.xpath('//div[@class="item follows"]//em/text()')[0].replace(' ', '') #学习时长
user_exp = int(content.xpath('//div[@class="item follows"]//em/text()')[1]) #经验
user_score = int(content.xpath('//div[@class="item follows"]//em/text()')[2]) #积分
user_follows = int(content.xpath('//div[@class="item follows"]//em/text()')[3]) #关注
user_fans = int(content.xpath('//div[@class="item follows"]//em/text()')[4]) #粉丝
到此我们就抓取了用户的基本信息,接着我们看课程信息。
3.3 爬取课程学习记录
用户的课程信息分为三种情况:
- 用户课程信息需要翻页
- 无需翻页
- 无学习记录
对于这三种情况我们爬取的时候需要进行一个判断
In [5]:
last_page = content.xpath('//div[@class="page"]/a[last()]/text()') #是否包含尾页button
user_course_list = []
if last_page:
if last_page[0] == u'尾页':#需要翻页
#代码较长,完整代码见github ... ...
else:
course_num = len(content.xpath('//li[@class="course-one"]')) #该页课程数量
if course_num == 0:#无学习记录
pass
else:#有记录,不需要翻页
#代码较长,完整代码见github ... ...
3.4 数据持久化
由于爬取的数据较大,我们需要把数据存储起来,因此我们把爬下来的记录存储在mysql中
In [5]:
def creat_MysqlDB():
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="123456",
database="MOOC"
)
return mydb
mydb = creat_MysqlDB()
sql = "INSERT INTO user_learn_info (user_id,user_name,user_sex,user_time,user_exp,\
user_score,user_follows,user_fans,course_id,course_name,last_time,\
process,note,code,qna) VALUES \
(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,%s, %s, %s, %s, %s)"
val = (user_id,user_name,user_sex,user_time,user_exp,user_score,user_follows,user_fans
,course_id,course_name,last_time,process,note,code,qna)
mycursor = mydb.cursor()
mycursor.execute(sql, val)
mydb.commit()
3.5 使用多进程提高爬取效率
In [5]:
from multiprocessing import Pool as ThreadPool
pool = ThreadPool(8) #进程数
pool.map(getsource, urls) #对每个URL进行爬取
pool.close() #关闭进程池
pool.join() #主线程,等待子线程运行完毕
4. 结果
这是爬取过程中数据库表记录,可以看到已经爬取了两百多万条记录,爬虫稳定运行,等着也是等着,写篇博客记录一下,完整代码在github上,见---->>完整代码
共同学习,写下你的评论
评论加载中...
作者其他优质文章