作业1:
- 要求:
▪ 熟练掌握 Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内
容。
▪ 使用Selenium框架+ MySQL数据库存储技术路线爬取“沪深A股”、“上证A股”、
“深证A股”3个板块的股票数据信息。
▪ 候选网站:东方财富网:http://quote.eastmoney.com/center/gridlist.html#hs_a_board
▪ 输出信息:MYSQL数据库存储和输出格式如下,表头应是英文命名例如:序号
id,股票代码:bStockNo……,由同学们自行定义设计表头:
• Gitee文件夹链接:
https://gitee.com/sui123feng/20251015/tree/master/102302142罗伟钊_实践4/1
- 导入库:
selenium:自动化测试工具,用于模拟浏览器行为,抓取动态加载的股票数据
pymysql:Python 的 MySQL 驱动,用于连接数据库、创建表及存储爬取的数据
time:时间处理模块,用于设置强制等待,确保页面元素加载完成
os:操作系统接口模块,用于获取当前文件路径,定位本地的 chromedriver.exe
re:正则表达式模块,用于清洗文本数据
- 核心思路:

代码爬取 标签字段后通过位置将所需要的数据存入列表,不过对与cell[3]的数据需要注意跳过。
以上对每行的数据返回,再存储在stock_data中。
- 代码内容:
database.py
以下代码负责管理 MySQL 数据库连接和初始化,包括自动创建数据库与表结构,并将爬取到的股票数据持久化存储到数据库中。
--------------------------------------------------
点击查看代码
# -*- coding: utf-8 -*-
"""
数据库操作模块
"""
import pymysql
from config import DB_CONFIGclass DatabaseManager:def __init__(self):self.connection = Noneself.connect()self.create_table()def connect(self):"""连接数据库"""try:self.connection = pymysql.connect(**DB_CONFIG)print("数据库连接成功")except pymysql.err.OperationalError as e:# 错误代码 1049 表示数据库不存在if e.args[0] == 1049:print(f"数据库 '{DB_CONFIG['database']}' 不存在,正在创建...")self._create_database()# 创建后重新尝试连接self.connection = pymysql.connect(**DB_CONFIG)print("数据库连接成功")else:print(f"数据库连接失败: {e}")raiseexcept Exception as e:print(f"数据库连接失败: {e}")raisedef _create_database(self):"""创建数据库"""# 创建一个不指定数据库的临时连接配置temp_config = DB_CONFIG.copy()if 'database' in temp_config:del temp_config['database']try:# 连接 MySQL 服务(不指定数据库)conn = pymysql.connect(**temp_config)with conn.cursor() as cursor:db_name = DB_CONFIG['database']cursor.execute(f"CREATE DATABASE IF NOT EXISTS {db_name} DEFAULT CHARSET utf8mb4")conn.commit()conn.close()print(f"数据库 '{db_name}' 创建成功")except Exception as e:print(f"创建数据库失败: {e}")raisedef create_table(self):"""创建股票数据表"""create_table_sql = """CREATE TABLE IF NOT EXISTS stock_data (id INT AUTO_INCREMENT PRIMARY KEY,stock_code VARCHAR(20) NOT NULL COMMENT '股票代码',stock_name VARCHAR(100) COMMENT '股票名称',latest_price DECIMAL(10,4) COMMENT '最新报价',change_percent DECIMAL(8,4) COMMENT '涨跌幅(%)',change_amount DECIMAL(10,4) COMMENT '涨跌额',volume BIGINT COMMENT '成交量(手)',turnover DECIMAL(15,2) COMMENT '成交额(万元)',amplitude DECIMAL(8,4) COMMENT '振幅(%)',high_price DECIMAL(10,4) COMMENT '最高价',low_price DECIMAL(10,4) COMMENT '最低价',open_price DECIMAL(10,4) COMMENT '今开',close_price DECIMAL(10,4) COMMENT '昨收',plate_type VARCHAR(20) COMMENT '板块类型',crawl_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,UNIQUE KEY unique_stock_plate (stock_code, plate_type)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='股票数据表';"""try:with self.connection.cursor() as cursor:cursor.execute(create_table_sql)self.connection.commit()print("数据表创建成功")except Exception as e:print(f"创建数据表失败: {e}")def insert_stock_data(self, stock_data):"""插入股票数据"""insert_sql = """INSERT INTO stock_data (stock_code, stock_name, latest_price, change_percent, change_amount,volume, turnover, amplitude, high_price, low_price, open_price, close_price, plate_type) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)ON DUPLICATE KEY UPDATEstock_name = VALUES(stock_name),latest_price = VALUES(latest_price),change_percent = VALUES(change_percent),change_amount = VALUES(change_amount),volume = VALUES(volume),turnover = VALUES(turnover),amplitude = VALUES(amplitude),high_price = VALUES(high_price),low_price = VALUES(low_price),open_price = VALUES(open_price),close_price = VALUES(close_price),crawl_time = CURRENT_TIMESTAMP"""try:with self.connection.cursor() as cursor:cursor.execute(insert_sql, stock_data)self.connection.commit()return Trueexcept Exception as e:print(f"插入数据失败: {e}")self.connection.rollback()return Falsedef close(self):"""关闭数据库连接"""if self.connection:self.connection.close()print("数据库连接已关闭")
--------------------------------------------------
view_data.py
以下代码用于连接数据库查询已存储的股票数据,并通过自定义的格式化函数处理中英文对齐,最终在终端以整齐的表格形式展示数据以便预览。
--------------------------------------------------
点击查看代码
# -*- coding: utf-8 -*-
"""
查看股票数据库内容
"""
import pymysql
from config import DB_CONFIGdef get_display_width(s):width = 0for char in s:if ord(char) > 256:width += 2else:width += 1return widthdef format_cell(text, width):text = str(text) if text is not None else ""text = text.replace('\n', ' ').replace('\r', '')display_width = get_display_width(text)if display_width > width:while get_display_width(text + "..") > width and len(text) > 0:text = text[:-1]text += ".."display_width = get_display_width(text)return text + " " * (width - display_width)def view_data():conn = Nonetry:conn = pymysql.connect(**DB_CONFIG)cursor = conn.cursor()# 查询所有数据sql = """SELECT id, stock_code, stock_name, latest_price, change_percent, change_amount, volume, turnover, amplitude, plate_type FROM stock_data LIMIT 50"""cursor.execute(sql)results = cursor.fetchall()if not results:print("数据库中暂无数据,请先运行 main.py 进行爬取。")returnprint(f"\n{'='*20} 股票数据库内容预览 (前50条) {'='*20}")print(f"总共找到 {len(results)} 条记录\n")# 定义列配置 (列名, 宽度)columns = [("ID", 4),("代码", 8),("名称", 12),("最新价", 8),("涨跌幅", 8),("涨跌额", 8),("成交量", 10),("成交额", 12),("振幅", 8),("板块", 10)]# 打印表头header_line = ""for col_name, width in columns:header_line += format_cell(col_name, width) + " "print(header_line)print("-" * len(header_line))# 打印数据行for row in results:line = ""# 确保数据项与列配置一一对应row_data = [row[0], # IDrow[1], # 代码row[2], # 名称row[3], # 最新价row[4], # 涨跌幅row[5], # 涨跌额row[6], # 成交量row[7], # 成交额row[8], # 振幅row[9] # 板块]for i, val in enumerate(row_data):width = columns[i][1]line += format_cell(val, width) + " "print(line)except Exception as e:print(f"查询失败: {e}")finally:if conn:conn.close()if __name__ == "__main__":view_data()
--------------------------------------------------
- 输出结果:

view_data.py下的代码输出。

套用数据库后对前20行数据的输出。
- 心得体会:
通过这次实践,我深刻体会到网络爬虫不仅是代码的编写,更是对目标网站逻辑的解构与重组。从解决 Selenium 驱动配置到应对动态网页的结构变化,我学会了灵活运用显式等待、URL 跳转等策略来提升爬虫的稳定性,而不是死板地模拟点击。
作业2:
- 要求:
▪ 熟练掌握 Selenium 查找HTML元素、实现用户模拟登录、爬取Ajax网页数据、
等待HTML元素等内容。
▪ 使用Selenium框架+MySQL爬取中国mooc网课程资源信息(课程号、课程名
称、学校名称、主讲教师、团队成员、参加人数、课程进度、课程简介)
▪ 候选网站:中国mooc网:https://www.icourse163.org
▪ 输出信息:MYSQL数据库存储和输出格式
• Gitee文件夹链接:
https://gitee.com/sui123feng/20251015/tree/master/102302142罗伟钊_实践4/2
- 导入库:
selenium:自动化测试工具,用于模拟浏览器行为,抓取动态加载的股票数据
pymysql:Python 的 MySQL 驱动,用于连接数据库、创建表及存储爬取的数据
time:时间处理模块,用于设置强制等待,确保页面元素加载完成
os:操作系统接口模块,用于获取当前文件路径,定位本地的 chromedriver.exe
re:正则表达式模块,用于清洗文本数据
- 核心思路:

这里通过手动的到达“我的课程”界面,极大的便利了爬取相关信息的难度。
- 代码内容:
database.py
以下代码负责管理 MySQL 数据库连接和初始化,包括自动创建数据库与表结构,并将爬取到的课程数据持久化存储到数据库中。
--------------------------------------------------
点击查看代码
# -*- coding: utf-8 -*-
"""
数据库操作模块
"""
import pymysql
from config import DB_CONFIGclass DatabaseManager:def __init__(self):self.connection = Noneself.connect()self.create_table()def connect(self):"""连接数据库,如果不存在则创建"""try:self.connection = pymysql.connect(**DB_CONFIG)print("数据库连接成功")except pymysql.err.OperationalError as e:if e.args[0] == 1049:print(f"数据库 '{DB_CONFIG['database']}' 不存在,正在创建...")self._create_database()self.connection = pymysql.connect(**DB_CONFIG)print("数据库连接成功")else:raiseexcept Exception as e:print(f"数据库连接失败: {e}")raisedef _create_database(self):"""创建数据库"""temp_config = DB_CONFIG.copy()if 'database' in temp_config:del temp_config['database']conn = pymysql.connect(**temp_config)with conn.cursor() as cursor:cursor.execute(f"CREATE DATABASE IF NOT EXISTS {DB_CONFIG['database']} DEFAULT CHARSET utf8mb4")conn.commit()conn.close()def create_table(self):"""创建课程数据表"""# Id, cCourse, cCollege, cTeacher, cTeam, cCount, cProcess, cBriefsql = """CREATE TABLE IF NOT EXISTS course_info (id INT AUTO_INCREMENT PRIMARY KEY,cCourse VARCHAR(255) NOT NULL COMMENT '课程名称',cCollege VARCHAR(100) COMMENT '学校名称',cTeacher VARCHAR(100) COMMENT '主讲教师',cTeam TEXT COMMENT '团队成员',cCount VARCHAR(50) COMMENT '参加人数',cProcess VARCHAR(100) COMMENT '课程进度',cBrief TEXT COMMENT '课程简介',crawl_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,UNIQUE KEY unique_course (cCourse, cCollege)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='MOOC课程信息';"""try:with self.connection.cursor() as cursor:cursor.execute(sql)self.connection.commit()except Exception as e:print(f"创建表失败: {e}")def insert_course(self, data):"""插入课程数据"""sql = """INSERT INTO course_info (cCourse, cCollege, cTeacher, cTeam, cCount, cProcess, cBrief) VALUES (%s, %s, %s, %s, %s, %s, %s)ON DUPLICATE KEY UPDATEcTeacher = VALUES(cTeacher),cTeam = VALUES(cTeam),cCount = VALUES(cCount),cProcess = VALUES(cProcess),cBrief = VALUES(cBrief),crawl_time = CURRENT_TIMESTAMP"""try:with self.connection.cursor() as cursor:cursor.execute(sql, (data.get('cCourse'),data.get('cCollege'),data.get('cTeacher'),data.get('cTeam'),data.get('cCount'),data.get('cProcess'),data.get('cBrief')))self.connection.commit()return Trueexcept Exception as e:print(f"插入数据失败: {e}")return Falsedef close(self):if self.connection:self.connection.close()
--------------------------------------------------
view_data.py
以下代码用于连接数据库查询已存储的课程数据,并通过自定义的格式化函数处理中英文对齐,最终在终端以整齐的表格形式展示数据以便预览。
--------------------------------------------------
点击查看代码
# -*- coding: utf-8 -*-
"""
查看数据库内容
"""
import pymysql
from config import DB_CONFIGdef get_display_width(s):width = 0for char in s:if ord(char) > 256:width += 2else:width += 1return widthdef format_cell(text, width):text = str(text) if text else ""text = text.replace('\n', ' ').replace('\r', '')display_width = get_display_width(text)if display_width > width:while get_display_width(text + "..") > width and len(text) > 0:text = text[:-1]text += ".."display_width = get_display_width(text)return text + " " * (width - display_width)def view_data():conn = Nonetry:conn = pymysql.connect(**DB_CONFIG)cursor = conn.cursor()# 查询所有数据sql = "SELECT id, cCourse, cCollege, cTeacher, cTeam, cCount, cProcess, cBrief FROM course_info"cursor.execute(sql)results = cursor.fetchall()if not results:print("数据库中暂无数据,请先运行 main.py 进行爬取。")returnprint(f"\n{'='*20} 数据库内容预览 {'='*20}")print(f"总共找到 {len(results)} 条记录\n")# 定义列配置 (列名, 宽度)columns = [("ID", 3),("课程名称", 18),("学校", 12),("讲师", 8),("团队成员", 10),("人数", 10),("进度", 10),("简介", 30)]# 打印表头header_line = ""for col_name, width in columns:header_line += format_cell(col_name, width) + " "print(header_line)print("-" * len(header_line))# 打印数据行for row in results:line = ""# 确保数据项与列配置一一对应row_data = [row[0], # IDrow[1], # 课程名称row[2], # 学校row[3], # 讲师row[4], # 团队成员row[5], # 人数row[6], # 进度row[7] # 简介]for i, val in enumerate(row_data):width = columns[i][1]line += format_cell(val, width) + " "print(line)except Exception as e:print(f"查询失败: {e}")finally:if conn:conn.close()if __name__ == "__main__":view_data()
--------------------------------------------------
- 输出结果:

以上即为“我的课程”上的部分内容。
- 心得体会:
通过这次实践,将杂乱的网页数据经过清洗、转换并规范化存储到 MySQL 数据库的过程,让我真正理解了从数据获取到数据持久化的全链路开发。
作业3:
- 要求:
• 掌握大数据相关服务,熟悉Xshell的使用
• 完成文档 华为云_大数据实时分析处理实验手册-Flume日志采集实验(部分)v2.docx 中的任务,即为下面5个任务,具体操作见文档。

进入Python脚本所在目录,执行python脚本,生成一份数据。

执行命令,解压文件,并安装Kafka。

在kafka中创建topic,查看topic信息。

下载Flume客户端。
- 心得体会:
本实验让我系统性实践了从数据生成、传输到采集的全链路技术栈。通过Xshell高效操作远程服务器,不仅巩固了Linux命令熟练度,更深化了对大数据组件协同工作的理解。未来可进一步探索Flume拦截器对数据的预处理能力,以及Kafka在实时流处理中的深度融合应用。