102302142罗伟钊第四次作业
作业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_CONFIG
class DatabaseManager:
def __init__(self):
self.connection = None
self.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}")
raise
except Exception as e:
print(f"数据库连接失败: {e}")
raise
def _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}")
raise
def 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 UPDATE
stock_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 True
except Exception as e:
print(f"插入数据失败: {e}")
self.connection.rollback()
return False
def close(self):
"""关闭数据库连接"""
if self.connection:
self.connection.close()
print("数据库连接已关闭")
--------------------------------------------------
view_data.py
以下代码用于连接数据库查询已存储的股票数据,并通过自定义的格式化函数处理中英文对齐,最终在终端以整齐的表格形式展示数据以便预览。
--------------------------------------------------
点击查看代码
# -*- coding: utf-8 -*-
"""
查看股票数据库内容
"""
import pymysql
from config import DB_CONFIG
def get_display_width(s):
width = 0
for char in s:
if ord(char) > 256:
width += 2
else:
width += 1
return width
def 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 = None
try:
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 进行爬取。")
return
print(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], # ID
row[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_CONFIG
class DatabaseManager:
def __init__(self):
self.connection = None
self.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:
raise
except Exception as e:
print(f"数据库连接失败: {e}")
raise
def _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, cBrief
sql = """
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 UPDATE
cTeacher = 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 True
except Exception as e:
print(f"插入数据失败: {e}")
return False
def close(self):
if self.connection:
self.connection.close()
--------------------------------------------------
view_data.py
以下代码用于连接数据库查询已存储的课程数据,并通过自定义的格式化函数处理中英文对齐,最终在终端以整齐的表格形式展示数据以便预览。
--------------------------------------------------
点击查看代码
# -*- coding: utf-8 -*-
"""
查看数据库内容
"""
import pymysql
from config import DB_CONFIG
def get_display_width(s):
width = 0
for char in s:
if ord(char) > 256:
width += 2
else:
width += 1
return width
def 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 = None
try:
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 进行爬取。")
return
print(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], # ID
row[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在实时流处理中的深度融合应用。
浙公网安备 33010602011771号