飛槳AI Studio星河社區(qū)-人工智能學(xué)習(xí)與實(shí)訓(xùn)社區(qū)
這篇文章好像有點(diǎn)大,所以上邊網(wǎng)頁(yè)點(diǎn)進(jìn)去是看不到的,進(jìn)入環(huán)境之后就能看了
??必要包的下載導(dǎo)入
!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
#爬取該頁(yè)面股票信息
?
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為爬取多少條記錄,可手動(dòng)設(shè)置
num = 20
#該地址為頁(yè)面實(shí)際獲取數(shù)據(jù)的接口地址
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()
-
定義了一個(gè)函數(shù)
getHtml(url)
,用于獲取指定URL頁(yè)面的HTML內(nèi)容。使用requests.get()
方法發(fā)送GET請(qǐng)求,通過(guò)fake_useragent生成隨機(jī)的User-Agent來(lái)偽裝請(qǐng)求頭,避免被網(wǎng)站封禁IP。然后設(shè)置編碼為頁(yè)面的apparent_encoding,確保編碼正確 -
設(shè)置要爬取的記錄條數(shù)
num
-
定義了變量
stockUrl
,該地址為頁(yè)面實(shí)際獲取數(shù)據(jù)的接口地址。通過(guò)該接口地址可以獲取股票信息的JSON數(shù)據(jù) -
在主程序中,調(diào)用
getHtml(stockUrl)
方法獲取頁(yè)面的HTML內(nèi)容 -
解析HTML內(nèi)容,提取出JSON數(shù)據(jù)。首先使用
split()
方法分割字符串,提取出JSON文本部分。然后使用json.loads()
方法將JSON文本解析為Python字典 -
從解析后的JSON數(shù)據(jù)中提取股票信息,并存儲(chǔ)到列表
datalist
中 -
打開文件
stock.csv
,使用CSV模塊創(chuàng)建一個(gè)寫入對(duì)象writer
,將股票信息寫入CSV文件中 -
遍歷
datalist
列表,將每條股票信息寫入CSV文件中 -
關(guān)閉CSV文件
??多線程并發(fā)下載股票數(shù)據(jù)文件并存儲(chǔ)為CSV格式
import csv
import urllib.request as r
import threading
#讀取之前獲取的個(gè)股csv丟入到一個(gè)列表中
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
#設(shè)置信號(hào)量,控制線程并發(fā)數(shù)
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()
-
定義了一個(gè)新的函數(shù)
getStockList()
,用于從之前獲取的個(gè)股CSV文件中讀取數(shù)據(jù),并將其存儲(chǔ)到一個(gè)列表中。通過(guò)csv.reader()
方法逐行讀取CSV文件,并將每一行數(shù)據(jù)存儲(chǔ)為一個(gè)列表,最后將所有列表存儲(chǔ)到stockList
中 -
定義了一個(gè)新的函數(shù)
downloadFile(url, filepath)
,用于下載文件。通過(guò)urllib.request.urlretrieve()
方法下載指定URL的文件,并保存到指定的路徑 -
引入了
threading
模塊,用于創(chuàng)建線程實(shí)現(xiàn)多線程下載 -
定義了一個(gè)信號(hào)量
sem
,用于控制線程并發(fā)數(shù)。在多線程環(huán)境下,為了避免資源競(jìng)爭(zhēng)和死鎖,可以使用信號(hào)量來(lái)限制同時(shí)執(zhí)行的線程數(shù)量 -
定義了一個(gè)新的函數(shù)
downloadFileSem(url, filepath)
,在該函數(shù)中使用了信號(hào)量sem
來(lái)限制并發(fā)數(shù),然后調(diào)用downloadFile()
函數(shù)下載文件 -
修改了
urlStart
和urlEnd
變量,用于構(gòu)造下載文件的URL。根據(jù)個(gè)股代碼的首位數(shù)字(0表示滬市,1表示深市),選擇對(duì)應(yīng)的交易所代碼 -
在主程序中,獲取之前獲取的個(gè)股列表
stockList
,然后依次遍歷每個(gè)股票信息 -
對(duì)于每個(gè)股票信息,提取股票代碼和名稱,并構(gòu)造對(duì)應(yīng)的下載URL和文件路徑
-
創(chuàng)建一個(gè)新的線程,通過(guò)
threading.Thread()
方法傳入目標(biāo)函數(shù)downloadFileSem
和參數(shù),啟動(dòng)線程并進(jìn)行下載
??股票信息分析
import pandas as pd
import matplotlib.pyplot as plt
import csv
# 設(shè)置顯示中文
plt.rcParams['font.sans-serif'] = ['simhei'] # 指定默認(rèn)字體
plt.rcParams['axes.unicode_minus']=False # 用來(lái)顯示負(fù)號(hào)
plt.rcParams['figure.dpi'] = 100 # 每英寸點(diǎn)數(shù)
?
files = []
# ['日期' '股票代碼' '名稱' '收盤價(jià)' '最高價(jià)' '最低價(jià)' '開盤價(jià)' '前收盤' '漲跌額' '漲跌幅' '成交量' '成交金額']
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)
?
?
?
# 獲取股票的漲跌額及漲跌幅度變化曲線
# ['日期' '股票代碼' '名稱' '收盤價(jià)' '最高價(jià)' '最低價(jià)' '開盤價(jià)' '前收盤' '漲跌額' '漲跌幅' '成交量' '成交金額']
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['最高價(jià)'].values.tolist()]
y2=[float(c) if c!='None' else 0 for c in data['最低價(jià)'].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',linestyle="-")
plt.plot(range(1,len(x)+1),y2,c='g',linestyle="--")
?
plt.title('{}-最高價(jià)/最低價(jià)'.format(file_name.split('_')[0]),fontsize=20)
ax.set_xticks(xticks)
ax.set_xticklabels(xlabels, rotation=40)
plt.xlabel('日期',fontsize=20)
plt.ylabel('價(jià)格',fontsize=20)
plt.legend(['最高價(jià)','最低價(jià)'],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',linestyle="-")
plt.plot(range(1,len(x)+1),y2,c='r',linestyle="--")
?
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('{}-成交量與前一天漲跌幅的關(guān)系'.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('潤(rùn)和軟件_300339.csv')
# read_file('N邁拓_301006.csv')
# read_file('N崧盛_301002.csv')
-
read_file(file_name)
函數(shù):讀取CSV文件并返回?cái)?shù)據(jù)以及列名 -
get_files_path()
函數(shù):獲取文件路徑,并將文件名添加到列表files
中。首先調(diào)用了getStockList()
函數(shù)獲取個(gè)股列表,然后遍歷每個(gè)個(gè)股,在文件名中提取股票代碼和名稱,并根據(jù)文件名讀取數(shù)據(jù)。如果數(shù)據(jù)長(zhǎng)度大于1,則將文件名添加到files
列表中 -
get_diff(file_name)
函數(shù):根據(jù)給定的文件名繪制股票的漲跌額和漲跌幅變化曲線。首先讀取指定文件的數(shù)據(jù),然后提取日期、漲跌額和漲跌幅數(shù)據(jù)。根據(jù)數(shù)據(jù)量確定x軸刻度的間隔,然后繪制兩個(gè)子圖,分別表示漲跌額和漲跌幅。在子圖中,橫軸表示日期,縱軸分別表示漲跌額和漲跌幅。最后保存圖片并展示 -
get_max_min
函數(shù)繪制了最高價(jià)和最低價(jià)的折線圖 -
get_deal
函數(shù)繪制了成交量和成交金額的折線圖 -
get_rel
函數(shù)繪制了成交量與前一天漲跌幅的散點(diǎn)圖
文件里面畫了很多圖,但是都太大了,截不全,感興趣的朋友可以進(jìn)鏈接里看一下。
??有什么問(wèn)題我們隨時(shí)評(píng)論區(qū)見~文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-850598.html
?點(diǎn)贊收藏不迷路~文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-850598.html
到了這里,關(guān)于百度松果菁英班——機(jī)器學(xué)習(xí)實(shí)踐六:股票行情爬取與分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!