Python爬虫实战:用Requests和lxml搞定长江雨课堂选择题,自动存入MySQL数据库

发布时间:2026/7/4 17:23:14

Python爬虫实战:用Requests和lxml搞定长江雨课堂选择题,自动存入MySQL数据库 Python爬虫实战从数据抓取到MySQL存储的完整解决方案在数字化学习时代网课平台积累了大量有价值的习题资源。对于学习者而言如何高效地整理和复习这些题目成为提升学习效率的关键。本文将带你完整实现一个Python爬虫项目从登录认证到数据持久化构建一个健壮的习题采集系统。1. 项目规划与环境准备任何爬虫项目开始前明确目标和规划技术路线至关重要。我们需要实现的核心功能包括模拟登录获取认证、精准定位目标数据、解析复杂JSON结构、处理异常情况以及最终将结构化数据存入数据库。首先确保安装必要的Python库pip install requests lxml pymysql这三个库分别承担不同角色requests处理HTTP请求和响应lxml解析HTML和XML文档pymysql连接MySQL数据库执行操作提示建议使用虚拟环境管理项目依赖避免库版本冲突。可以使用python -m venv venv创建隔离环境。2. 认证与会话管理现代教育平台普遍采用Cookie或Token进行身份验证。以长江雨课堂为例我们需要先获取有效的Cookie使用浏览器正常登录平台打开开发者工具F12访问任意课程页面在Network选项卡中找到XHR请求复制Request Headers中的Cookie值实现代码示例import requests headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64), Cookie: your_cookie_here # 替换为实际获取的Cookie } session requests.Session() session.headers.update(headers)关键注意事项Cookie具有时效性通常几小时到几天不等频繁请求可能触发反爬机制建议实现Cookie自动更新机制3. 数据抓取与解析策略教育平台的习题数据通常通过API返回JSON格式。我们需要定位包含习题数据的API端点分析响应数据结构提取题目、选项和答案典型的数据解析流程from lxml import etree def parse_question(data): try: # 提取题目HTML片段 html data[slide][ProblemBodys][0][Paragraphs][0][Lines][0][Html] # 使用XPath提取纯文本 question etree.HTML(html).xpath(//span/text())[0] # 处理选项 options [] for bullet in data[slide][Problem][Bullets]: option_html bullet[Contents][0][Paragraphs][0][Lines][0][Html] option_text etree.HTML(option_html).xpath(//span/text())[0] options.append(f{bullet[Label]}: {option_text}) return { question: question, answer: data[answer], options: | .join(options) } except KeyError as e: print(f解析异常: {e}) return None常见问题处理问题类型解决方案代码示例键不存在异常捕获try-except KeyError数据格式变化类型检查isinstance(data, dict)网络超时重试机制requests.adapters.HTTPAdapter4. 数据库设计与操作合理的数据库设计能提升查询效率并减少冗余。我们创建以下表结构CREATE TABLE exam_questions ( id INT NOT NULL AUTO_INCREMENT, question VARCHAR(512) NOT NULL, correct_answer VARCHAR(32) NOT NULL, all_options VARCHAR(1024) NOT NULL, course_id VARCHAR(64) NOT NULL, question_type ENUM(choice, fill) NOT NULL, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY idx_question (question(255)) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;Python操作MySQL的最佳实践import pymysql from contextlib import contextmanager contextmanager def db_connection(): conn pymysql.connect( hostlocalhost, useryour_username, passwordyour_password, databaseexam_db, charsetutf8mb4 ) try: yield conn finally: conn.close() def save_question(question_data): sql INSERT INTO exam_questions (question, correct_answer, all_options, course_id, question_type) VALUES (%s, %s, %s, %s, %s) with db_connection() as conn: with conn.cursor() as cursor: cursor.execute(sql, ( question_data[question], question_data[answer], question_data[options], course_123, # 实际课程ID choice )) conn.commit()性能优化建议使用连接池管理数据库连接批量插入代替单条插入添加适当的索引提升查询速度5. 项目优化与扩展基础功能实现后我们可以从以下几个维度提升项目质量5.1 反爬虫策略应对教育平台可能采取的反爬措施包括请求频率限制User-Agent验证行为分析鼠标移动、点击模式应对方案import time import random from fake_useragent import UserAgent def get_random_headers(): ua UserAgent() return { User-Agent: ua.random, Accept-Language: zh-CN,zh;q0.9, Referer: https://changjiang.yuketang.cn/ } def random_delay(): time.sleep(random.uniform(1, 3))5.2 错误处理与日志记录健壮的系统需要完善的错误处理机制import logging from requests.exceptions import RequestException logging.basicConfig( filenamespider.log, levellogging.INFO, format%(asctime)s - %(levelname)s - %(message)s ) def safe_request(url, max_retries3): for attempt in range(max_retries): try: response session.get(url) response.raise_for_status() return response.json() except RequestException as e: logging.warning(f请求失败: {e}, 尝试 {attempt 1}/{max_retries}) if attempt max_retries - 1: logging.error(f最终请求失败: {url}) raise time.sleep(2 ** attempt)5.3 填空题支持扩展原始项目仅处理选择题扩展填空题处理def parse_fill_question(data): try: # 填空题HTML结构可能不同 html data[slide][shapes][0][Paragraphs][0][Lines][0][Html] question etree.HTML(html).xpath(//span/text())[0] return { question: question, answer: data[answer], options: 填空题, type: fill } except (KeyError, IndexError) as e: logging.error(f填空题解析错误: {e}) return None6. 项目部署与定时运行实现完整功能后可以考虑将配置信息如数据库连接、Cookie等移出代码使用配置文件或环境变量添加命令行参数支持方便指定课程ID等参数设置定时任务定期自动更新习题库示例配置分离# config.py DB_CONFIG { host: localhost, user: db_user, password: secure_password, database: exam_questions } SPIDER_CONFIG { base_url: https://changjiang.yuketang.cn/v2/api/web, max_retries: 5, request_timeout: 10 }定时任务示例Linux crontab0 2 * * * /usr/bin/python3 /path/to/spider.py --course-id CS101 /var/log/spider.log 21在实际项目中我发现最耗时的部分不是代码编写而是对平台API响应结构的分析和异常处理。特别是当平台更新导致数据结构变化时需要有良好的日志系统快速定位问题。建议在开发阶段就建立完善的数据校验机制确保抓取到的每道题目都符合预期格式。

相关新闻