自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

原創(chuàng)
數(shù)據(jù)庫 開發(fā)工具
沃倫·巴菲特( Warren Buffett),全球著名的投資商。從事股票、電子現(xiàn)貨、基金行業(yè)。在 2017 年 7 月 17 日,《福布斯富豪榜》發(fā)布,沃倫·巴菲特以凈資產(chǎn) 734 億美元排名第四。

[[202360]]

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

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

[[202361]]

他的投資名言有很多:

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

若你不打算持有某只股票達十年,則十分鐘也不要持有。

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

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

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

從他的這些名言中,我們不難發(fā)現(xiàn),巴菲特做的是長期投資,他投一家公司,抱定的目標是持續(xù)持有,不因為價格原因而出售。他看準一家公司,會分析這家公司的競爭優(yōu)勢,也會分析這家公司的對手的競爭優(yōu)勢,然后做出投資決策。

他是怎么確定一家公司是否值得自己長期投資,是否具有競爭優(yōu)勢的呢?其中,最有效、最常用的手段之一就是分析上市公司財務報表。網(wǎng)上有很多《跟巴菲特學看上市公司財務報表》諸如此類的文章,仁者見仁智者見智。

本文重點不在于如何分析財務報表,而是如何獲得財務報表,為后續(xù)的方便分析做準備。

實戰(zhàn)背景

  • Github代碼獲?。?a >https://github.com/Jack-Cherish/python-spider
  • Python版本: Python3.x
  • 運行平臺: Windows
  • IDE: Sublime text3

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

今天,我們看哪個金融門戶網(wǎng)站?網(wǎng)易財經(jīng)!

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

這個網(wǎng)站長這樣:

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

可以看到,我截圖的時間,騰訊控股”綠了”,也就是跌了。點擊財務數(shù)據(jù),我們就可以看到騰訊控股的財務報表,如圖所示:

這個財務數(shù)據(jù)欄目中,提供了《主要財務指標》、《利潤表》、《資產(chǎn)負債表》以及《現(xiàn)金流量表》。

從圖中可以看到,該網(wǎng)站提供了財務數(shù)據(jù)在線瀏覽功能,但是沒有提供財務報表下載功能,如何將每年的財務數(shù)據(jù)獲取,并存入數(shù)據(jù)庫,方便我們后續(xù)的分析呢?沒錯,這就是本文的主題:財務報表爬取入庫。

網(wǎng)站分析

我們以騰訊控股的財務數(shù)據(jù)為例進行分析。

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

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

思考一個問題,下圖的這些數(shù)據(jù),我們需要爬取嗎?

答曰:不需要!為什么?因為財務報表的格式是統(tǒng)一的。我們需要的是這些報表里的數(shù)據(jù),而不是表的欄目名稱,這些欄目名稱,我們直接手動敲入到數(shù)據(jù)庫中就可以了,直接作為數(shù)據(jù)庫的列名。

那么,這些報表數(shù)據(jù)如何獲取呢?請看下圖:

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

抓包截圖如下:

我們可以看到,這個點擊查詢按鈕,發(fā)送的請求地址和返回數(shù)據(jù)。從上圖可以看出返回的數(shù)據(jù)是以 JSON 格式存儲的。那么我們只要解析出這個 JSON 數(shù)據(jù),就可以獲得《主要財務指標》了。

同理,通過抓包可知,主要財務指標、利潤表、資產(chǎn)負債表、現(xiàn)金流量表請求的 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

發(fā)現(xiàn)規(guī)律了嗎?

  • symbol=股票代碼
  • start=最早的財務報表時間
  • end=最近的財務報表時間
  • type=報表縮寫(cwz代表主要財務指標,lrb代表利潤表,fzb代表負債表,llb代表現(xiàn)金流量表)

已經(jīng)知道了各個請求的地址,那么接下來就是解析 JSON 數(shù)據(jù)了。

可以看到,數(shù)據(jù)存儲是用的英文,我們得與下圖的中文進行對應,創(chuàng)建一個字典進行存儲。

別問我,我是怎么對應出來的。我只想說,我花費了半個多小時,對數(shù)據(jù),對得我頭暈眼花。

最終生成的對照表如下:

編寫代碼

在繼續(xù)看文本之前,希望你已經(jīng)掌握以下知識:

  • SQL 基礎(chǔ)語法。
  • MySQL 數(shù)據(jù)庫的安裝與使用。
  • Python 操作 MySQL 數(shù)據(jù)庫的方法。
  • SQLyog 的安裝與使用。SQLyog 是一個快速而簡潔的圖形化管理 MySQL 數(shù)據(jù)庫的工具,它能夠在任何地點有效地管理你的數(shù)據(jù)庫。
  • Python3 爬蟲基礎(chǔ)。

01.在 SQLyog 中創(chuàng)建表

我們創(chuàng)建一個名字為 financialdata 的數(shù)據(jù)庫,并根據(jù)網(wǎng)站情況創(chuàng)建四個表,分別為:

  • cwzb(主要財務指標 )。
  • fzb(資產(chǎn)負債表 )。
  • llb(現(xiàn)金流量表 )。
  • lrb(利潤表)。

除了財務報表中的數(shù)據(jù),我們還需要額外添加股票名、股票代碼、報表日期,用以區(qū)分不同股票,不同時間的財務報表情況。

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

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

02.編寫代碼

編寫代碼如下:

  1. #-*- coding:UTF-8 -*- 
  2. import pymysql 
  3. import requests 
  4. import json 
  5. import re 
  6. from bs4 import BeautifulSoup 
  7.  
  8. if __name__ == '__main__'
  9.     #打開數(shù)據(jù)庫連接:host-連接主機地址,port-端口號,user-用戶名,passwd-用戶密碼,db-數(shù)據(jù)庫名,charset-編碼 
  10.     conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='yourpasswd',db='financialdata',charset='utf8'
  11.     #使用cursor()方法獲取操作游標 
  12.     cursor = conn.cursor()  
  13.  
  14.     #主要財務指標 
  15.     cwzb_dict = {'EPS':'基本每股收益','EPS_DILUTED':'攤薄每股收益','GROSS_MARGIN':'毛利率'
  16.         'CAPITAL_ADEQUACY':'資本充足率','LOANS_DEPOSITS':'貸款回報率','ROTA':'總資產(chǎn)收益率'
  17.         'ROEQUITY':'凈資產(chǎn)收益率','CURRENT_RATIO':'流動比率','QUICK_RATIO':'速動比率'
  18.         'ROLOANS':'存貸比','INVENTORY_TURNOVER':'存貨周轉(zhuǎn)率','GENERAL_ADMIN_RATIO':'管理費用比率'
  19.         'TOTAL_ASSET2TURNOVER':'資產(chǎn)周轉(zhuǎn)率','FINCOSTS_GROSSPROFIT':'財務費用比率','TURNOVER_CASH':'銷售現(xiàn)金比率','YEAREND_DATE':'報表日期'
  20.  
  21.     #利潤表 
  22.     lrb_dict = {'TURNOVER':'總營收','OPER_PROFIT':'經(jīng)營利潤','PBT':'除稅前利潤'
  23.         'NET_PROF':'凈利潤','EPS':'每股基本盈利','DPS':'每股派息'
  24.         'INCOME_INTEREST':'利息收益','INCOME_NETTRADING':'交易收益','INCOME_NETFEE':'費用收益','YEAREND_DATE':'報表日期'
  25.  
  26.     #資產(chǎn)負債表 
  27.     fzb_dict = { 
  28.         'FIX_ASS':'固定資產(chǎn)','CURR_ASS':'流動資產(chǎn)','CURR_LIAB':'流動負債'
  29.         'INVENTORY':'存款','CASH':'現(xiàn)金及銀行存結(jié)','OTHER_ASS':'其他資產(chǎn)'
  30.         'TOTAL_ASS':'總資產(chǎn)','TOTAL_LIAB':'總負債','EQUITY':'股東權(quán)益'
  31.         'CASH_SHORTTERMFUND':'庫存現(xiàn)金及短期資金','DEPOSITS_FROM_CUSTOMER':'客戶存款'
  32.         'FINANCIALASSET_SALE':'可供出售之證券','LOAN_TO_BANK':'銀行同業(yè)存款及貸款'
  33.         'DERIVATIVES_LIABILITIES':'金融負債','DERIVATIVES_ASSET':'金融資產(chǎn)','YEAREND_DATE':'報表日期'
  34.  
  35.     #現(xiàn)金流表 
  36.     llb_dict = { 
  37.         'CF_NCF_OPERACT':'經(jīng)營活動產(chǎn)生的現(xiàn)金流','CF_INT_REC':'已收利息','CF_INT_PAID':'已付利息'
  38.         'CF_INT_REC':'已收股息','CF_DIV_PAID':'已派股息','CF_INV':'投資活動產(chǎn)生現(xiàn)金流'
  39.         'CF_FIN_ACT':'融資活動產(chǎn)生現(xiàn)金流','CF_BEG':'期初現(xiàn)金及現(xiàn)金等價物','CF_CHANGE_CSH':'現(xiàn)金及現(xiàn)金等價物凈增加額'
  40.         'CF_END':'期末現(xiàn)金及現(xiàn)金等價物','CF_EXCH':'匯率變動影響','YEAREND_DATE':'報表日期'
  41.  
  42.     #總表 
  43.     table_dict = {'cwzb':cwzb_dict,'lrb':lrb_dict,'fzb':fzb_dict,'llb':llb_dict} 
  44.  
  45.     #請求頭 
  46.     headers = {'Accept''text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'
  47.         'Accept-Encoding''gzip, deflate'
  48.         'Accept-Language''zh-CN,zh;q=0.8'
  49.         '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',} 
  50.  
  51.     #上市股票地址 
  52.     target_url = 'http://quotes.money.163.com/hkstock/cwsj_00700.html' 
  53.     req = requests.get(url = target_url, headers = headers) 
  54.     req.encoding = 'utf-8' 
  55.     html = req.text 
  56.     page_bf = BeautifulSoup(html, 'lxml'
  57.     #股票名稱,股票代碼 
  58.     name = page_bf.find_all('span', class_ = 'name')[0].string 
  59.     code = page_bf.find_all('span', class_ = 'code')[0].string 
  60.     code = re.findall('\d+',code)[0] 
  61.     #打印股票信息 
  62.     print(name + ':' + code) 
  63.     print(''
  64.     #存儲各個表名的列表 
  65.     table_name_list = [] 
  66.     table_date_list = [] 
  67.     each_date_list = [] 
  68.     url_list = [] 
  69.     #表名和表時間 
  70.     table_name = page_bf.find_all('div', class_ = 'titlebar3'
  71.     for each_table_name in table_name: 
  72.         #表名 
  73.         table_name_list.append(each_table_name.span.string) 
  74.         #表時間 
  75.         for each_table_date in each_table_name.div.find_all('select', id = re.compile('.+1$')): 
  76.             url_list.append(re.findall('(\w+)1',each_table_date.get('id'))[0]) 
  77.             for each_date in each_table_date.find_all('option'): 
  78.                 each_date_list.append(each_date.string) 
  79.             table_date_list.append(each_date_list) 
  80.             each_date_list = [] 
  81.  
  82.     #插入信息 
  83.     for i in range(len(table_name_list)): 
  84.         print('表名:',table_name_list[i]) 
  85.         print(''
  86.  
  87.         #獲取數(shù)據(jù)地址 
  88.         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]) 
  89.         req_table = requests.get(url = url, headers = headers) 
  90.         value_dict = {} 
  91.         for each_data in req_table.json(): 
  92.             value_dict['股票名'] = name 
  93.             value_dict['股票代碼'] = code 
  94.             for key, value in each_data.items(): 
  95.                 if key in table_dict[url_list[i]]: 
  96.                     value_dict[table_dict[url_list[i]][key]] = value 
  97.  
  98.             # print(value_dict) 
  99.             sql1 = ""
  100.             INSERT INTO %s (`股票名`,`股票代碼`,`報表日期`) VALUES ('%s','%s','%s')""" % (url_list[i],value_dict['股票名'],value_dict['股票代碼'],value_dict['報表日期']) 
  101.             print(sql1) 
  102.             try: 
  103.                 cursor.execute(sql1) 
  104.                 # 執(zhí)行sql語句 
  105.                 conn.commit() 
  106.             except
  107.                 # 發(fā)生錯誤時回滾 
  108.                 conn.rollback() 
  109.  
  110.             for key, value in value_dict.items(): 
  111.                 if key not in ['股票名','股票代碼','報表日期']: 
  112.                     sql2 = ""
  113.                     UPDATE %s SET %s='%s' WHERE `股票名`='%s' AND `報表日期`='%s'""" % (url_list[i],key,value,value_dict['股票名'],value_dict['報表日期']) 
  114.                     print(sql2) 
  115.                     try: 
  116.                         cursor.execute(sql2) 
  117.                         # 執(zhí)行sql語句 
  118.                         conn.commit() 
  119.                     except
  120.                         # 發(fā)生錯誤時回滾 
  121.                         conn.rollback() 
  122.             value_dict = {} 
  123.  
  124.     # 關(guān)閉數(shù)據(jù)庫連接 
  125.     cursor.close()  
  126.     conn.close() 

看下運行效果,我們已經(jīng)順利地將騰訊控股的財務報表帶入數(shù)據(jù)庫中了。

上述代碼比較粗糙,繼續(xù)完善代碼。對代碼進行重構(gòu),創(chuàng)建一個獲取數(shù)據(jù)報表的類。根據(jù)用戶輸入股票代碼,下載相應股票的財務報表,并顯示下載進度,實現(xiàn)效果如下所示:

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

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

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

總結(jié)

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

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

然后程序根據(jù)輸入的股票代碼,進行相應的解析,創(chuàng)建出對應的URL鏈接,即可實現(xiàn)批量下載。

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

其他:

  • 在使用 MySQL 創(chuàng)建數(shù)據(jù)庫連接的時候,如果數(shù)據(jù)庫(utf8 編碼)中有中文,一定要記得設(shè)置 charset 參數(shù)為 utf8(對應數(shù)據(jù)庫編碼)。
  • 學習 SQL 很有幫助,數(shù)據(jù)庫查詢很方便,方便我們進行數(shù)據(jù)分析。
  • 所有爬蟲實戰(zhàn)的代碼,均可以在我的 Github 進行下載(Star 數(shù)量要破 100 了,給個助攻好不好?):https://github.com/Jack-Cherish/python-spider
  • 如有問題,請留言。如有錯誤,還望指正,謝謝!

[[202371]]

崔家華

知名博客博主

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

【51CTO原創(chuàng)稿件,合作站點轉(zhuǎn)載請注明原文作者和出處為51CTO.com】

責任編輯:武曉燕 來源: 51CTO技術(shù)棧
相關(guān)推薦

2024-05-14 13:44:16

網(wǎng)絡安全財務報表

2010-06-08 18:47:07

IT服務運維管理摩卡軟件

2011-11-21 14:21:34

2017-05-23 08:50:16

巴菲特挑戰(zhàn)

2022-03-24 09:48:59

勒索軟件網(wǎng)絡攻擊

2010-06-11 10:48:20

馬云蓋茨

2009-06-02 08:14:42

2011-06-30 15:23:14

2018-02-02 15:51:20

2011-10-27 16:32:28

2012-02-20 09:50:14

2020-08-18 17:26:46

數(shù)據(jù)爬蟲代碼

2010-09-01 11:03:19

巴菲特蓋茨

2011-11-21 14:16:13

2011-11-21 14:16:52

巴菲特IBM云計算

2009-10-23 09:40:36

養(yǎng)豬丁磊

2009-04-17 09:06:56

鴻海郭臺銘比亞迪

2014-10-10 10:02:16

2011-11-21 14:39:46

巴菲特IBM

2020-07-27 15:56:06

安永
點贊
收藏

51CTO技術(shù)棧公眾號