news 2026/6/3 8:03:57

用Python爬取中国大学MOOC课程数据,34万条评论数据集免费分享(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Python爬取中国大学MOOC课程数据,34万条评论数据集免费分享(附完整代码)

Python实战:构建中国大学MOOC课程数据爬虫与34万条评论数据集分析

最近在分析在线教育平台数据时,我发现中国大学MOOC平台上的课程评价数据特别有价值。这些真实用户反馈不仅能反映课程质量,还能揭示学习者的偏好和行为模式。今天就来分享一个完整的Python爬虫解决方案,从API分析到数据清洗,最终生成可直接用于研究的结构化数据集。

1. 环境准备与工具选择

在开始爬取数据前,我们需要搭建合适的开发环境。不同于简单的静态网页抓取,MOOC平台的数据大多通过API接口返回JSON格式,这对我们的工具选择提出了特定要求。

核心工具栈配置:

# 基础环境安装 pip install requests pandas numpy tqdm fake-useragent

推荐配置:Python 3.8+环境,VS Code或PyCharm作为IDE,配合Jupyter Notebook进行数据探索。

关键库的作用:

  • requests:处理HTTP请求的核心库
  • pandas:数据清洗和结构化存储
  • tqdm:显示爬取进度条
  • fake-useragent:生成随机请求头

注意:实际操作中建议配置代理IP池,虽然MOOC平台反爬机制相对宽松,但高频请求仍可能触发限制。

我通常会创建一个独立的虚拟环境来管理项目依赖:

python -m venv mooc_scraper source mooc_scraper/bin/activate # Linux/Mac mooc_scraper\Scripts\activate # Windows

2. API分析与请求策略

中国大学MOOC平台采用前后端分离架构,所有课程数据都通过API接口动态加载。通过浏览器开发者工具(F12),我们可以轻松找到这些关键接口。

主要API端点分析:

接口类型URL示例请求方式关键参数
课程分类.../listChannelCategoryDetail.rpcPOSTcsrfKey
课程列表.../searchCourseCardByChannelAndCategoryId.rpcPOSTcategoryId, pageIndex
课程评价.../getCourseEvaluatePaginationByCourseIdOrTermId.rpcPOSTcourseId, pageSize

请求头定制技巧:

headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Referer": "https://www.icourse163.org/channel/", "Origin": "https://www.icourse163.org", "Content-Type": "application/x-www-form-urlencoded" }

实际请求时需要注意几个关键点:

  1. csrfKey参数需要从首页或登录后的Cookie中提取
  2. 分页参数pageIndex从1开始计数
  3. 评价接口的orderBy=3表示按最新排序

3. 数据爬取实战代码

下面展示完整的爬虫实现,采用模块化设计便于维护和扩展。我们将分三个步骤获取数据:课程分类→课程详情→课程评价。

3.1 课程分类爬取

def get_course_categories(): base_url = "https://www.icourse163.org/web/j/channelBean.listChannelCategoryDetail.rpc" params = { "csrfKey": get_csrf_key() # 需要提前实现的函数 } payload = "includeALLChannels=true&includeDefaultChannels=false" response = requests.post(base_url, params=params, data=payload, headers=headers) data = response.json() # 数据清洗示例 categories = [] for category in data['result']['channelCategoryDetails']: for channel in category['channels']: clean_data = { 'id': channel['id'], 'name': channel['name'], 'desc': channel.get('shortDesc', '') } categories.append(clean_data) return categories

3.2 课程详情爬取

采用分页爬取策略,每类课程单独处理:

def get_courses_by_category(category_id, max_pages=50): courses = [] url = "https://www.icourse163.org/web/j/mocSearchBean.searchCourseCardByChannelAndCategoryId.rpc" for page in range(1, max_pages+1): payload = { "mocCourseQueryVo": json.dumps({ "categoryId": -1, "categoryChannelId": category_id, "pageIndex": page, "pageSize": 20 }) } try: response = requests.post(url, data=payload, headers=headers) page_data = response.json() for item in page_data['result']['list']: course = item['mocCourseBaseCardVo'] courses.append({ 'course_id': course['id'], 'name': course['name'], 'school': course['schoolName'], 'teacher': course['teacherName'], 'enroll_count': course['enrollCount'] }) if page >= page_data['result']['query']['totlePageCount']: break except Exception as e: print(f"Error on page {page}: {str(e)}") return courses

3.3 课程评价爬取

评价数据量最大,需要特别注意性能和异常处理:

def get_course_reviews(course_id): reviews = [] url = "https://www.icourse163.org/web/j/mocCourseV2RpcBean.getCourseEvaluatePaginationByCourseIdOrTermId.rpc" page = 1 while True: payload = { 'courseId': str(course_id), 'pageIndex': str(page), 'pageSize': '20', 'orderBy': '3' } try: response = requests.post(url, data=payload, headers=headers) data = response.json() for review in data['result']['list']: reviews.append({ 'id': review['id'], 'content': review['content'], 'user': review['userNickName'], 'rating': review.get('mark', 0), 'date': review['gmtModified'] }) if page >= data['result']['query']['totlePageCount']: break page += 1 time.sleep(0.5) # 礼貌性延迟 except Exception as e: print(f"Failed to get page {page}: {str(e)}") break return reviews

4. 数据存储与清洗

获取原始数据后,我们需要进行结构化处理和持久化存储。这里推荐使用Pandas进行数据清洗,然后保存为多种格式。

数据清洗关键步骤:

  1. 处理缺失值:
df['rating'] = df['rating'].fillna(0)
  1. 统一日期格式:
df['date'] = pd.to_datetime(df['date'], unit='ms')
  1. 文本清洗:
import re df['content'] = df['content'].apply(lambda x: re.sub(r'\s+', ' ', x).strip())

多格式存储方案:

格式优点适用场景代码示例
CSV通用性强数据交换df.to_csv('reviews.csv')
Parquet列式存储大数据分析df.to_parquet('reviews.parquet')
SQLite关系型本地查询df.to_sql('reviews', con=engine)

完整的数据处理流水线示例:

def process_data(raw_data): # 转换为DataFrame df = pd.DataFrame(raw_data) # 类型转换 df['date'] = pd.to_datetime(df['date'], unit='ms') df['rating'] = pd.to_numeric(df['rating']) # 文本处理 df['content'] = df['content'].str.strip() # 去重 df = df.drop_duplicates('id') return df

5. 数据分析与可视化

获得清洗后的数据后,我们可以进行一些基础分析,挖掘数据价值。以下是几个典型分析方向:

课程评价词云生成:

from wordcloud import WordCloud import jieba text = ' '.join(df['content'].dropna()) wordlist = ' '.join(jieba.cut(text)) wc = WordCloud( font_path='simhei.ttf', background_color='white', max_words=200 ).generate(wordlist) plt.imshow(wc) plt.axis('off') plt.show()

课程评分分布分析:

plt.figure(figsize=(10,6)) sns.countplot(x='rating', data=df) plt.title('评分分布') plt.xlabel('星级') plt.ylabel('数量') plt.show()

热门课程识别:

top_courses = df.groupby('course_name')['rating'] \ .agg(['count', 'mean']) \ .sort_values('count', ascending=False) print(top_courses.head(10))

6. 项目优化与扩展

基础爬虫完成后,我们可以从以下几个方向进行优化:

性能优化方案:

  • 使用aiohttp实现异步请求
  • 采用Redis作为请求队列
  • 实现断点续爬功能

反反爬策略:

  • 动态User-Agent轮换
  • 请求频率随机化
  • 重要参数加密处理

数据分析扩展:

  • 情感分析(使用SnowNLP或BERT)
  • 用户行为模式挖掘
  • 课程推荐系统构建

一个简单的异步爬虫改造示例:

import aiohttp import asyncio async def fetch(session, url, params): async with session.post(url, data=params) as response: return await response.json() async def main(): async with aiohttp.ClientSession() as session: tasks = [] for course_id in course_ids: task = fetch(session, API_URL, {'courseId': course_id}) tasks.append(task) results = await asyncio.gather(*tasks) # 处理结果...

7. 完整数据集分享

经过两周的爬取和清洗,最终获得的数据集包含:

  • 23个课程分类
  • 29,196门课程基本信息
  • 343,525条课程评价

数据集字段说明:

数据表主要字段记录数
课程分类id, name, desc23
课程信息id, name, school, teacher29,196
课程评价id, content, rating, date343,525

数据集下载链接已整理在项目仓库中,包含:

  • 原始JSON数据
  • 清洗后的CSV文件
  • 数据分析示例Notebook

使用建议:

  1. 教育研究者:分析课程评价与教学质量关系
  2. 产品经理:了解用户真实需求和痛点
  3. 数据科学学习者:作为文本分析练习素材

在真实项目中,这套数据帮助我们发现了几个有趣的现象:

  • 评分在4.2-4.5之间的课程最受欢迎
  • 用户更关注教师授课风格而非课程内容难度
  • 周末的评价情感倾向更为积极
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/3 7:54:14

基于MPU-9250与Arduino的3D记忆游戏立方体设计与实现

1. 项目概述如果你玩过经典的“西蒙说”(Simon Says)记忆游戏,大概会记得那个会按顺序闪烁不同颜色、需要你复现序列的玩具。这次,我想把这个游戏从二维的平面按钮,搬到三维的物理空间里。核心想法很简单:用…

作者头像 李华