百度松果菁英班——机器学习实践六:股票行情爬取与分析
飞桨AI Studio星河社区-人工智能学习与实训社区
这篇文章好像有点大,所以上边网页点进去是看不到的,进入环境之后就能看了
🥪必要包的下载导入
!pip install fake_useragent !pip install bs4 !cp /home/aistudio/simhei.ttf /opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/ttf/ !cp /home/aistudio/simhei.ttf .fonts/ !rm -rf .cache/matplotlib
🥪股票信息爬取
#coding=utf-8 ''' Created on 2021年02月20日 @author: zhongshan ''' #http://quote.eastmoney.com/center/gridlist.html #爬取该页面股票信息 import requests from fake_useragent import UserAgent from bs4 import BeautifulSoup import json import csv def getHtml(url): r = requests.get(url,headers={ 'User-Agent': UserAgent().random, }) r.encoding = r.apparent_encoding return r.text #num为爬取多少条记录,可手动设置 num = 20 #该地址为页面实际获取数据的接口地址 stockUrl='http://99.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112408733409809437476_1623137764048&pn=1&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&fs=m:0+t:80&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1623137764167:formatted' if __name__ == '__main__': responseText = getHtml(stockUrl) jsonText = responseText.split("(")[1].split(")")[0]; resJson = json.loads(jsonText) datas = resJson["data"]["diff"] datalist = [] for data in datas: # if (str().startswith('6') or str(data["f12"]).startswith('3') or str(data["f12"]).startswith('0')): row = [data["f12"],data["f14"]] datalist.append(row) print(datalist) f =open('stock.csv','w+',encoding='utf-8',newline="") writer = csv.writer(f) writer.writerow(('代码', '名称')) for data in datalist: writer.writerow((data[0]+"\t",data[1]+"\t")) f.close()
-
定义了一个函数getHtml(url),用于获取指定URL页面的HTML内容。使用requests.get()方法发送GET请求,通过fake_useragent生成随机的User-Agent来伪装请求头,避免被网站封禁IP。然后设置编码为页面的apparent_encoding,确保编码正确
-
设置要爬取的记录条数num
-
定义了变量stockUrl,该地址为页面实际获取数据的接口地址。通过该接口地址可以获取股票信息的JSON数据
-
在主程序中,调用getHtml(stockUrl)方法获取页面的HTML内容
-
解析HTML内容,提取出JSON数据。首先使用split()方法分割字符串,提取出JSON文本部分。然后使用json.loads()方法将JSON文本解析为Python字典
-
从解析后的JSON数据中提取股票信息,并存储到列表datalist中
-
打开文件stock.csv,使用CSV模块创建一个写入对象writer,将股票信息写入CSV文件中
-
遍历datalist列表,将每条股票信息写入CSV文件中
-
关闭CSV文件
🥪多线程并发下载股票数据文件并存储为CSV格式
import csv import urllib.request as r import threading #读取之前获取的个股csv丢入到一个列表中 def getStockList(): stockList = [] f = open('stock.csv','r',encoding='utf-8') f.seek(0) reader = csv.reader(f) for item in reader: stockList.append(item) f.close() return stockList def downloadFile(url,filepath): # print(filepath) try: r.urlretrieve(url,filepath) except Exception as e: print(e) print(filepath,"is downloaded") pass #设置信号量,控制线程并发数 sem = threading.Semaphore(1) def downloadFileSem(url,filepath): with sem: downloadFile(url,filepath) urlStart = 'http://quotes.money.163.com/service/chddata.html?code=' urlEnd = '&end=20210221&fields=TCLOSE;HIGH;LOW;TOPEN;LCLOSE;CHG;PCHG;VOTURNOVER;VATURNOVER' if __name__ == '__main__': stockList = getStockList() stockList.pop(0) print(stockList) for s in stockList: scode = str(s[0].split("\t")[0]) #0:沪市;1:深市 url = urlStart + ("0" if scode.startswith('6') else "1") + scode + urlEnd print(url) filepath = (str(s[1].split("\t")[0])+"_"+scode) + ".csv" threading.Thread(target=downloadFileSem,args=(url,filepath)).start()
-
定义了一个新的函数getStockList(),用于从之前获取的个股CSV文件中读取数据,并将其存储到一个列表中。通过csv.reader()方法逐行读取CSV文件,并将每一行数据存储为一个列表,最后将所有列表存储到stockList中
-
定义了一个新的函数downloadFile(url, filepath),用于下载文件。通过urllib.request.urlretrieve()方法下载指定URL的文件,并保存到指定的路径
-
引入了threading模块,用于创建线程实现多线程下载
-
定义了一个信号量sem,用于控制线程并发数。在多线程环境下,为了避免资源竞争和死锁,可以使用信号量来限制同时执行的线程数量
-
定义了一个新的函数downloadFileSem(url, filepath),在该函数中使用了信号量sem来限制并发数,然后调用downloadFile()函数下载文件
-
修改了urlStart和urlEnd变量,用于构造下载文件的URL。根据个股代码的首位数字(0表示沪市,1表示深市),选择对应的交易所代码
-
在主程序中,获取之前获取的个股列表stockList,然后依次遍历每个股票信息
-
对于每个股票信息,提取股票代码和名称,并构造对应的下载URL和文件路径
-
创建一个新的线程,通过threading.Thread()方法传入目标函数downloadFileSem和参数,启动线程并进行下载
🥪股票信息分析
import pandas as pd import matplotlib.pyplot as plt import csv # 设置显示中文 plt.rcParams['font.sans-serif'] = ['simhei'] # 指定默认字体 plt.rcParams['axes.unicode_minus']=False # 用来显示负号 plt.rcParams['figure.dpi'] = 100 # 每英寸点数 files = [] # ['日期' '股票代码' '名称' '收盘价' '最高价' '最低价' '开盘价' '前收盘' '涨跌额' '涨跌幅' '成交量' '成交金额'] def read_file(file_name): data = pd.read_csv(file_name,encoding='gbk') col_name = data.columns.values return data, col_name def get_files_path(): stock_list=getStockList() paths = [] for stock in stock_list[1:]: p = stock[1].strip()+"_"+stock[0].strip()+".csv" print(p) data,_ = read_file(p) if len(data)>1: files.append(p) print(p) get_files_path() print(files) # 获取股票的涨跌额及涨跌幅度变化曲线 # ['日期' '股票代码' '名称' '收盘价' '最高价' '最低价' '开盘价' '前收盘' '涨跌额' '涨跌幅' '成交量' '成交金额'] def get_diff(file_name): data, col_name = read_file(file_name) index = len(data['日期'])-1 sep = index//15 plt.figure(figsize=(15,17)) x = data['日期'].values.tolist() x.reverse() # x = x[-index:] xticks=list(range(0,len(x),sep)) xlabels=[x[i] for i in xticks] xticks.append(len(x)) # xlabels.append(x[-1]) y1 = [float(c) if c!='None' else 0 for c in data['涨跌额'].values.tolist()] y2=[float(c) if c!='None' else 0 for c in data['涨跌幅'].values.tolist()] y1.reverse() y2.reverse() # y1 = y1[-index:] # y2 = y2[-index:] ax1 = plt.subplot(211) plt.plot(range(1,len(x)+1),y1,c='r') plt.title('{}-涨跌额/涨跌幅'.format(file_name.split('_')[0]),fontsize=20) ax1.set_xticks(xticks) ax1.set_xticklabels(xlabels, rotation=40) # plt.xlabel('日期') plt.ylabel('涨跌额',fontsize=20) ax2 = plt.subplot(212) plt.plot(range(1,len(x)+1),y2,c='g') # plt.title('{}-涨跌幅'.format(file_name.split('_')[0])) ax2.set_xticks(xticks) ax2.set_xticklabels(xlabels, rotation=40) plt.xlabel('日期',fontsize=20) plt.ylabel('涨跌幅',fontsize=20) plt.savefig('work/'+file_name.split('.')[0]+'_diff.png') plt.show() def get_max_min(file_name): data, col_name = read_file(file_name) index = len(data['日期'])-1 sep = index//15 plt.figure(figsize=(15,10)) x = data['日期'].values.tolist() x.reverse() x = x[-index:] xticks=list(range(0,len(x),sep)) xlabels=[x[i] for i in xticks] xticks.append(len(x)) # xlabels.append(x[-1]) y1 = [float(c) if c!='None' else 0 for c in data['最高价'].values.tolist()] y2=[float(c) if c!='None' else 0 for c in data['最低价'].values.tolist()] y1.reverse() y2.reverse() y1 = y1[-index:] y2 = y2[-index:] ax = plt.subplot(111) plt.plot(range(1,len(x)+1),y1,c='r',line) plt.plot(range(1,len(x)+1),y2,c='g',line) plt.title('{}-最高价/最低价'.format(file_name.split('_')[0]),fontsize=20) ax.set_xticks(xticks) ax.set_xticklabels(xlabels, rotation=40) plt.xlabel('日期',fontsize=20) plt.ylabel('价格',fontsize=20) plt.legend(['最高价','最低价'],fontsize=20) plt.savefig('work/'+file_name.split('.')[0]+'_minmax.png') plt.show() def get_deal(file_name): data, col_name = read_file(file_name) index = len(data['日期'])-1 sep = index//15 plt.figure(figsize=(15,10)) x = data['日期'].values.tolist() x.reverse() x = x[-index:] xticks=list(range(0,len(x),sep)) xlabels=[x[i] for i in xticks] xticks.append(len(x)) # xlabels.append(x[-1]) y1 = [float(c) if c!='None' else 0 for c in data['成交量'].values.tolist()] y2=[float(c) if c!='None' else 0 for c in data['成交金额'].values.tolist()] y1.reverse() y2.reverse() y1 = y1[-index:] y2 = y2[-index:] ax = plt.subplot(111) plt.plot(range(1,len(x)+1),y1,c='b',line) plt.plot(range(1,len(x)+1),y2,c='r',line) plt.title('{}-成交量/成交金额'.format(file_name.split('_')[0]),fontsize=20) ax.set_xticks(xticks) ax.set_xticklabels(xlabels, rotation=40) plt.xlabel('日期',fontsize=20) # plt.ylabel('') plt.legend(['成交量','成交金额'],fontsize=20) plt.savefig('work/'+file_name.split('.')[0]+'_deal.png') plt.show() def get_rel(file_name): data, col_name = read_file(file_name) index = len(data['日期'])-1 sep = index//15 plt.figure(figsize=(15,10)) x = data['日期'].values.tolist() x.reverse() x = x[-index:] xticks=list(range(0,len(x),sep)) xlabels=[x[i] for i in xticks] xticks.append(len(x)) # xlabels.append(x[-1]) y1 = [float(c) if c!='None' else 0 for c in data['成交量'].values.tolist()] y2=[float(c) if c!='None' else 0 for c in data['涨跌幅'].values.tolist()] y1.reverse() y2.reverse() y1 = y1[-index:] y2 = y2[-index:] y2 = [0] + y2[:-1] ax = plt.subplot(111) plt.scatter(y2,y1) plt.title('{}-成交量与前一天涨跌幅的关系'.format(file_name.split('_')[0]),fontsize=20) # ax.set_xticks(xticks) # ax.set_xticklabels(xlabels, rotation=40) plt.xlabel('前一天涨跌幅',fontsize=20) plt.ylabel('成交量',fontsize=20) # plt.legend(['成交量','成交金额'],fontsize=20) plt.savefig('work/'+file_name.split('.')[0]+'_rel.png') plt.show() # for file in files: # get_diff(file) # for file in files: # get_max_min(file) print(len(files)) for file in files: get_max_min(file) get_deal(file) get_diff(file) get_rel(file) # read_file('润和软件_300339.csv') # read_file('N迈拓_301006.csv') # read_file('N崧盛_301002.csv')
-
read_file(file_name)函数:读取CSV文件并返回数据以及列名
-
get_files_path()函数:获取文件路径,并将文件名添加到列表files中。首先调用了getStockList()函数获取个股列表,然后遍历每个个股,在文件名中提取股票代码和名称,并根据文件名读取数据。如果数据长度大于1,则将文件名添加到files列表中
-
get_diff(file_name)函数:根据给定的文件名绘制股票的涨跌额和涨跌幅变化曲线。首先读取指定文件的数据,然后提取日期、涨跌额和涨跌幅数据。根据数据量确定x轴刻度的间隔,然后绘制两个子图,分别表示涨跌额和涨跌幅。在子图中,横轴表示日期,纵轴分别表示涨跌额和涨跌幅。最后保存图片并展示
-
get_max_min 函数绘制了最高价和最低价的折线图
-
get_deal 函数绘制了成交量和成交金额的折线图
-
get_rel 函数绘制了成交量与前一天涨跌幅的散点图
文件里面画了很多图,但是都太大了,截不全,感兴趣的朋友可以进链接里看一下。
🥗有什么问题我们随时评论区见~
⭐点赞收藏不迷路~
-
-
还没有评论,来说两句吧...