<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          價值十萬代碼之三-獲取全部歷史數(shù)據(jù)

          共 7363字,需瀏覽 15分鐘

           ·

          2020-11-25 19:31

          文 |?閑歡

          來源:Python 技術(shù)「ID: pythonall」

          上篇文章 價值十萬的代碼之二---手把手教你獲取數(shù)據(jù)篇 中,小醬手把手教大家如何獲取股票行情的實時數(shù)據(jù),大家自己親自動手實現(xiàn)了嗎?首先感謝大家一貫的支持和鼓勵,給我了持續(xù)分享的動力。本篇將接著上一篇的內(nèi)容,為大家講解一下如何獲取所有個股的歷史數(shù)據(jù)。

          選定目標(biāo)

          上篇我們是通過網(wǎng)易財經(jīng)的行情頁來獲取股票的實時行情數(shù)據(jù)的,那么我們最好還是在網(wǎng)易財經(jīng)獲取歷史數(shù)據(jù),避免不同平臺一些股票標(biāo)識不一樣,導(dǎo)致數(shù)據(jù)需要進(jìn)行轉(zhuǎn)換。

          在網(wǎng)易財經(jīng)上左翻右翻,左看右看,終于被我找到了我們的目標(biāo)。我們首先進(jìn)入股票實時行情頁面(上一篇我們的目標(biāo)頁面):

          股票行情頁

          點擊某只股票名稱,進(jìn)入股票詳情頁面:

          股票詳情頁

          我們可以看到這里面是按照季度來展現(xiàn)股票的歷史交易數(shù)據(jù)的。細(xì)心的你肯定發(fā)現(xiàn)了旁邊的“下載數(shù)據(jù)”的鏈接按鈕,是不是突然有點興奮了,仿佛點擊這個按鈕就可以獲取到數(shù)據(jù)了,希望就在眼前。我們點擊這個按鈕看看:

          股票詳情頁

          哇!我看到了起始日期和截止日期,選擇開始日期和截止日期,就可以下載一只股票的所有歷史交易數(shù)據(jù),so easy~

          下載數(shù)據(jù)

          我仿佛看到了各位臉上興奮的笑容,只需要模擬這個下載操作,我就可以獲取一只股票的數(shù)據(jù)了,所有的 A 股數(shù)據(jù)也只需要獲取幾千次而已。

          沒錯,這個思路確實很正確,我之前也是這么操作的。不過好景不長,從今年的某個時間起,我的程序通過這種操作獲取不到數(shù)據(jù)了,每次獲取到的只有一行標(biāo)題,當(dāng)時我就有點迷茫了,這么好的一個渠道失去了,意味著我又需要重新尋找獲取數(shù)據(jù)的方法。當(dāng)然了,如果你不嫌麻煩并且時間充裕,可以一只只股票點進(jìn)來,然后點擊下載數(shù)據(jù),也可以將所有數(shù)據(jù)下載到本地,只是機(jī)械操作比較多而已。

          既然“下載數(shù)據(jù)”這個入口已經(jīng)不適合程序操作了,那我們回到股票詳情頁面,這個頁面是按照季度來查詢歷史交易數(shù)據(jù)的,那我們把這個頁面的數(shù)據(jù)解析出來,不就獲取了這只股票一個季度的數(shù)據(jù)了嗎?然后寫個循環(huán),逐個季度獲取,不就完事了嗎?

          分析目標(biāo)頁面

          我們選擇2020年三季度,然后點擊“查詢”按鈕,查看“天邁科技”2020年三季度的歷史交易數(shù)據(jù):

          季度數(shù)據(jù)

          我們可以看到第一個請求 URL,就很像是這個頁面的請求,再看看返回預(yù)覽是這個頁面的數(shù)據(jù),看來這個大概率是我們的目標(biāo)請求了。

          我們再接著看這個請求的返回,顯示是一個 html 頁面的代碼,想要知道這個 HTML 頁面中是否包含我們的目標(biāo)數(shù)據(jù)(主要是為了區(qū)分這頁面是及時返回數(shù)據(jù),還是頁面加載后通過 ajax 請求再來獲取數(shù)據(jù)),我們只需要將這個頁面代碼復(fù)制到文本編輯器,然后用交易數(shù)據(jù)的表格中的一個數(shù)據(jù)項搜索頁面代碼,如果能搜索到,說明頁面的數(shù)據(jù)都在這個頁面代碼中,如果獲取不到,我們再去研究頁面代碼,找到加載數(shù)據(jù)的請求。通過搜索,我們發(fā)現(xiàn)可以搜到,說明是及時加載的,也給我們提供了方便,不用再去研究延時加載了。

          既然這樣,我們就可以直接通過解析這個 HTML 頁面內(nèi)容來解析出我們需要的股票數(shù)據(jù)了。

          代碼實現(xiàn)

          通過上面的分析,我們知道,我們獲取一只股票的歷史交易數(shù)據(jù),需要逐個季度的請求解析,然后拼湊在一起。所以,我們的第一步是獲取目前 A 股所有的股票,還記得我們上篇文章的輸出嗎?全部的 A 股股票就在那里。我們當(dāng)時是存入 MySQL 數(shù)據(jù)庫的,現(xiàn)在可以獲取出來為我所用了:


          def?query_lcode(self,?day):
          ????????query_sql?=?"select?code,name?from?stock_info?where?day='%s'"?%?day

          ????????try:
          ????????????lcode?=?self.cur.execute_sql(query_sql)
          ????????????return?lcode
          ????????except?Exception:
          ????????????#輸出異常信息
          ????????????traceback.print_exc()

          接著,我們以獲取一只股票的一個季度的數(shù)據(jù)為例,來說說怎么解析這個頁面獲取數(shù)據(jù)。

          第一步,我們獲取頁面 HTML 內(nèi)容:


          def?get_data(self,?code,?year,?season):
          ????????url?=?'http://quotes.money.163.com/trade/lsjysj_%s.html?year=%s&season=%d'?%?(code,?year,?season)
          ????????ua_header?=?{"Connection":?"keep-alive",
          ?????????????????????"User-Agent":?"Mozilla/5.0?(Macintosh;?Intel?Mac?OS?X?10_13_6)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/74.0.3729.157?Safari/537.36",
          ?????????????????????"Host":?"quotes.money.163.com",
          ?????????????????????"Cookie":?"vjuids=2453fea.1759e01b4ef.0.c69c7922974aa;?_ntes_nnid=99f0981d725ac03af6da5eec0508354e,1604673713410;?_ntes_nuid=99f0981d725ac03af6da5eec0508354e;?_ntes_stock_recent_=1300033;?_ntes_stock_recent_=1300033;?_ntes_stock_recent_=1300033;?ne_analysis_trace_id=1604846790608;?s_n_f_l_n3=20f075946bacfe111604846790626;?_antanalysis_s_id=1604933714338;?vjlast=1604673713.1605015317.11;?pgr_n_f_l_n3=20f075946bacfe1116050154486829637;?vinfo_n_f_l_n3=20f075946bacfe11.1.0.1604846790623.0.1605015456187",
          ?????????????????????"Accept":?"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
          ?????????????????????"Accept-Encoding":?"gzip,?deflate",
          ?????????????????????"Accept-Language":?"zh-CN,zh;q=0.9,en;q=0.8,fr;q=0.7",
          ?????????????????????"Cache-Control":?"no-cache",
          ?????????????????????"Pragma":?"no-cache",
          ?????????????????????"Referer":?"http://quotes.money.163.com/trade/lsjysj_%s.html"?%?code,
          ?????????????????????"Upgrade-Insecure-Requests":?"1",
          ?????????????????????}
          ????????response?=?requests.get(url,?headers=ua_header,?verify=False)
          ????????content?=?response.content.decode("utf-8")

          ????????return?content

          第二步,我們來解析數(shù)據(jù):


          def?parse_data(self,?code,?name,?content):
          ????????soup?=?BeautifulSoup(content,?'html.parser')
          ????????table?=?soup.find("table",?class_="table_bg001?border_box?limit_sale").prettify()
          ????????tb_soup?=?BeautifulSoup(table,?'html.parser')
          ????????tr_list?=?tb_soup.find_all('tr')
          ????????stock_list?=?[]
          ????????if?len(tr_list):
          ????????????del?tr_list[0]
          ????????????for?tr?in?tr_list:
          ????????????????items?=?tr.text.split('\n\n')
          ????????????????if?len(items):
          ????????????????????del?items[0]
          ????????????????????stock?=?{}
          ????????????????????stock['day']?=?items[0].replace('\n?',?'').replace('?',?'')
          ????????????????????stock['code']?=?code
          ????????????????????stock['name']?=?name
          ????????????????????stock['open_price']?=?self.trans_float(items[1].replace('\n?',?'').replace('?',?''))
          ????????????????????stock['top_price']?=?self.trans_float(items[2].replace('\n?',?'').replace('?',?''))
          ????????????????????stock['low_price']?=?self.trans_float(items[3].replace('\n?',?'').replace('?',?''))
          ????????????????????stock['close_price']?=?self.trans_float(items[4].replace('\n?',?'').replace('?',?''))
          ????????????????????#?stock['last_price']?=?self.trans_float(items[7])
          ????????????????????stock['add_point']?=?self.trans_float(items[5].replace('\n?',?'').replace('?',?''))
          ????????????????????stock['add_percent']?=?self.trans_float(items[6].replace('\n?',?'').replace('?',?''))
          ????????????????????stock['volumn']?=?self.trans_float(items[7].replace('\n?',?'').replace('?',?'').replace(',',?''))
          ????????????????????stock['turnover']?=?self.trans_float(items[8].replace('\n?',?'').replace('?',?'').replace(',',?''))
          ????????????????????stock['amplitude']?=?self.trans_float(items[9].replace('\n?',?'').replace('?',?''))
          ????????????????????stock['exchange_rate']?=?self.trans_float(items[10].replace('\n?\n',?'').replace('?',?''))
          ????????????????????#?stock['market_value']?=?self.trans_float(items[13])
          ????????????????????#?stock['flow_market_value']?=?self.trans_float(items[14])

          ????????????????????stock_list.append(stock)

          ????????return?stock_list

          這里我先用 bs4 來解析 HTML 頁面,定位到數(shù)據(jù)表格,然后再解析表格的內(nèi)容就可以獲取每一個日期的數(shù)據(jù)項了。但是這里相對于我們上一篇的實時行情數(shù)據(jù),會少幾項,例如前一個交易日的收盤價,市場成交額等,不過這幾項數(shù)據(jù)是可以通過所有的歷史數(shù)據(jù)計算出來的,所以即使以后要用我們也有辦法。

          解析完數(shù)據(jù)之后,我們就可以存儲到數(shù)據(jù)庫了:


          def?insertdb(self,?data_list):
          ????????attrs?=?['day',?'code',?'name',?'open_price',?'top_price',?'low_price',?'close_price',?'add_point',
          ?????????????????'add_percent',?'volumn',?'turnover',?'amplitude',?'exchange_rate']
          ????????insert_tuple?=?[]
          ????????for?obj?in?data_list:
          ????????????insert_tuple.append((obj['day'],?obj['code'],?obj['name'],?obj['open_price'],?obj['top_price'],?obj['low_price'],?obj['close_price'],?obj['add_point'],?obj['add_percent'],?obj['volumn'],?obj['turnover'],?obj['amplitude'],?obj['exchange_rate']))
          ????????values_sql?=?['%s'?for?v?in?attrs]
          ????????attrs_sql?=?'('+','.join(attrs)+')'
          ????????values_sql?=?'?values('+','.join(values_sql)+')'
          ????????sql?=?'insert?into?%s'?%?'stock_info'
          ????????sql?=?sql?+?attrs_sql?+?values_sql
          ????????try:
          ????????????print(sql)
          ????????????for?i?in?range(0,?len(insert_tuple),?20000):
          ????????????????self.cur.executemany(sql,?tuple(insert_tuple[i:i+20000]))
          ????????????????self.conn.commit()
          ????????except?pymysql.Error?as?e:
          ????????????self.conn.rollback()
          ????????????error?=?'insertMany?executemany?failed!?ERROR?(%s):?%s'?%?(e.args[0],?e.args[1])
          ????????????print(error)

          這個沒什么好說的,就是一個數(shù)據(jù)庫批量插入操作而已。

          到這里,我們就把一只股票的一個季度的數(shù)據(jù)獲取到了。那么如何獲取所有股票的歷史數(shù)據(jù)呢?相信聰明的你已經(jīng)有了答案了。一種辦法是獲取股票的詳細(xì)信息,然后解析出上市日期,然后從上市日期所在年度季度開始,逐個季度獲取數(shù)據(jù)。另一種辦法是從 A 股開市時間開始,滬市的開市日期是1990-12-20,深市的開市日期是1991-01-03,創(chuàng)業(yè)板的開市日期是2009-10-30,科創(chuàng)板的開市日期是2019-07-22。四個板塊的股票分別從這幾個日期開始獲取,不管這只股票是什么時候上市的,都可以獲取全這只股票的歷史數(shù)據(jù)。

          總結(jié)

          本文教大家如何從網(wǎng)易財經(jīng)的個股歷史交易數(shù)據(jù)頁面獲取到全市場個股的歷史交易數(shù)據(jù),大家可以根據(jù)文中的方法自己去實踐一下。

          到此為止,獲取股票的數(shù)據(jù)這個環(huán)節(jié)我就介紹完了,接下來就是如何利用手中的數(shù)據(jù)去分析出有價值的東西。如果大家感興趣,還望先給我點個在看,我會繼續(xù)履行前面許下的承諾,結(jié)合研報數(shù)據(jù)和股票數(shù)據(jù)去分析,從而輔助股票交易的決策分析。

          PS公號內(nèi)回復(fù)「Python」即可進(jìn)入Python 新手學(xué)習(xí)交流群,一起 100 天計劃!


          老規(guī)矩,兄弟們還記得么,右下角的 “在看” 點一下,如果感覺文章內(nèi)容不錯的話,記得分享朋友圈讓更多的人知道!

          代碼獲取方式

          識別文末二維碼,回復(fù):201124


          瀏覽 20
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  麻豆成人视频 | av无码av| 人人舔人人爽 | 国产婷婷色一区二区在线观看 | 午夜福利电影AV |