您的位置:首頁>財經>正文

我用Python爬了上市公司財務報表,跟巴菲特學習如何炒股

【51CTO.com原創稿件】沃倫·巴菲特( Warren Buffett), 全球著名的投資商。 從事股票、電子現貨、基金行業。 在 2017 年 7 月 17 日, 《福布斯富豪榜》發佈, 沃倫·巴菲特以淨資產 734 億美元排名第四。

作為”股神”, 他的投資理念被許多人追捧。 與其共進午餐的慈善活動都可以拍賣到 345.67 萬美元, 從中我們可以輕易地看出, 他的投資界地位、影響力有多大。

他的投資名言有很多:

風險, 是來自你不知道你在做什麼。

若你不打算持有某檔股票達十年,

則十分鐘也不要持有。

投資的秘訣, 不是評估某一行業對社會的影響有多大, 或它的發展前景有多好, 而是一間公司有多強的競爭優勢。 這優勢可以維持多久, 產品和服務的優越性持久而深厚, 才能給投資者帶來優厚的回報。

我最喜歡的持股時間是……永遠!

要投資成功, 就要拼命閱讀。 不但讀有興趣購入的公司資料, 也要閱讀其他競爭者的資料。

從他的這些名言中, 我們不難發現, 巴菲特做的是長期投資, 他投一家公司, 抱定的目標是持續持有, 不因為價格原因而出售。 他看准一家公司, 會分析這家公司的競爭優勢, 也會分析這家公司的對手的競爭優勢, 然後做出投資決策。

他是怎麼確定一家公司是否值得自己長期投資,

是否具有競爭優勢的呢?其中, 最有效、最常用的手段之一就是分析上市公司財務報表。 網上有很多《跟巴菲特學看上市公司財務報表》諸如此類的文章, 仁者見仁智者見智。

本文重點不在於如何分析財務報表, 而是如何獲得財務報表, 為後續的方便分析做準備。

實戰背景

Github代碼獲取:https://github.com/Jack-Cherish/python-spider

Python版本: Python3.x

運行平臺: Windows

IDE: Sublime text3

每個上市公司的財務報表都是免費提供的, 可以在他們的官網進行下載。 但是這樣一個一個找, 太麻煩。 有沒有一個網站, 集成好各個上市公司的財務資訊呢?當然有, 而且很多!各個金融門戶網站都有!

今天, 我們看哪個金融門戶網站?網易財經!

雙手奉上它的位址:http://quotes.money.163.com/hkstock/

這個網站長這樣:

我們可以通過股票查詢, 查看股票情況。 比如我輸入 00700, 查看騰訊控股在美股的情況, 如下圖:

可以看到, 我截圖的時間, 騰訊控股”綠了”, 也就是跌了。 點擊財務資料, 我們就可以看到騰訊控股的財務報表, 如圖所示:

這個財務資料欄目中,提供了《主要財務指標》、《利潤表》、《資產負債表》以及《現金流量表》。

從圖中可以看到,該網站提供了財務資料線上流覽功能,但是沒有提供財務報表下載功能,如何將每年的財務資料獲取,並存入資料庫,方便我們後續的分析呢?沒錯,這就是本文的主題:財務報表爬取入庫。

網站分析

我們以騰訊控股的財務資料為例進行分析。

它的URL:http://quotes.money.163.com/hkstock/cwsj_00700.html

看一下這個 URL 地址有什麼特點?騰訊控股的股票代碼是 00700。對的,你沒猜錯,’http://quotes.money.163.com/hkstock/cwsj_’ + 股票代碼 + ‘.html’,就是各個上市公司的財務資料頁面。

思考一個問題,下圖的這些資料,我們需要爬取嗎?

答曰:不需要!為什麼?因為財務報表的格式是統一的。我們需要的是這些報表裡的資料,而不是表的欄目名稱,這些欄目名稱,我們直接手動敲入到資料庫中就可以了,直接作為資料庫的列名。

那麼,這些報表資料如何獲取呢?請看下圖:

在時間選擇框這裡,我們可以獲取到一共有哪些時間的財務報表。點擊查詢按鈕,我們就可以進行查詢,對點擊主要財務指標的查詢按鈕這個動作,使用 Fiddler 進行抓包分析。

抓包截圖如下:

我們可以看到,這個點擊查詢按鈕,發送的請求位址和返回資料。從上圖可以看出返回的資料是以 JSON 格式存儲的。那麼我們只要解析出這個 JSON 資料,就可以獲得《主要財務指標》了。

同理,通過抓包可知,主要財務指標、利潤表、資產負債表、現金流量表請求的 URL 分別如下:

http://quotes.money.163.com/hk/service/cwsj_service.php?symbol=00700&start=2006-06-30&end=2016-12-31&type=cwzb

http://quotes.money.163.com/hk/service/cwsj_service.php?symbol=00700&start=2006-06-30&end=2016-12-31&type=lrb

http://quotes.money.163.com/hk/hk/service/cwsj_service.php?symbol=00700&start=2006-12-31&end=2016-12-31&type=fzb

http://quotes.money.163.com/hk/service/cwsj_service.php?symbol=00700&start=2006-06-30&end=2016-12-31&type=llb

發現規律了嗎?

symbol=股票代碼

start=最早的財務報表時間

end=最近的財務報表時間

type=報表縮寫(cwz代表主要財務指標,lrb代表利潤表,fzb代表負債表,llb代表現金流量表)

已經知道了各個請求的位址,那麼接下來就是解析 JSON 資料了。

可以看到,資料存儲是用的英文,我們得與下圖的中文進行對應,創建一個字典進行存儲。

別問我,我是怎麼對應出來的。我只想說,我花費了半個多小時,對資料,對得我頭暈眼花。

最終生成的對照表如下:

編寫代碼

在繼續看文本之前,希望你已經掌握以下知識:

SQL 基礎語法。

MySQL 資料庫的安裝與使用。

Python 操作 MySQL 資料庫的方法。

SQLyog 的安裝與使用。SQLyog 是一個快速而簡潔的圖形化管理 MySQL 資料庫的工具,它能夠在任何地點有效地管理你的資料庫。

Python3 爬蟲基礎。

01.在 SQLyog 中創建表

我們創建一個名字為 financialdata 的資料庫,並根據網站情況創建四個表,分別為:

cwzb(主要財務指標 )。

fzb(資產負債表 )。

llb(現金流量表 )。

lrb(利潤表)。

除了財務報表中的資料,我們還需要額外添加股票名、股票代碼、報表日期,用以區分不同股票,不同時間的財務報表情況。

各個資料的資料類型,我是粗略分配的,可以根據實際情況和自己的需求進行設置。當然,如果為了省事,可以像我一樣:除了報表時間設置為 date 類型外,其他都設置為 char(30)類型即可。

好了,準備工作都好了,我們開始編寫代碼吧,需要注意的一點是:在創建資料庫連接的時候,我們需要指定 charset 參數,將其設置為 ’utf8’,因為資料庫中存在中文,如果不設置,資料無法導入,當然,記得更改你的資料庫名和密碼。

02.編寫代碼

編寫代碼如下:

#-*- coding:UTF-8 -*- import pymysql import requests import json import re from bs4 import BeautifulSoup if __name__ == '__main__': #打開資料庫連接:host-連接主機位址,port-埠號,user-用戶名,passwd-使用者密碼,db-資料庫名,charset-編碼 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='yourpasswd',db='financialdata',charset='utf8') #使用cursor()方法獲取操作游標 cursor = conn.cursor() #主要財務指標 cwzb_dict = {'EPS':'基本每股收益','EPS_DILUTED':'攤薄每股收益','GROSS_MARGIN':'毛利率', 'CAPITAL_ADEQUACY':'資本充足率','LOANS_DEPOSITS':'貸款回報率','ROTA':'總資產收益率', 'ROEQUITY':'淨資產收益率','CURRENT_RATIO':'流動比率','QUICK_RATIO':'速動比率', 'ROLOANS':'存貸比','INVENTORY_TURNOVER':'存貨周轉率','GENERAL_ADMIN_RATIO':'管理費用比率', 'TOTAL_ASSET2TURNOVER':'資產周轉率','FINCOSTS_GROSSPROFIT':'財務費用比率','TURNOVER_CASH':'銷售現金比率','YEAREND_DATE':'報表日期'} #利潤表 lrb_dict = {'TURNOVER':'總營收','OPER_PROFIT':'經營利潤','PBT':'除稅前利潤', 'NET_PROF':'淨利潤','EPS':'每股基本盈利','DPS':'每股派息', 'INCOME_INTEREST':'利息收益','INCOME_NETTRADING':'交易收益','INCOME_NETFEE':'費用收益','YEAREND_DATE':'報表日期'} #資產負債表 fzb_dict = { 'FIX_ASS':'固定資產','CURR_ASS':'流動資產','CURR_LIAB':'流動負債', 'INVENTORY':'存款','CASH':'現金及銀行存結','OTHER_ASS':'其他資產', 'TOTAL_ASS':'總資產','TOTAL_LIAB':'總負債','EQUITY':'股東權益', 'CASH_SHORTTERMFUND':'庫存現金及短期資金','DEPOSITS_FROM_CUSTOMER':'客戶存款', 'FINANCIALASSET_SALE':'可供出售之證券','LOAN_TO_BANK':'銀行同業存款及貸款', 'DERIVATIVES_LIABILITIES':'金融負債','DERIVATIVES_ASSET':'金融資產','YEAREND_DATE':'報表日期'} #現金流表 llb_dict = { 'CF_NCF_OPERACT':'經營活動產生的現金流','CF_INT_REC':'已收利息','CF_INT_PAID':'已付利息', 'CF_INT_REC':'已收股息','CF_DIV_PAID':'已派股息','CF_INV':'投資活動產生現金流', 'CF_FIN_ACT':'融資活動產生現金流','CF_BEG':'期初現金及現金等價物','CF_CHANGE_CSH':'現金及現金等價物淨增加額', 'CF_END':'期末現金及現金等價物','CF_EXCH':'匯率變動影響','YEAREND_DATE':'報表日期'} #總表 table_dict = {'cwzb':cwzb_dict,'lrb':lrb_dict,'fzb':fzb_dict,'llb':llb_dict} #請求頭 headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.8', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.109 Safari/537.36',} #上市股票地址 target_url = 'http://quotes.money.163.com/hkstock/cwsj_00700.html' req = requests.get(url = target_url, headers = headers) req.encoding = 'utf-8' html = req.text page_bf = BeautifulSoup(html, 'lxml') #股票名稱,股票代碼 name = page_bf.find_all('span', class_ = 'name')[0].string code = page_bf.find_all('span', class_ = 'code')[0].string code = re.findall('d+',code)[0] #列印股票資訊 print(name + ':' + code) print('') #存儲各個表名的清單 table_name_list = [] table_date_list = [] each_date_list = [] url_list = [] #表名和表時間 table_name = page_bf.find_all('div', class_ = 'titlebar3') for each_table_name in table_name: #表名 table_name_list.append(each_table_name.span.string) #表時間 for each_table_date in each_table_name.div.find_all('select', id = re.compile('.+1$')): url_list.append(re.findall('(w+)1',each_table_date.get('id'))[0]) for each_date in each_table_date.find_all('option'): each_date_list.append(each_date.string) table_date_list.append(each_date_list) each_date_list = [] #插入資訊 for i in range(len(table_name_list)): print('表名:',table_name_list[i]) print('') #獲取資料位址 url = 'http://quotes.money.163.com/hk/service/cwsj_service.php?symbol={}&start={}&end={}&type={}&unit=yuan'.format(code,table_date_list[i][-1],table_date_list[i][0],url_list[i]) req_table = requests.get(url = url, headers = headers) value_dict = {} for each_data in req_table.json(): value_dict['股票名'] = name value_dict['股票代碼'] = code for key, value in each_data.items(): if key in table_dict[url_list[i]]: value_dict[table_dict[url_list[i]][key]] = value # print(value_dict) sql1 = """ INSERT INTO %s (`股票名`,`股票代碼`,`報表日期`) VALUES ('%s','%s','%s')""" % (url_list[i],value_dict['股票名'],value_dict['股票代碼'],value_dict['報表日期']) print(sql1) try: cursor.execute(sql1) # 執行sql語句 conn.commit() except: # 發生錯誤時回滾 conn.rollback() for key, value in value_dict.items(): if key not in ['股票名','股票代碼','報表日期']: sql2 = """ UPDATE %s SET %s='%s' WHERE `股票名`='%s' AND `報表日期`='%s'""" % (url_list[i],key,value,value_dict['股票名'],value_dict['報表日期']) print(sql2) try: cursor.execute(sql2) # 執行sql語句 conn.commit() except: # 發生錯誤時回滾 conn.rollback() value_dict = {} # 關閉資料庫連接 cursor.close() conn.close()

看下運行效果,我們已經順利地將騰訊控股的財務報表帶入資料庫中了。

上述代碼比較粗糙,繼續完善代碼。對代碼進行重構,創建一個獲取資料包表的類。根據使用者輸入股票代碼,下載相應股票的財務報表,並顯示下載進度,實現效果如下所示:

一直在看,何不自己寫個代碼試試?實現效果如上圖所示!只有自己動手,才能體會到程式設計的快樂,對知識掌握也就更加扎實。

如果你覺得代碼編寫的差不多了,想對照代碼看一看或者感覺自己無需動手,這種東西就可以輕鬆掌握。

那麼可以從我的 Github 獲取上圖實現效果的代碼:https://github.com/Jack-Cherish/python-spider/blob/master/financical.py

總結

本文沒有實現批量上市公司財務報表的獲取與入庫,因為方法有很多。

首先,我們可以根據使用者提供的股票代碼進行批量下載。比如用戶輸入:00700,00701,00702。

然後程式根據輸入的股票代碼,進行相應的解析,創建出對應的URL連結,即可實現批量下載。

另外,也可以通過程式自動獲取連結,比如網易財經提供了各個股票板塊的漲幅排行榜、跌幅排行榜、成交額排行榜等,我們通過獲取這些股票的連結,也可以進行財務報表批量下載,方法很簡單,因此不再累贅。

其他:

在使用 MySQL 創建資料庫連接的時候,如果資料庫(utf8 編碼)中有中文,一定要記得設置 charset 參數為 utf8(對應資料庫編碼)。

學習 SQL 很有説明,資料庫查詢很方便,方便我們進行資料分析。

所有爬蟲實戰的代碼,均可以在我的 Github 進行下載(Star 數量要破 100 了,給個助攻好不好?):https://github.com/Jack-Cherish/python-spider。

如有問題,請留言。如有錯誤,還望指正,謝謝!

崔家華

知名博客博主

現就讀于東北大學模式識別與智慧系統專業。本科期間,曾擔任學生會”科技創新中心主任”一職,負責組織各類科技競賽相關活動。與此同時,熱愛科技競賽,曾於 2015 年獲得第十屆全國大學生“飛思卡爾”杯智慧車競賽全國一等獎。研究生期間,致力於機器學習,在知名博客已取得了不錯的關注度。

【51CTO原創稿件,合作網站轉載請注明原文作者和出處為51CTO.com】

這個財務資料欄目中,提供了《主要財務指標》、《利潤表》、《資產負債表》以及《現金流量表》。

從圖中可以看到,該網站提供了財務資料線上流覽功能,但是沒有提供財務報表下載功能,如何將每年的財務資料獲取,並存入資料庫,方便我們後續的分析呢?沒錯,這就是本文的主題:財務報表爬取入庫。

網站分析

我們以騰訊控股的財務資料為例進行分析。

它的URL:http://quotes.money.163.com/hkstock/cwsj_00700.html

看一下這個 URL 地址有什麼特點?騰訊控股的股票代碼是 00700。對的,你沒猜錯,’http://quotes.money.163.com/hkstock/cwsj_’ + 股票代碼 + ‘.html’,就是各個上市公司的財務資料頁面。

思考一個問題,下圖的這些資料,我們需要爬取嗎?

答曰:不需要!為什麼?因為財務報表的格式是統一的。我們需要的是這些報表裡的資料,而不是表的欄目名稱,這些欄目名稱,我們直接手動敲入到資料庫中就可以了,直接作為資料庫的列名。

那麼,這些報表資料如何獲取呢?請看下圖:

在時間選擇框這裡,我們可以獲取到一共有哪些時間的財務報表。點擊查詢按鈕,我們就可以進行查詢,對點擊主要財務指標的查詢按鈕這個動作,使用 Fiddler 進行抓包分析。

抓包截圖如下:

我們可以看到,這個點擊查詢按鈕,發送的請求位址和返回資料。從上圖可以看出返回的資料是以 JSON 格式存儲的。那麼我們只要解析出這個 JSON 資料,就可以獲得《主要財務指標》了。

同理,通過抓包可知,主要財務指標、利潤表、資產負債表、現金流量表請求的 URL 分別如下:

http://quotes.money.163.com/hk/service/cwsj_service.php?symbol=00700&start=2006-06-30&end=2016-12-31&type=cwzb

http://quotes.money.163.com/hk/service/cwsj_service.php?symbol=00700&start=2006-06-30&end=2016-12-31&type=lrb

http://quotes.money.163.com/hk/hk/service/cwsj_service.php?symbol=00700&start=2006-12-31&end=2016-12-31&type=fzb

http://quotes.money.163.com/hk/service/cwsj_service.php?symbol=00700&start=2006-06-30&end=2016-12-31&type=llb

發現規律了嗎?

symbol=股票代碼

start=最早的財務報表時間

end=最近的財務報表時間

type=報表縮寫(cwz代表主要財務指標,lrb代表利潤表,fzb代表負債表,llb代表現金流量表)

已經知道了各個請求的位址,那麼接下來就是解析 JSON 資料了。

可以看到,資料存儲是用的英文,我們得與下圖的中文進行對應,創建一個字典進行存儲。

別問我,我是怎麼對應出來的。我只想說,我花費了半個多小時,對資料,對得我頭暈眼花。

最終生成的對照表如下:

編寫代碼

在繼續看文本之前,希望你已經掌握以下知識:

SQL 基礎語法。

MySQL 資料庫的安裝與使用。

Python 操作 MySQL 資料庫的方法。

SQLyog 的安裝與使用。SQLyog 是一個快速而簡潔的圖形化管理 MySQL 資料庫的工具,它能夠在任何地點有效地管理你的資料庫。

Python3 爬蟲基礎。

01.在 SQLyog 中創建表

我們創建一個名字為 financialdata 的資料庫,並根據網站情況創建四個表,分別為:

cwzb(主要財務指標 )。

fzb(資產負債表 )。

llb(現金流量表 )。

lrb(利潤表)。

除了財務報表中的資料,我們還需要額外添加股票名、股票代碼、報表日期,用以區分不同股票,不同時間的財務報表情況。

各個資料的資料類型,我是粗略分配的,可以根據實際情況和自己的需求進行設置。當然,如果為了省事,可以像我一樣:除了報表時間設置為 date 類型外,其他都設置為 char(30)類型即可。

好了,準備工作都好了,我們開始編寫代碼吧,需要注意的一點是:在創建資料庫連接的時候,我們需要指定 charset 參數,將其設置為 ’utf8’,因為資料庫中存在中文,如果不設置,資料無法導入,當然,記得更改你的資料庫名和密碼。

02.編寫代碼

編寫代碼如下:

#-*- coding:UTF-8 -*- import pymysql import requests import json import re from bs4 import BeautifulSoup if __name__ == '__main__': #打開資料庫連接:host-連接主機位址,port-埠號,user-用戶名,passwd-使用者密碼,db-資料庫名,charset-編碼 conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='yourpasswd',db='financialdata',charset='utf8') #使用cursor()方法獲取操作游標 cursor = conn.cursor() #主要財務指標 cwzb_dict = {'EPS':'基本每股收益','EPS_DILUTED':'攤薄每股收益','GROSS_MARGIN':'毛利率', 'CAPITAL_ADEQUACY':'資本充足率','LOANS_DEPOSITS':'貸款回報率','ROTA':'總資產收益率', 'ROEQUITY':'淨資產收益率','CURRENT_RATIO':'流動比率','QUICK_RATIO':'速動比率', 'ROLOANS':'存貸比','INVENTORY_TURNOVER':'存貨周轉率','GENERAL_ADMIN_RATIO':'管理費用比率', 'TOTAL_ASSET2TURNOVER':'資產周轉率','FINCOSTS_GROSSPROFIT':'財務費用比率','TURNOVER_CASH':'銷售現金比率','YEAREND_DATE':'報表日期'} #利潤表 lrb_dict = {'TURNOVER':'總營收','OPER_PROFIT':'經營利潤','PBT':'除稅前利潤', 'NET_PROF':'淨利潤','EPS':'每股基本盈利','DPS':'每股派息', 'INCOME_INTEREST':'利息收益','INCOME_NETTRADING':'交易收益','INCOME_NETFEE':'費用收益','YEAREND_DATE':'報表日期'} #資產負債表 fzb_dict = { 'FIX_ASS':'固定資產','CURR_ASS':'流動資產','CURR_LIAB':'流動負債', 'INVENTORY':'存款','CASH':'現金及銀行存結','OTHER_ASS':'其他資產', 'TOTAL_ASS':'總資產','TOTAL_LIAB':'總負債','EQUITY':'股東權益', 'CASH_SHORTTERMFUND':'庫存現金及短期資金','DEPOSITS_FROM_CUSTOMER':'客戶存款', 'FINANCIALASSET_SALE':'可供出售之證券','LOAN_TO_BANK':'銀行同業存款及貸款', 'DERIVATIVES_LIABILITIES':'金融負債','DERIVATIVES_ASSET':'金融資產','YEAREND_DATE':'報表日期'} #現金流表 llb_dict = { 'CF_NCF_OPERACT':'經營活動產生的現金流','CF_INT_REC':'已收利息','CF_INT_PAID':'已付利息', 'CF_INT_REC':'已收股息','CF_DIV_PAID':'已派股息','CF_INV':'投資活動產生現金流', 'CF_FIN_ACT':'融資活動產生現金流','CF_BEG':'期初現金及現金等價物','CF_CHANGE_CSH':'現金及現金等價物淨增加額', 'CF_END':'期末現金及現金等價物','CF_EXCH':'匯率變動影響','YEAREND_DATE':'報表日期'} #總表 table_dict = {'cwzb':cwzb_dict,'lrb':lrb_dict,'fzb':fzb_dict,'llb':llb_dict} #請求頭 headers = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.8', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.109 Safari/537.36',} #上市股票地址 target_url = 'http://quotes.money.163.com/hkstock/cwsj_00700.html' req = requests.get(url = target_url, headers = headers) req.encoding = 'utf-8' html = req.text page_bf = BeautifulSoup(html, 'lxml') #股票名稱,股票代碼 name = page_bf.find_all('span', class_ = 'name')[0].string code = page_bf.find_all('span', class_ = 'code')[0].string code = re.findall('d+',code)[0] #列印股票資訊 print(name + ':' + code) print('') #存儲各個表名的清單 table_name_list = [] table_date_list = [] each_date_list = [] url_list = [] #表名和表時間 table_name = page_bf.find_all('div', class_ = 'titlebar3') for each_table_name in table_name: #表名 table_name_list.append(each_table_name.span.string) #表時間 for each_table_date in each_table_name.div.find_all('select', id = re.compile('.+1$')): url_list.append(re.findall('(w+)1',each_table_date.get('id'))[0]) for each_date in each_table_date.find_all('option'): each_date_list.append(each_date.string) table_date_list.append(each_date_list) each_date_list = [] #插入資訊 for i in range(len(table_name_list)): print('表名:',table_name_list[i]) print('') #獲取資料位址 url = 'http://quotes.money.163.com/hk/service/cwsj_service.php?symbol={}&start={}&end={}&type={}&unit=yuan'.format(code,table_date_list[i][-1],table_date_list[i][0],url_list[i]) req_table = requests.get(url = url, headers = headers) value_dict = {} for each_data in req_table.json(): value_dict['股票名'] = name value_dict['股票代碼'] = code for key, value in each_data.items(): if key in table_dict[url_list[i]]: value_dict[table_dict[url_list[i]][key]] = value # print(value_dict) sql1 = """ INSERT INTO %s (`股票名`,`股票代碼`,`報表日期`) VALUES ('%s','%s','%s')""" % (url_list[i],value_dict['股票名'],value_dict['股票代碼'],value_dict['報表日期']) print(sql1) try: cursor.execute(sql1) # 執行sql語句 conn.commit() except: # 發生錯誤時回滾 conn.rollback() for key, value in value_dict.items(): if key not in ['股票名','股票代碼','報表日期']: sql2 = """ UPDATE %s SET %s='%s' WHERE `股票名`='%s' AND `報表日期`='%s'""" % (url_list[i],key,value,value_dict['股票名'],value_dict['報表日期']) print(sql2) try: cursor.execute(sql2) # 執行sql語句 conn.commit() except: # 發生錯誤時回滾 conn.rollback() value_dict = {} # 關閉資料庫連接 cursor.close() conn.close()

看下運行效果,我們已經順利地將騰訊控股的財務報表帶入資料庫中了。

上述代碼比較粗糙,繼續完善代碼。對代碼進行重構,創建一個獲取資料包表的類。根據使用者輸入股票代碼,下載相應股票的財務報表,並顯示下載進度,實現效果如下所示:

一直在看,何不自己寫個代碼試試?實現效果如上圖所示!只有自己動手,才能體會到程式設計的快樂,對知識掌握也就更加扎實。

如果你覺得代碼編寫的差不多了,想對照代碼看一看或者感覺自己無需動手,這種東西就可以輕鬆掌握。

那麼可以從我的 Github 獲取上圖實現效果的代碼:https://github.com/Jack-Cherish/python-spider/blob/master/financical.py

總結

本文沒有實現批量上市公司財務報表的獲取與入庫,因為方法有很多。

首先,我們可以根據使用者提供的股票代碼進行批量下載。比如用戶輸入:00700,00701,00702。

然後程式根據輸入的股票代碼,進行相應的解析,創建出對應的URL連結,即可實現批量下載。

另外,也可以通過程式自動獲取連結,比如網易財經提供了各個股票板塊的漲幅排行榜、跌幅排行榜、成交額排行榜等,我們通過獲取這些股票的連結,也可以進行財務報表批量下載,方法很簡單,因此不再累贅。

其他:

在使用 MySQL 創建資料庫連接的時候,如果資料庫(utf8 編碼)中有中文,一定要記得設置 charset 參數為 utf8(對應資料庫編碼)。

學習 SQL 很有説明,資料庫查詢很方便,方便我們進行資料分析。

所有爬蟲實戰的代碼,均可以在我的 Github 進行下載(Star 數量要破 100 了,給個助攻好不好?):https://github.com/Jack-Cherish/python-spider。

如有問題,請留言。如有錯誤,還望指正,謝謝!

崔家華

知名博客博主

現就讀于東北大學模式識別與智慧系統專業。本科期間,曾擔任學生會”科技創新中心主任”一職,負責組織各類科技競賽相關活動。與此同時,熱愛科技競賽,曾於 2015 年獲得第十屆全國大學生“飛思卡爾”杯智慧車競賽全國一等獎。研究生期間,致力於機器學習,在知名博客已取得了不錯的關注度。

【51CTO原創稿件,合作網站轉載請注明原文作者和出處為51CTO.com】

Next Article
喜欢就按个赞吧!!!
点击关闭提示