Python实验1

您所在的位置:网站首页 动态网页爬取实验总结 Python实验1

Python实验1

2024-07-12 04:01| 来源: 网络整理| 查看: 265

Python实验1——网络爬虫及数据可视化

文章目录 Python实验1——网络爬虫及数据可视化前言1. 实验目标与基本要求1.1 实验目标1.2 基本要求 2. 主要知识点、重点与难点2.1 主要知识点2.2 重点2.3 难点 3. 实验过程设计3.1 实验设计流程图3.2 数据获取与处理3.2.1 龙虎榜数据3.2.1.1 获取网页静态文本3.2.1.2 获取需要的数据3.2.1.3 存储到数据库中 3.2.2 个股数据获取与处理3.2.2.1 获取网页静态文本3.2.2.2 获取需要的数据3.2.2.3 存储到数据库中 3.3 数据的展示3.3.1 表格的展示3.3.2 龙虎榜图表3.3.3 股票季度K线图表3.3.4 [通过机器学习进行股票预测](https://www.cnblogs.com/JavaArchitect/p/13489328.html) 3.4 GUI界面设计4 优势与不足4.1 优势4.2 不足 5. 收获与心得4 优势与不足4.1 优势4.2 不足 5. 收获与心得

前言

本文参考了这篇和那篇,算是综合了这两篇的一些特性吧,给需要做爬虫实验的同学一些参考和学习的资料……

1. 实验目标与基本要求 1.1 实验目标

开发网络爬虫在东方财富、新浪财经或者纳斯达克等财经网站上爬取一只股票的每天的开盘价,收盘价,最高价,最低价等信息,并存储在数据库中,并开发GUI应用可视化。

1.2 基本要求

(1) 掌握网络爬虫的开发方法; (2) 掌握Python开发数据库的GUI界面; (3) 掌握Matplotlib绘制股票的K线图;

2. 主要知识点、重点与难点 2.1 主要知识点

(1) 网络爬虫的基本知识; (2) 利用正则表达式对网页信息提取; (3) 数据库的访问和表中的数据操作; (4) Matplotlib库的使用。

2.2 重点

(1) 网络爬虫框架的使用; (2) 正则表达式的使用; (3) 数据库存储数据。

2.3 难点

(1) 利用正则表达式根据网页中的信息组织方式提取数据; (2) K线图的展现。

3. 实验过程设计 3.1 实验设计流程图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bT7hVOsU-1652889457181)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220516124202152.png)]

3.2 数据获取与处理 3.2.1 龙虎榜数据

获取龙虎榜数据主要通过以下几个函数:

''' 文件中的函数和简单功能描述: get_html: 获得一个请求得到的静态网页 get_data: 编写正则表达式获取信息,形成列表 storage: 将爬取的信息存储到数据库中 clear_data: 清洗全局变量 do_lhbProcessment: 启动龙虎榜数据获取与处理 ''' 3.2.1.1 获取网页静态文本 # 获取静态网页的文本 def get_html(): data = requests.get('https://data.eastmoney.com/stock/lhb.html', {"user-agent": "Mozilla/5.0"}) return data.text

爬取的网站是东方财富的龙虎榜数据,因为不涉及个股,所以直接输入网站即可获取完整的龙虎榜数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bR426axs-1652889457182)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220516201412196.png)]

为了便于下面的数据处理,我们返回网页的静态文本。

3.2.1.2 获取需要的数据

查看网页的源码,我们发现数据存储在head的script中,通过调用soup,我们获取一个含有龙虎榜数据的字符串:

在这里插入图片描述

然而,这一行数据中还是有许多我们不需要的信息。所以,我们还要编写正则表达式,对股票名,股票代码,涨跌率等数据进行进一步的爬取,完整代码如下:

# 编写正则表达式获取信息,形成列表 def get_data(text): soup = BeautifulSoup(text, "html.parser") tmp_list = soup.find("head").find_all("script")[1:] tmp_str = tmp_list[0].text[72:] print(tmp_str) # 获得龙虎榜股票数量 p1 = r'"count":.+?(?=})' match_count = re.search(p1, tmp_str) num = int(match_count.group()[8:]) print(num) # 获取龙虎榜更新日期 p1 = r'"TRADE_DATE":".+?(?= )' match_count = re.search(p1, tmp_str) global date date = match_count.group()[14:] print(date) # 获取股票名字 p1 = r'"SECURITY_NAME_ABBR":".+?(?=")' match_list1 = re.findall(p1, tmp_str) for i in range(num): if ' ' in match_list1[i]: break name_list.append((match_list1[i][22:])) print(name_list) # 获取股票涨跌率 p1 = r'"CHANGE_RATE":.+?(?=,)' match_list1 = re.findall(p1, tmp_str) for i in range(num): change_rate_list.append(float(match_list1[i][14:])) print(change_rate_list) # 获取交易市场代码 p1 = r'"TRADE_MARKET_CODE":.+?(?=")' match_list1 = re.findall(p1, tmp_str) for i in range(num): trade_market_code_list.append(match_list1[i][21:]) print(trade_market_code_list) # 获取股票代码 p1 = r'"SECURITY_CODE":.+?(?=")' match_list1 = re.findall(p1, tmp_str) for i in range(num): stock_code_list.append(match_list1[i][17:]) print(stock_code_list) # 获得总的字典列表 tmp_list1 = [] tmp_list2 = [] for i in range(num): tmp_dic = {"日期": date, "涨跌率": change_rate_list[i], "交易市场代码": trade_market_code_list[i], "股票代码": stock_code_list[i]} if tmp_dic["股票代码"][0] == '8': continue tmp_dict = {"股票名": name_list[i], "日期": date, "涨跌率": change_rate_list[i], "交易市场代码": trade_market_code_list[i], "股票代码": stock_code_list[i]} tmp_list1.append(tmp_dict) tmp_list2.append(tmp_dic) global total_data_list global sql_data_list print(total_data_list) total_data_list = sorted(tmp_list1, key=lambda list1: -list1["涨跌率"]) sql_data_list = sorted(tmp_list2, key=lambda list1: -list1["涨跌率"]) 3.2.1.3 存储到数据库中

接下来,我们将处理好的数据存入数据库中,利用sqlalchemy的create_engine以及pandas的to_sql,我们可以很方便地实现数据库的存储。

# 存储到数据库中 def storage(): connect_str = "mysql+pymysql://root:" + password + "@localhost/stockData?charset=utf8" con = create_engine(connect_str, echo=True, encoding='utf8') df = pd.DataFrame(sql_data_list) df.to_sql('lhb-{}'.format(date), con=con, if_exists='replace', index=False) 3.2.2 个股数据获取与处理

获取个股数据主要通过以下几个函数:

''' 文件中的函数和简单功能描述: get_html: 获得一个请求得到的静态网页 get_data: 将HTML文本转化成字典列表 storage: 将爬取的信息存储到数据库中 data_pretreatment: 为画K线图做数据处理,将五个数据分别放进五个列表中 clear_data: 清洗全局变量 do_DataProcessment: 启动个股数据获取与处理 ''' 3.2.2.1 获取网页静态文本

爬取的网站是网易财经的股票历史交易记录。经过观察发现,不同股票历史交易记录的区别在于中间的一段股票代码,然后是年份以及季度,于是通过输入股票代码,年份和季度来获取指定股票的交易网页。(下图以中国平安为例)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HKReaDTo-1652889457183)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220516203302894.png)]

为了便于下面的数据处理,我们返回网页的静态文本。

3.2.2.2 获取需要的数据

同样还是以中国平安为例,查看网页的源码,发现所需要的标签存储在inner_box下面的"table_bg001 border_box limit_sale"之中,通过beautifulSoup下面的find()方法即可找到标签。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hf2RJW9r-1652889568101)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220516203503799.png)]

由于这个网站的数据通过标签分隔开了,我们可以直接通过find_all()来获取数据,无需编取复杂的正则表达式。

# 将HTML文本转化成字典列表 # text: 待处理HTML文本 # total_data_list: 存储{日期,开盘价,收盘价……}信息的字典列表 def get_data(text): monthDataList = [] soup = BeautifulSoup(text, "html.parser") tmp_list = soup.find("div", "inner_box").find("table", "table_bg001 border_box limit_sale") # print(type(tmp_list)) data_list = tmp_list.find_all("tr")[1:] print(data_list) with open("data.txt", "w") as f: for item in data_list: kv = {} tdList = item.find_all("td") kv["日期"] = tdList[0].text kv["开盘价"] = tdList[1].text kv["最高价"] = tdList[2].text kv["最低价"] = tdList[3].text kv["收盘价"] = tdList[4].text kv["成交量"] = tdList[7].text monthDataList.append(kv) to_write = json.dumps(kv, ensure_ascii=False) f.write(to_write) global total_data_list total_data_list = sorted(monthDataList, key=lambda list1: list1["日期"]) 3.2.2.3 存储到数据库中

基本操作与前面的相似,只是将表名修改一下即可。

# 将爬取的信息存储到数据库中 # data: 需要存储的信息 # name: 数据表名 def storage(name, year, quarter): print(total_data_list) connect_str = "mysql+pymysql://root:" + password + "@localhost/stockData?charset=utf8" con = create_engine(connect_str, echo=True) df = pd.DataFrame(total_data_list) df.to_sql('{}-{}-{}'.format(name, year, quarter), con=con, if_exists='replace', index=False) 3.3 数据的展示 3.3.1 表格的展示

通过上面处理好的数据,我们可以对数据进行展示,其中比较直接的方法就是使用二维表的方式显示数据,我们通过wx.grid.Grid中的表格对象对龙虎榜数据和个股数据在GUI界面进行展示,以下是代码:

# 生成个股数据表 def create_grid(self): data0 = SingleStockProcessing.total_data_list my_list = [] for item in data0: tmp = list(item.values()) my_list.append(tmp) data = my_list for row in range(len(data)): for col in range(len(data[row])): self.grid.SetCellValue(row, col, str(data[row][col])) # 生成龙虎榜数据表 def create_grid1(self): data0 = DragonTigerProcessing.total_data_list column_names = ['股票名称', '日期', '涨跌率', '交易市场代码', '股票代码'] my_list = [] for item in data0: tmp = list(item.values()) my_list.append(tmp) data = my_list self.grid1 = wx.grid.Grid(parent=self.panel, pos=(50, 130), size=(600, 600)) self.grid1.CreateGrid(len(data), len(data[0])) self.grid1.EnableEditing(False) for row in range(len(data)): for col in range(len(data[row])): self.grid1.SetColLabelValue(col, column_names[col]) self.grid1.SetCellValue(row, col, str(data[row][col])) self.grid1.SetColSize(1, 120) self.grid1.SetColSize(3, 140)

以下是表格数据的示例左边是龙虎榜数据,右边是个股数据:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hTFC5HPX-1652889457184)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220516204844895.png)]

3.3.2 龙虎榜图表

我们将爬取到的龙虎榜数据加工成图表,主要调用的库是pyecharts,为了区分涨跌,使用了JavaScript根据数值大于还是小于0进行不同的着色,代码如下:

# 绘制龙虎榜图表 def draw_lhb(): tmp1 = [] tmp2 = [] l1 = DragonTigerProcessing.name_list l2 = DragonTigerProcessing.change_rate_list for i in range(len(l1)): if DragonTigerProcessing.stock_code_list[i][0] == '8': continue tmp1.append(l1[i]) tmp2.append(l2[i]) bar = ( Bar(init_opts=opts.InitOpts(theme=ThemeType.WESTEROS)) .add_xaxis(tmp1) .add_yaxis("龙虎榜", tmp2, category_gap=2, itemstyle_opts=opts.ItemStyleOpts( color=JsCode( """ function(params) { var colorList; if (params.data >= 0) { colorList = '#FF4500'; } else { colorList = '#14b143'; } return colorList; } """ ) ) ) .set_global_opts( xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-60), name="股票名"), title_opts=opts.TitleOpts(title="龙虎榜"), yaxis_opts=opts.AxisOpts(name="涨跌率"), ) .set_series_opts( label_opts=opts.LabelOpts(is_show=False), markpoint_opts=opts.MarkPointOpts( data=[ opts.MarkPointItem(type_="min", name="最小值"), opts.MarkPointItem(type_="max", name="最大值"), opts.MarkPointItem(type_="average", name="平均值"), ] ), ) ) bar.render("龙虎图.html")

绘制出的柱状图效果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W6ycCoud-1652889457185)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220516205659810.png)]

3.3.3 股票季度K线图表

我们将爬取到的个股数据加工成图表,主要调用的库同样是pyecharts,通过overlap()函数实现图线的重叠,可以在一张K线图上同时显示最高价,最低价等信息,方便用户进行查询,代码如下:

# 绘制K线图 def draw_K(): kline = Kline().set_global_opts(title_opts=opts.TitleOpts(title="K线图")) v1 = [] size = len(SingleStockProcessing.opening_price) # 有多少条数据(多少天) opening_price = SingleStockProcessing.opening_price closing_price = SingleStockProcessing.closing_price lowest_price = SingleStockProcessing.lowest_price highest_price = SingleStockProcessing.highest_price date = SingleStockProcessing.date for i in range(0, size): tmp = [opening_price[i], closing_price[i], lowest_price[i], highest_price[i]] v1.append(tmp) # 整合好一组数据存入v1中 # print(v1) kline.add_yaxis(series_name="日均K线", y_axis=v1) kline.add_xaxis([s for s in date]) c = ( Line() .add_xaxis(date) .add_yaxis('最低价', lowest_price, itemstyle_opts=opts.ItemStyleOpts(color='green')) .add_yaxis('最高价', highest_price, itemstyle_opts=opts.ItemStyleOpts(color='red')) .add_yaxis('开盘价', opening_price, itemstyle_opts=opts.ItemStyleOpts(color='blue')) .add_yaxis('收盘价', closing_price, itemstyle_opts=opts.ItemStyleOpts(color='orange')) .set_series_opts( # 是否显示标签 label_opts=opts.LabelOpts(is_show=False), # 标注点数据项 markpoint_opts=opts.MarkPointOpts( data=[opts.MarkPointItem(type_="max", name="max"), opts.MarkPointItem(type_="min", name="min")] ), markline_opts=opts.MarkLineOpts (data=[opts.MarkLineItem(name="average", type_="average")]) ) .set_global_opts( xaxis_opts=opts.AxisOpts(name_rotate=-60), yaxis_opts=opts.AxisOpts(name="价格:元/股") ) ) kline.overlap(c) kline.render("K线图.html")

绘制出的折线图效果如下:

在这里插入图片描述

3.3.4 通过机器学习进行股票预测

我们将爬取到的个股数据通过sklearn库中的线性回归方法,进行简单的机器学习,其中训练集为一个季度的前95%天,而测试集是后5%天,代码如下:

# 通过机器学习进行股票预测 def do_PredictStockData(): origDf = pd.DataFrame(SingleStockProcessing.total_data_list) predicted_frame = origDf[['开盘价', '最高价', '最低价', '收盘价', '成交量']] featureData = predicted_frame[['开盘价', '最高价', '最低价', '成交量']] # 划分特征值和目标值 feature = featureData.values for i in range(len(feature)): for j in range(len(feature[0])): if j == 3: print(feature[i][j]) feature[i][j] = feature[i][j].replace(',', '') feature[i][j] = float(feature[i][j]) print(feature) target = np.array(predicted_frame['收盘价']) for i in range(len(target)): target[i] = float(target[i]) print(target) # 划分训练集,测试集 feature_train, feature_test, target_train, target_test = train_test_split(feature, target, test_size=0.05) predicted_days = int(math.ceil(0.05 * len(origDf))) # 预测天数 lrTool = LinearRegression() lrTool.fit(feature_train, target_train) # 训练 # 用测试集预测结果 predict_by_test = lrTool.predict(feature_test) print(predict_by_test) index = 0 global predicted_list predicted_list = [] while index


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3