久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Python爬蟲(chóng)抓取東方財(cái)富網(wǎng)股票數(shù)據(jù)并實(shí)現(xiàn)MySQL數(shù)據(jù)庫(kù)存儲(chǔ)

 yjs47 2020-05-06

Python爬蟲(chóng)可以說(shuō)是好玩又好用了?,F(xiàn)想利用Python爬取網(wǎng)頁(yè)股票數(shù)據(jù)保存到本地csv數(shù)據(jù)文件中,,同時(shí)想把股票數(shù)據(jù)保存到MySQL數(shù)據(jù)庫(kù)中。需求有了,,剩下的就是實(shí)現(xiàn)了,。

在開(kāi)始之前,保證已經(jīng)安裝好了MySQL并需要啟動(dòng)本地MySQL數(shù)據(jù)庫(kù)服務(wù),。提到安裝MySQL數(shù)據(jù)庫(kù),,前兩天在一臺(tái)電腦上安裝MySQL5.7時(shí),死活裝不上,,總是提示缺少Visual Studio 2013 Redistributable,,但是很疑惑,明明已經(jīng)安裝了呀,,原來(lái)問(wèn)題出在版本上,,更換一個(gè)版本后就可以了。小問(wèn)題大苦惱,,不知道有沒(méi)有人像我一樣悲催,。

言歸正傳,啟動(dòng)本地?cái)?shù)據(jù)庫(kù)服務(wù):

    用管理員身份打開(kāi)“命令提示符(管理員)”,,然后輸入“net start mysql57”(我把數(shù)據(jù)庫(kù)服務(wù)名定義為mysql57了,,安裝MySQL時(shí)可以修改)就可以開(kāi)啟服務(wù)了。注意使用管理員身份打開(kāi)小黑框,,如果不是管理員身份,,我這里會(huì)提示沒(méi)有權(quán)限,大家可以試試,。

啟動(dòng)服務(wù)之后,,我們可以選擇打開(kāi)“MySQL 5.7 Command Line Client”小黑框,需要先輸入你的數(shù)據(jù)庫(kù)的密碼,安裝的時(shí)候定義過(guò),,在這里可以進(jìn)行數(shù)據(jù)庫(kù)操作,。

下面開(kāi)始上正餐。

一,、Python爬蟲(chóng)抓取網(wǎng)頁(yè)數(shù)據(jù)并保存到本地?cái)?shù)據(jù)文件中

首先導(dǎo)入需要的數(shù)據(jù)模塊,,定義函數(shù):

復(fù)制代碼
#導(dǎo)入需要使用到的模塊 import urllib import re import pandas as pd import pymysql import os #爬蟲(chóng)抓取網(wǎng)頁(yè)函數(shù) def getHtml(url): html = urllib.request.urlopen(url).read() html = html.decode('gbk') return html #抓取網(wǎng)頁(yè)股票代碼函數(shù) def getStackCode(html): s = r'<li><a target='_blank' pat = re.compile(s) code = pat.findall(html) return code
復(fù)制代碼

真正干活的代碼塊:

復(fù)制代碼
Url = 'http://quote.eastmoney.com/stocklist.html'#東方財(cái)富網(wǎng)股票數(shù)據(jù)連接地址
filepath = 'D:\\data\\'#定義數(shù)據(jù)文件保存路徑
#實(shí)施抓取
code = getStackCode(getHtml(Url)) 
#獲取所有股票代碼(以6開(kāi)頭的,應(yīng)該是滬市數(shù)據(jù))集合
CodeList = []
for item in code:
    if item[0]=='6':
        CodeList.append(item)
#抓取數(shù)據(jù)并保存到本地csv文件
for code in CodeList:
    print('正在獲取股票%s數(shù)據(jù)'%code)
    url = 'http://quotes.money.163.com/service/chddata.html?code=0' code         '&end=20161231&fields=TCLOSE;HIGH;LOW;TOPEN;LCLOSE;CHG;PCHG;TURNOVER;VOTURNOVER;VATURNOVER;TCAP;MCAP'
    urllib.request.urlretrieve(url, filepath code '.csv')
復(fù)制代碼

以上代碼實(shí)現(xiàn)了爬蟲(chóng)網(wǎng)頁(yè)抓取股票數(shù)據(jù),,并保存到本地文件中,。關(guān)于爬蟲(chóng)的東西,有很多資料可以參考,,大都是一個(gè)套路,,不再多說(shuō)。同時(shí),,本文實(shí)現(xiàn)過(guò)程中也參考了很多的網(wǎng)頁(yè)資源,,在此對(duì)所有原創(chuàng)者表示感謝!

先看下抓取的結(jié)果,。CodeList是抓取到的所有股票代碼的集合,,我們看到它共包含1416條元素,即1416支股票數(shù)據(jù),。因?yàn)楣善碧?,所以抓取的是?開(kāi)頭的,貌似是滬市股票數(shù)據(jù)(原諒我不懂金融),。

 抓取到的股票數(shù)據(jù)會(huì)分別存儲(chǔ)到csv文件中,,一只股票數(shù)據(jù)一個(gè)文件。理論上會(huì)有1416個(gè)csv文件,,和股票代碼數(shù)一致,。但原諒我的渣網(wǎng)速,下載一個(gè)都費(fèi)勁,,也是呵呵了,。

 打開(kāi)一個(gè)本地?cái)?shù)據(jù)文件看一下抓取的數(shù)據(jù)長(zhǎng)什么樣子:

 其實(shí)和人工手動(dòng)下載也沒(méi)什么區(qū)別了,硬要說(shuō)區(qū)別,,那就是解放了勞動(dòng)力,,提高了生產(chǎn)力(怎么聽(tīng)起來(lái)像政治?),。

二,、將數(shù)據(jù)存儲(chǔ)到MySQL數(shù)據(jù)庫(kù)

 首先建立本地?cái)?shù)據(jù)庫(kù)連接:

復(fù)制代碼
#數(shù)據(jù)庫(kù)名稱(chēng)和密碼 name = 'xxxx' password = 'xxxx' #替換為自己的用戶(hù)名和密碼 #建立本地?cái)?shù)據(jù)庫(kù)連接(需要先開(kāi)啟數(shù)據(jù)庫(kù)服務(wù)) db = pymysql.connect('localhost', name, password, charset='utf8') cursor = db.cursor()
復(fù)制代碼

其中,數(shù)據(jù)庫(kù)名稱(chēng)(name)和密碼(password)是安裝MySQL時(shí)設(shè)置的,。

創(chuàng)建數(shù)據(jù)庫(kù),,專(zhuān)門(mén)用來(lái)存儲(chǔ)本次股票數(shù)據(jù):

#創(chuàng)建數(shù)據(jù)庫(kù)stockDataBase,如果存在則跳過(guò)
sqlSentence1 = 'create database if not exists stockDataBase'
cursor.execute(sqlSentence1)#選擇使用當(dāng)前數(shù)據(jù)庫(kù)
sqlSentence2 = 'use stockDataBase;'
cursor.execute(sqlSentence2)

在首次運(yùn)行的時(shí)候一般都會(huì)正常創(chuàng)建數(shù)據(jù)庫(kù),但如果再次運(yùn)行,,因數(shù)據(jù)庫(kù)已經(jīng)存在,,那么跳過(guò)創(chuàng)建,繼續(xù)往下執(zhí)行,。創(chuàng)建好數(shù)據(jù)庫(kù)后,,選擇使用剛剛創(chuàng)建的數(shù)據(jù)庫(kù),,在該數(shù)據(jù)庫(kù)中存儲(chǔ)數(shù)據(jù)表,。

下面看具體的存儲(chǔ)代碼:

復(fù)制代碼
#獲取本地文件列
fileList = os.listdir(filepath)
#
依次對(duì)每個(gè)數(shù)據(jù)文件進(jìn)行存儲(chǔ) for fileName in fileList: data = pd.read_csv(filepath fileName, encoding='gbk') #創(chuàng)建數(shù)據(jù)表,如果數(shù)據(jù)表已經(jīng)存在,,會(huì)跳過(guò)繼續(xù)執(zhí)行下面的步驟print('創(chuàng)建數(shù)據(jù)表stock_%s'% fileName[0:6]) sqlSentence3 = 'create table if not exists stock_%s' % fileName[0:6] '(日期 date, 股票代碼 VARCHAR(10), 名稱(chēng) VARCHAR(10), 收盤(pán)價(jià) float,\
最高價(jià) float, 最低價(jià) float, 開(kāi)盤(pán)價(jià) float, 前收盤(pán) float, 漲跌額 float, 漲跌幅 float, 換手率 float,\
成交量 bigint, 成交金額 bigint, 總市值 bigint, 流通市值 bigint)
' cursor.execute(sqlSentence3)#迭代讀取表中每行數(shù)據(jù),,依次存儲(chǔ)(整表存儲(chǔ)還沒(méi)嘗試過(guò)) print('正在存儲(chǔ)stock_%s'% fileName[0:6]) length = len(data) for i in range(0, length): record = tuple(data.loc[i]) #插入數(shù)據(jù)語(yǔ)句 try: sqlSentence4 = 'insert into stock_%s' % fileName[0:6] '(日期, 股票代碼, 名稱(chēng), 收盤(pán)價(jià), 最高價(jià), 最低價(jià), 開(kāi)盤(pán)價(jià),\
前收盤(pán), 漲跌額, 漲跌幅, 換手率, 成交量, 成交金額, 總市值, 流通市值) \
values ('%s',%s','%s',%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
' % record #獲取的表中數(shù)據(jù)很亂,包含缺失值,、Nnone,、none等,插入數(shù)據(jù)庫(kù)需要處理成空值 sqlSentence4 = sqlSentence4.replace('nan','null').replace('None','null').replace('none','null') cursor.execute(sqlSentence4) except:#如果以上插入過(guò)程出錯(cuò),,跳過(guò)這條數(shù)據(jù)記錄,,繼續(xù)往下進(jìn)行 break
復(fù)制代碼

 代碼并不復(fù)雜,只要注意其中幾個(gè)點(diǎn)就好了,。

1.邏輯層次:

    包含兩層循環(huán),,外層循環(huán)是對(duì)股票代碼的循環(huán),內(nèi)層循環(huán)是對(duì)當(dāng)前股票的每一條記錄的循環(huán),。說(shuō)白了就是按照股票一支一支的存儲(chǔ),,對(duì)于每一支股票,按照它每日的記錄一條一條的存儲(chǔ),。是不是很簡(jiǎn)單很暴力,?是的!完全沒(méi)有考慮更加優(yōu)化的方式,。

2.讀取本地?cái)?shù)據(jù)文件的編碼方式:

    使用'gbk'編碼,,默認(rèn)應(yīng)該是'utf8',但好像不支持中文,。

3.創(chuàng)建數(shù)據(jù)表:

    同樣的,,如果數(shù)據(jù)表已經(jīng)存在(判斷是否存在if not exists),則跳過(guò)創(chuàng)建,,繼續(xù)執(zhí)行下面的步驟(會(huì)繼續(xù)存儲(chǔ)),。有個(gè)問(wèn)題是,有可能數(shù)據(jù)重復(fù)存儲(chǔ),,可以選擇跳過(guò)存儲(chǔ)或者只存儲(chǔ)最新數(shù)據(jù),。我在這里沒(méi)有考慮太多額外的處理。其次,指定字段格式,,后邊幾個(gè)字段成交量,、成交金額、總市值,、流通市值,,因?yàn)閿?shù)據(jù)較大,選擇使用bigint類(lèi)型,。

4.沒(méi)有指定數(shù)據(jù)表的主鍵:

    最初是打算使用日期作為主鍵的,,后來(lái)發(fā)現(xiàn)獲取到的數(shù)據(jù)中竟然包含重復(fù)日期的數(shù)據(jù),這就打破了主鍵的唯一性,,會(huì)出bug的,,然后我也沒(méi)有多去思考數(shù)據(jù)文件的內(nèi)容,也不會(huì)進(jìn)一步使用這些個(gè)數(shù)據(jù),,也就圖省事直接不設(shè)置主鍵了,。

5.構(gòu)造sql語(yǔ)句sqlSentence4:

    該過(guò)程實(shí)現(xiàn)中,直接把股票數(shù)據(jù)記錄tuple了,,然后使用字符串格式化(%操作符),。造成的精度問(wèn)題沒(méi)有多考慮,不知道會(huì)不會(huì)產(chǎn)生什么樣的影響,。%s有的上邊帶著' ',,是為了在sql語(yǔ)句中表示字符串。其中有一個(gè)%s',,只有右邊有單引號(hào),,匹配的是股票代碼,只有一邊單引號(hào),,這是因?yàn)閺臄?shù)據(jù)文件中讀取到的字符串已經(jīng)包含了左邊的單引號(hào),,左邊不需要再添加了。這是數(shù)據(jù)文件格式的問(wèn)題,,為了表示文本形式預(yù)先使用了單引號(hào),。

 6.異常值處理:

    文本文件中,包含有空值,、None,、none等不標(biāo)準(zhǔn)化數(shù)據(jù),這里全部替換為null了,,即數(shù)據(jù)庫(kù)的空值,。

完成MySQL數(shù)據(jù)庫(kù)數(shù)據(jù)存儲(chǔ)后,需要關(guān)閉數(shù)據(jù)庫(kù)連接:

#關(guān)閉游標(biāo),,提交,,關(guān)閉數(shù)據(jù)庫(kù)連接
cursor.close()
db.commit()
db.close()

不關(guān)閉數(shù)據(jù)庫(kù)連接,,就無(wú)法在MySQL端進(jìn)行數(shù)據(jù)庫(kù)的查詢(xún)等操作,相當(dāng)于數(shù)據(jù)庫(kù)被占用,。

三,、MySQL數(shù)據(jù)庫(kù)查詢(xún)

復(fù)制代碼
#重新建立數(shù)據(jù)庫(kù)連接 db = pymysql.connect('localhost', name, password, 'stockDataBase') cursor = db.cursor() #查詢(xún)數(shù)據(jù)庫(kù)并打印內(nèi)容 cursor.execute('select * from stock_600000') results = cursor.fetchall() for row in results: print(row) #關(guān)閉 cursor.close() db.commit() db.close()
復(fù)制代碼

以上逐條打印,會(huì)凌亂到死的,。也可以在MySQL端查看,,先選中數(shù)據(jù)庫(kù):use stockDatabase;,然后查詢(xún):select * from stock_600000;,,結(jié)果大概就是下面這個(gè)樣子了:

四,、完整代碼

    實(shí)際上,整個(gè)事情完成了兩個(gè)相對(duì)獨(dú)立的過(guò)程:1.爬蟲(chóng)獲取網(wǎng)頁(yè)股票數(shù)據(jù)并保存到本地文件,;2.將本地文件數(shù)據(jù)儲(chǔ)存到MySQL數(shù)據(jù)庫(kù),。并沒(méi)有直接的考慮把從網(wǎng)頁(yè)上抓取到的數(shù)據(jù)實(shí)時(shí)(或者通過(guò)一個(gè)臨時(shí)文件)扔進(jìn)數(shù)據(jù)庫(kù),,跳過(guò)本地?cái)?shù)據(jù)文件這個(gè)過(guò)程,。這里只是嘗試著去實(shí)現(xiàn)了一下這件事情,代碼沒(méi)有做任何的優(yōu)化考慮,。本身不實(shí)際去使用,,只是樂(lè)趣而已,差不多先這樣,。哈哈~~

復(fù)制代碼
#導(dǎo)入需要使用到的模塊
import urllib
import re
import pandas as pd
import pymysql
import os

#爬蟲(chóng)抓取網(wǎng)頁(yè)函數(shù)
def getHtml(url):
    html = urllib.request.urlopen(url).read()
    html = html.decode('gbk')
    return html

#抓取網(wǎng)頁(yè)股票代碼函數(shù)
def getStackCode(html):
    s = r'<li><a target='_blank' 
    pat = re.compile(s)
    code = pat.findall(html)
    return code
    
#########################開(kāi)始干活############################
Url = 'http://quote.eastmoney.com/stocklist.html'#東方財(cái)富網(wǎng)股票數(shù)據(jù)連接地址
filepath = 'C:\\Users\\Lenovo\\Desktop\\data\\'#定義數(shù)據(jù)文件保存路徑
#實(shí)施抓取
code = getStackCode(getHtml(Url)) 
#獲取所有股票代碼(以6開(kāi)頭的,,應(yīng)該是滬市數(shù)據(jù))集合
CodeList = []
for item in code:
    if item[0]=='6':
        CodeList.append(item)
#抓取數(shù)據(jù)并保存到本地csv文件
for code in CodeList:
    print('正在獲取股票%s數(shù)據(jù)'%code)
    url = 'http://quotes.money.163.com/service/chddata.html?code=0' code         '&end=20161231&fields=TCLOSE;HIGH;LOW;TOPEN;LCLOSE;CHG;PCHG;TURNOVER;VOTURNOVER;VATURNOVER;TCAP;MCAP'
    urllib.request.urlretrieve(url, filepath code '.csv')


##########################將股票數(shù)據(jù)存入數(shù)據(jù)庫(kù)###########################

#數(shù)據(jù)庫(kù)名稱(chēng)和密碼
name = 'xxxx'
password = 'xxxx'  #替換為自己的賬戶(hù)名和密碼
#建立本地?cái)?shù)據(jù)庫(kù)連接(需要先開(kāi)啟數(shù)據(jù)庫(kù)服務(wù))
db = pymysql.connect('localhost', name, password, charset='utf8')
cursor = db.cursor()
#創(chuàng)建數(shù)據(jù)庫(kù)stockDataBase
sqlSentence1 = 'create database stockDataBase'
cursor.execute(sqlSentence1)#選擇使用當(dāng)前數(shù)據(jù)庫(kù)
sqlSentence2 = 'use stockDataBase;'
cursor.execute(sqlSentence2)

#獲取本地文件列表
fileList = os.listdir(filepath)
#依次對(duì)每個(gè)數(shù)據(jù)文件進(jìn)行存儲(chǔ)
for fileName in fileList:
    data = pd.read_csv(filepath fileName, encoding='gbk')
   #創(chuàng)建數(shù)據(jù)表,如果數(shù)據(jù)表已經(jīng)存在,,會(huì)跳過(guò)繼續(xù)執(zhí)行下面的步驟print('創(chuàng)建數(shù)據(jù)表stock_%s'% fileName[0:6])
    sqlSentence3 = 'create table stock_%s' % fileName[0:6]   '(日期 date, 股票代碼 VARCHAR(10),     名稱(chēng) VARCHAR(10),                       收盤(pán)價(jià) float,    最高價(jià)    float, 最低價(jià) float, 開(kāi)盤(pán)價(jià) float, 前收盤(pán) float, 漲跌額    float,                        漲跌幅 float, 換手率 float, 成交量 bigint, 成交金額 bigint, 總市值 bigint, 流通市值 bigint)'
    cursor.execute(sqlSentence3)
    except:
        print('數(shù)據(jù)表已存在,!')

    #迭代讀取表中每行數(shù)據(jù),依次存儲(chǔ)(整表存儲(chǔ)還沒(méi)嘗試過(guò))
    print('正在存儲(chǔ)stock_%s'% fileName[0:6])
    length = len(data)
    for i in range(0, length):
        record = tuple(data.loc[i])
        #插入數(shù)據(jù)語(yǔ)句
        try:
            sqlSentence4 = 'insert into stock_%s' % fileName[0:6]   '(日期, 股票代碼, 名稱(chēng), 收盤(pán)價(jià), 最高價(jià), 最低價(jià), 開(kāi)盤(pán)價(jià), 前收盤(pán), 漲跌額, 漲跌幅, 換手率,             成交量, 成交金額, 總市值, 流通市值) values ('%s',%s','%s',%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)' % record
            #獲取的表中數(shù)據(jù)很亂,,包含缺失值,、Nnone、none等,,插入數(shù)據(jù)庫(kù)需要處理成空值
            sqlSentence4 = sqlSentence4.replace('nan','null').replace('None','null').replace('none','null') 
            cursor.execute(sqlSentence4)
        except:
            #如果以上插入過(guò)程出錯(cuò),,跳過(guò)這條數(shù)據(jù)記錄,繼續(xù)往下進(jìn)行
            break

#關(guān)閉游標(biāo),,提交,,關(guān)閉數(shù)據(jù)庫(kù)連接
cursor.close()
db.commit()
db.close()


###########################查詢(xún)剛才操作的成果##################################

#重新建立數(shù)據(jù)庫(kù)連接
db = pymysql.connect('localhost', name, password, 'stockDataBase')
cursor = db.cursor()
#查詢(xún)數(shù)據(jù)庫(kù)并打印內(nèi)容
cursor.execute('select * from stock_600000')
results = cursor.fetchall()
for row in results:
    print(row)
#關(guān)閉
cursor.close()
db.commit()
db.close()
復(fù)制代碼

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多