本文介紹通過來抓取上市公司簡介和行業(yè),昨天我講解了上市公司列表的抓取 , 我們拿到上市公司列表后,就可以實現(xiàn)循環(huán)抓取各個上市公司的詳情數(shù)據(jù) 。本文將初次涉及到的模塊使用,將介紹模塊中常用的類和方法,還包括xpath介紹和使用 。
先回顧一下本主題“抓取上市公司財務(wù)數(shù)據(jù)”的內(nèi)容體系,分成9節(jié)來為?大家講解,從0到1來詳細(xì)拆解程序開發(fā)流程和編碼實現(xiàn),這套體系內(nèi)容適合給零基礎(chǔ)的小白學(xué)者學(xué)習(xí),同時也對熟悉但對數(shù)據(jù)采集不熟練的量化專家提供一套抓取的最佳實踐 。其包含的主要章節(jié)如下:
1. 搭建代碼庫和運行環(huán)境
2. Win10搭建開發(fā)環(huán)境
3. 爬蟲應(yīng)用運行()鏡像準(zhǔn)備
4. 編碼實現(xiàn)上市公司列表抓取
5. 編碼實現(xiàn)上市公司簡介和行業(yè)板塊抓取
6. 編碼實現(xiàn)上市公司企業(yè)財務(wù)摘要抓取
7. 編碼實現(xiàn)上市公司歷年財務(wù)數(shù)據(jù)抓取
8. 編碼實現(xiàn)上市公司財務(wù)數(shù)據(jù)抓取結(jié)果入庫(Mysql)
9. 代碼提交及部署運行
本文講解的是其中的第5章節(jié),主要包括:
1)公司簡介頁面的數(shù)據(jù)結(jié)構(gòu)分析
2)編寫公司信息數(shù)據(jù)抓取和解析程序
3)公司簡介抓取程序的運行
4)所屬行業(yè)頁面數(shù)據(jù)抓取和解析
本文涉及到的相關(guān)基礎(chǔ)知識主要有類的使用、xpath表達(dá)式的使用,以字符串的處理 。其中,類支持xpath和css兩種提取元素選擇器方式 , 提取的元素可以使用的方法有:
1. 方法來獲取所選元素的內(nèi)容,結(jié)果為數(shù)組;
2. ,它只提取第一個元素的值,如果無符合條件的元素,則返回None 。
對于xpath的基本使用語法的表達(dá)式含義主要為如下:
1) 為選取此節(jié)點的所有子節(jié)點;
2) 表達(dá)式/代表絕對路徑匹配,從根節(jié)點選?。?
3) 表達(dá)式//代表相對路徑匹配,從所有節(jié)點中查找當(dāng)前選擇的節(jié)點,包括子節(jié)點和后代節(jié)點 , 其第一個/表示根節(jié)點;
4) 表達(dá)式.代表選取當(dāng)前節(jié)點;
5) 表達(dá)式..代表選取當(dāng)前節(jié)點的父節(jié)點;
6) 表達(dá)式@代表選取屬性值,通過屬性值選取數(shù)據(jù) 。常用元素屬性有@id、@name、@type、@class、@、@href 。
xpath提供了100多個內(nèi)建函數(shù),我們抓取常用的內(nèi)建函數(shù)主要使用了text(),用來文本匹配,表示值取當(dāng)前節(jié)點中的文本內(nèi)容 。
另外,我們對解析結(jié)果字符串的處理常用的有:
1. 字符串切割子串,它和數(shù)組的切割子數(shù)組類似,可以直接使用[x:y]、[x:]或[:y]的方式來取子串 。其中x和y為數(shù)值,代表下要切割的起始、結(jié)束下標(biāo)值 。如果使用負(fù)數(shù),則為從字符串結(jié)尾開始反向計算下標(biāo)位置,如'abc'[1:]和'abc'[-2:]的結(jié)果均為'bc';
2. 字符串兩邊的空格去除可以使用strip方法,如'ta b rn'.strip()的結(jié)果為'a b' 。
一、公司簡介頁面的數(shù)據(jù)結(jié)構(gòu)分析
第一步:打開公司簡介頁面
打開公司簡介頁面,以新華醫(yī)療()為例,如下:
第二步:打開頁面的瀏覽器檢查工具
我們通過右鍵-點擊“檢查”(或快捷鍵F12),如下圖:
第三步:使用元素選擇器選擇公司簡介表格
點擊元素的選擇器圖標(biāo) , 如下圖:
再將鼠標(biāo)移動到公司簡介表格的首行 , 并點擊選中公司的圖標(biāo)有什么用? , 如下圖:
第四步:復(fù)制表格首行的xpath信息
我們選擇首行所在的標(biāo)簽 , 點擊右鍵-復(fù)制-復(fù)制XPath , 如下圖:
得到的XPath信息為://*[@id=””]/tbody/tr[1]
二、編寫公司信息數(shù)據(jù)抓取和解析程序
第一步:打開.py模塊文件
打開項目文件夾- , 并選中.py右鍵-Edit with IDLE-Edit with IDLE 3.10(64-bit) , 如下圖:
打開后,如下圖:
第二步:編寫代碼抓取結(jié)果的XPath提取
編寫函數(shù)抓取頁面數(shù)據(jù)代碼,包含參數(shù)code股票代碼,詳情存儲目錄 , 是否重寫結(jié)果文件(若需將抓取結(jié)果覆蓋) 。并先編寫根據(jù)XPath提取元素部分,如下:
def scrapy_detail(self, code, detail_dir, overwrite):detail_url = "https://vip.stock.finance.sina.com.cn/corp/go.php/vCI_CorpInfo/stockid/%s.phtml"resp = request.urlopen(detail_url%(code), timeout=30)print("request url:" + resp.geturl())rt_code = resp.getcode()if rt_code==200:content = resp.read()response = HtmlResponse(url=detail_url, body=content)sel = Selector(response=response)print (sel.xpath('//*[@id="comInfo1"]/tbody/tr[1]'))print (sel.xpath('//*[@id="comInfo1"]/tbody '))print (sel.xpath('//*[@id="comInfo1"]'))else:print("error return code:%d" % rt_code)return True
上述代碼對xpath路徑及其父級路徑的提取結(jié)果都進(jìn)行了打印 。該方法定義在類中,格式需注意增加一層縮進(jìn) 。
另外,在模塊頂部增加依賴模塊的加載 , 引入代碼如下:
from urllib import requestimport sslssl._create_default_https_context = ssl._create_unverified_contextfrom scrapy.selector import Selectorfrom scrapy.http import HtmlResponse
以上代碼說明如下:
1. from為從模塊中加載子模塊,http請求我們使用模塊的方法;
2.ssl和ssl. = ssl.是在https安全請求時,設(shè)置為做不認(rèn)證的模式 。不做此設(shè)置會導(dǎo)致https類型的請求會失敗 。
3. 為選擇器類 , 提供xpath、css的路徑提取方法;
4. 為的子類 , 用于下載http請求的返回信息;
為了測試函數(shù),我們在run方法中增加調(diào)用,參數(shù)賦值為:
(1) code參數(shù)局部賦值,使用樣例企業(yè)新華醫(yī)療()作為測試;
(2) 作為類的成員變量進(jìn)行賦值;
(3) 設(shè)置成true,以方便后續(xù)重跑測試 。
代碼編寫好后,如下圖:
第三步:運行測試XPath提取結(jié)果
使用快捷鍵Ctrl+F5運行后,結(jié)果如下:
根據(jù)運行結(jié)果可知,通過請求拿到的表格格式略有不同,表格里面沒有tbody標(biāo)簽公司的圖標(biāo)有什么用?,因此只有最頂級的xpath能取到元素 。
第四步:修改調(diào)試XPath提取結(jié)果

文章插圖

文章插圖
我們將xpath路徑換成//*[@id=””]/tr[1] , 并增加打印第一行的所有列的xpath為//*[@id=””]/tr[1]/td,以及表格的所有行后的xpath為//*[@id=””]/tr,如下圖:
保存后運行模塊,結(jié)果如下:
根據(jù)結(jié)果輸出,我們成功獲取到了表格中的行和列元素數(shù)據(jù) 。
第五步:編寫公司簡介表格數(shù)據(jù)的循環(huán)解析
編寫xpath循環(huán)解析表格行,并每兩列作為一個鍵值對,存儲在字典中,代碼如下:
tr_list_sel = sel.xpath('//*[@id="comInfo1"]/tr')for tr_sel in tr_list_sel:one_row = tr_sel.xpath('td//text()').extract()key = Noneval = ""for one_sel in one_row:if one_sel.endswith(':'):val = ""key = one_sel[:len(one_sel)-1]else:val = val + ("t" if val else "") + one_selif key:info_dict[key] = val.strip()print (info_dict)其中:
1) 先用//*[@id=””]/tr解析出每行的元素選擇器;
2) 設(shè)置xpath為td//text()來循環(huán)提取出每列中的文本;
3) 對多列文本的數(shù)組進(jìn)行循環(huán)處理,將':'結(jié)尾的作為鍵,隨后的列作為對應(yīng)的值,存儲在中;
4) 循環(huán)全部結(jié)束后,打印輸出解析結(jié)果字典 。
在函數(shù)中增加以上解析邏輯后 , 如下圖所示:
第六步:測試運行簡介表格解析結(jié)果
運行.py模塊,運行效果如下圖所示:
代碼成功解析出了上市公司的公司簡介 。
第七步:編寫將解析結(jié)果存儲到文件
增加文件存在判斷,代碼如下:
res_file = "%s/detail_%s.data"%(detail_dir, code)if not overwrite and os.path.isfile(res_file):print ("skip scrapy, result exist in:" + res_file)return False將該代碼邏輯放在函數(shù)的開頭,如下圖:
解析結(jié)果字典需要寫入文件,我們將寫文件邏輯放在函數(shù)中 , 代碼如下:
【五 Python抓取上市公司財務(wù)數(shù)據(jù):公司簡介和行業(yè)抓取】
def write_file(self, info_dict, res_file):if info_dict:try:fb = open(res_file, 'w')fb.write(json.dumps(info_dict)+'n')except IOError as err:print ('IO Error:', err)else:fb.close()由于用到了json模塊,我們需要在模塊頂部增加 json來加載,如下圖:
并在函數(shù)中,將解析結(jié)束后的打印字典換成寫文件,如下圖:
其中參數(shù)為解析結(jié)果字典,為將寫入的文件路徑 。最后,使用快捷鍵Ctrl+S保存更新后的模塊代碼 。
三、公司簡介抓取程序的運行
第一步:創(chuàng)建結(jié)果數(shù)據(jù)存儲的文件夾
打開項目文件夾,右鍵-新建-新建文件夾 , 如下圖:
新建的文件夾命名成 , 如下圖:
第二步:測試運行模塊
切換回.py的編輯窗口,使用快捷鍵ctrl+F5運行模塊,結(jié)果如下圖:
第三步:查看簡介數(shù)據(jù)抓取結(jié)果
打開文件夾,查看結(jié)果文件 , 如下圖:
運行結(jié)果成功保存到了.data數(shù)據(jù)文件中 。
四、所屬行業(yè)頁面數(shù)據(jù)抓取和解析
第一步:打開所屬行業(yè)頁面
打開公司所屬行業(yè)頁面,以新華醫(yī)療()為例,如下:
第二步:使用元素選擇器選擇所屬行業(yè)板塊的值
我們通過右鍵-點擊“檢查”(或快捷鍵F12) , 點擊左下角的元素的選擇器圖標(biāo),如下圖:
再將鼠標(biāo)移動到所屬行業(yè)板塊的值(本示例的值為“醫(yī)療器械”) , 并點擊選中,如下圖:
第三步:復(fù)制所屬行業(yè)板塊的值的xpath信息
選中標(biāo)簽,點擊右鍵-復(fù)制-復(fù)制XPath,如下圖:
得到表格該值的字段xpath信息為://*[@id=”con02-0″]/table[1]/tbody/tr[3]/td[1]
第四步:編寫代碼抓取并提取所屬行業(yè)板塊的值
在類中增加函數(shù),并編寫代碼如下:
def scrapy_industry(self, code, detail_dir, overwrite):res_file = "%s/industry_%s.data"%(detail_dir, code)if not overwrite and os.path.isfile(res_file):print ("skip scrapy, result exist in:" + res_file)return Falsedetail_url = "https://vip.stock.finance.sina.com.cn/corp/go.php/vCI_CorpOtherInfo/stockid/%s/menu_num/2.phtml"resp = request.urlopen(detail_url%(code))print("request url:" + resp.geturl())rt_code = resp.getcode()if rt_code==200:content = resp.read()response = HtmlResponse(url=detail_url, body=content)sel = Selector(response=response)one_sel = sel.xpath('//*[@id="con02-0"]/table[1]/tr[3]/td[1]/text()').extract_first()self.write_file({"industry" : one_sel}, res_file)else:print("error return code: %d" % rt_code)return True該方法實現(xiàn)中,將請求響應(yīng)的內(nèi)容直接使用剛剛獲取到的xpath信息,再拼接上/text()來獲取其元素下一級文本內(nèi)容 。解析結(jié)果直接以字典的形式寫入文件中 , 在前面已經(jīng)定義實現(xiàn)了 。相關(guān)依賴的模塊在前面步驟中已經(jīng)增加過加載代碼,就不用重復(fù)添加了 。代碼編寫完成后 , 效果如下圖:
在run方法中,增加方法的調(diào)用,并將設(shè)置為False,以避免重復(fù)抓取前面的公司簡介頁,并增加os模塊的加載,如下圖:
使用Ctrl+S快捷鍵保存所編寫的模塊代碼 。
第五步:所屬行業(yè)板塊抓取程序的運行
使用快捷鍵ctrl+F5運行.py模塊,結(jié)果如下圖:
第六步:查看所屬行業(yè)板塊抓取結(jié)果
打開文件夾,查看結(jié)果文件,如下圖:
運行結(jié)果成功保存到了.data數(shù)據(jù)文件中 。
五、結(jié)語
本文講解了如何對新浪財經(jīng)的上市公司簡介頁的數(shù)據(jù)結(jié)構(gòu)進(jìn)行分析,通過元素選擇器找到xpath信息,并通過編寫程序來實現(xiàn)數(shù)據(jù)的抓取和表格數(shù)據(jù)解析成鍵值對字典,最后將字典數(shù)據(jù)存儲到結(jié)果文件中 。最后使用同樣的流程對所屬行業(yè)頁面進(jìn)行了抓取、解析和存儲 。中間還遇到了瀏覽器和請求到的網(wǎng)頁數(shù)據(jù)不一致的坑,希望大家能及時發(fā)現(xiàn)這種坑 , 以程序響應(yīng)的數(shù)據(jù)為準(zhǔn),同時能掌握其調(diào)試和分析的思路 。
下一節(jié)將介紹“上市公司的財務(wù)摘要數(shù)據(jù)的抓取”,詳細(xì)拆解實現(xiàn)過程 , 以逐步深入的方式讓小白學(xué)者也能完全掌握抓取上市公司財務(wù)數(shù)據(jù)的編碼實操過程 。學(xué)到現(xiàn)在,你應(yīng)該對網(wǎng)頁數(shù)據(jù)的結(jié)構(gòu)和解析基本掌握了,后續(xù)將逐步側(cè)重加強數(shù)據(jù)處理和存儲分析方面的講解 。看到這里請支持下 , 對該主題感興趣的朋友可以下我的后續(xù)動態(tài)~
本文到此結(jié)束,希望對大家有所幫助 。
- 多干家務(wù)有五大好處
- ?五本甜寵文:女主寵男主,男主小公主,全程高甜!甜度5顆星
- 防踩雷!孩子討厭家長說的五句話,看看你中了幾句
- ?五位飾演過趙敏的女明星,誰才是最美趙敏?
- 和媽媽發(fā)生矛盾怎么辦?五點建議,緩解緊張的關(guān)系,讓你達(dá)成所愿
- 簡述三皇五帝之——軒轅黃帝簡介 ?黃帝簡介和歷史簡介
- 北京五道口附近美食 五道口附近美食
- ?女生玻璃心的表現(xiàn),因為玻璃心換了五次工作
- ?五十歲的女人,50歲的女人老了嗎
- 50歲學(xué)習(xí)python-量化交易第六天:程序化交易平臺
