Python爬蟲(chóng)Ajax系列——批量下載巨潮資訊網(wǎng)上市公司年報(bào)

公眾號(hào):Python for Finance

巨潮資訊網(wǎng)是中國(guó)證監(jiān)會(huì)指定的上市公司信息披露網(wǎng)站倘核,平臺(tái)提供上市公司公告、公司資訊即彪、公司互動(dòng)紧唱、股東大會(huì)網(wǎng)絡(luò)投票等內(nèi)容功能,一站式服務(wù)資本市場(chǎng)投資者。在本文隶校,我將展示如何批量下載上市公司年報(bào)漏益,如果大家想下載其他類型報(bào)告也是一樣的方法。

巨潮資訊網(wǎng)滬深公告網(wǎng)址:

http://www.cninfo.com.cn/new/commonUrl/pageOfSearch?url=disclosure/list/search

我們?cè)谟曳降摹肮嫠俨椤钡摹胺诸悺敝泄催x“年報(bào)”深胳,即可篩選出上市公司年報(bào)绰疤。那我們的目標(biāo)是下載這些pdf,如何實(shí)現(xiàn)呢稠屠?

image

基本思路:

1峦睡、獲取巨潮資訊網(wǎng)上市公司年報(bào)pdf的網(wǎng)址及公司公告標(biāo)題、公司代碼权埠、公司名稱等信息

2榨了、通過(guò)訪問(wèn)pdf地址進(jìn)行下載,按照公司公告標(biāo)題攘蔽、公司代碼龙屉、公司名稱進(jìn)行命名

一、觀察網(wǎng)頁(yè)

1.判斷網(wǎng)頁(yè)是靜態(tài)網(wǎng)頁(yè)還是動(dòng)態(tài)網(wǎng)頁(yè)

(1)我們翻頁(yè)后,發(fā)現(xiàn)網(wǎng)址欄的網(wǎng)址沒(méi)有發(fā)生變化转捕,說(shuō)明這是ajax動(dòng)態(tài)網(wǎng)頁(yè)作岖。

image

(2)我們右鍵“查看源代碼”,搜索第一個(gè)公司名稱“紫晶存儲(chǔ)”五芝,發(fā)現(xiàn)公司名字不在源代碼里痘儡,說(shuō)明我們想要的信息沒(méi)有存儲(chǔ)在我們當(dāng)前打開(kāi)的網(wǎng)頁(yè)上,所以我們需要找到我們需要的數(shù)據(jù)存在哪個(gè)網(wǎng)頁(yè)枢步。

image

2.找到數(shù)據(jù)的真實(shí)的網(wǎng)頁(yè)地址

(1)谷歌瀏覽器右鍵“檢查”沉删,點(diǎn)擊“Network”,在出現(xiàn)的界面中選擇“Fetch/XHR”按鈕醉途,刷新頁(yè)面矾瑰。

(2)點(diǎn)擊名為“query”的鏈接

(3)點(diǎn)擊“Preview”或者“Response”,可以發(fā)現(xiàn)我們需要的數(shù)據(jù)在這里隘擎。

image

二殴穴、請(qǐng)求數(shù)據(jù)

requests-post請(qǐng)求

我們查看“Headers”發(fā)現(xiàn)請(qǐng)求方法為post請(qǐng)求,我們拉到最下面货葬,找到“Form Data”采幌,即為post請(qǐng)求的數(shù)據(jù)參數(shù)。

image

我們請(qǐng)求數(shù)據(jù)的時(shí)候宝惰,有時(shí)候需要攜帶請(qǐng)求頭植榕,請(qǐng)求頭信息如下:

image

代碼如下:

#定義下載單頁(yè)年報(bào)pdf的函數(shù)
def get_and_download_pdf_flie(pageNum):
    url='http://www.cninfo.com.cn/new/hisAnnouncement/query'
    pageNum=int(pageNum)
    data={'pageNum':pageNum,
        'pageSize':30,
        'column':'szse',
        'tabName':'fulltext',
        'plate':'', 
        'stock':'',
        'searchkey':'',
        'secid':'',
        'category':'category_ndbg_szsh',
        'trade':'', 
        'seDate':'2021-03-26~2021-09-26',
        'sortName':'',
        'sortType':'', 
        'isHLtitle':'true'}
    headers={'Accept':'*/*',
        'Accept-Encoding':'gzip, deflate',
        'Accept-Language':'zh-CN,zh;q=0.9',
        'Connection':'keep-alive',
        'Content-Length':'181',
        'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',
        'Host':'www.cninfo.com.cn',
        'Origin':'http://www.cninfo.com.cn',
        'Referer':'http://www.cninfo.com.cn/new/commonUrl/pageOfSearch?url=disclosure/list/search',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',
        'X-Requested-With':'XMLHttpRequest'}
     r=requests.post(url,data=data,headers=headers)

三、存儲(chǔ)數(shù)據(jù)

json數(shù)據(jù)解析

由于網(wǎng)頁(yè)返回的是json格式數(shù)據(jù)尼夺,獲取我們需要的公司名稱尊残、公司代碼、公司公告淤堵,我們通過(guò)字典訪問(wèn)即可寝衫。其中公司公告pdf的網(wǎng)頁(yè)鏈接如何拿到?我們點(diǎn)擊第一條公司年報(bào)觀察拐邪,發(fā)現(xiàn)其網(wǎng)址后綴存儲(chǔ)在adjunctUrl里慰毅,我們可以提取此后綴,再將前綴加上扎阶,就可以拿到年報(bào)pdf的完整鏈接汹胃。

拿到pdf鏈接后,我們?nèi)绾蜗螺dpdf呢东臀,需要用response.content來(lái)寫入文件信息着饥。在此我們補(bǔ)充一個(gè)知識(shí)點(diǎn):

response.text 與 response.content的區(qū)別

response.text 與 response.content 都是來(lái)獲取response中的數(shù)據(jù)信息,那么response.text 和 response.content 到底有哪些差別惰赋?

(1)返回的數(shù)據(jù)類型

response.text 返回的是一個(gè) unicode 型的文本數(shù)據(jù)宰掉;

response.content 返回的是 bytes 型的二進(jìn)制數(shù)據(jù);

也就是說(shuō)如果想取文本數(shù)據(jù)可以通過(guò)response.text;如果想取文件等轨奄,則可以通過(guò) response.content孟害。

(2)數(shù)據(jù)編碼

response.content 返回的是二進(jìn)制響應(yīng)內(nèi)容,可通過(guò)response.content.decode()進(jìn)行解碼挪拟。

response.text 則是默認(rèn)”iso-8859-1”編碼挨务,服務(wù)器不指定的話是根據(jù)網(wǎng)頁(yè)的響應(yīng)來(lái)猜測(cè)編碼。

代碼如下:

result=r.json()['announcements']#獲取單頁(yè)年報(bào)的數(shù)據(jù)舞丛,數(shù)據(jù)格式為json耘子。獲取json中的年報(bào)信息。
#2.對(duì)數(shù)據(jù)信息進(jìn)行提取
    for i in result:
        if re.search('摘要',i['announcementTitle']):#避免下載一些年報(bào)摘要等不需要的文件
            pass
        else:
            title=i['announcementTitle']
            secName=i['secName']
            secName=secName.replace('*','')#下載前要將文件名中帶*號(hào)的去掉球切,因?yàn)槲募?guī)則不能帶*號(hào),否則程序會(huì)中斷
            secCode=i['secCode']
            adjunctUrl=i['adjunctUrl']
            down_url='http://static.cninfo.com.cn/'+adjunctUrl
            filename=f'{secCode}{secName}{title}.pdf'
            filepath=saving_path+'\\'+filename
            r=requests.get(down_url)
            with open(filepath,'wb') as f:
                f.write(r.content)
            print(f'{secCode}{secName}{title}下載完畢')#設(shè)置進(jìn)度條

四绒障、通過(guò)循環(huán)吨凑,批量下載公司年報(bào)

尋找翻頁(yè)規(guī)律。

我們分別點(diǎn)擊第1頁(yè)户辱、第2頁(yè)鸵钝、第3頁(yè),發(fā)現(xiàn)不同頁(yè)碼的動(dòng)態(tài)網(wǎng)頁(yè)一致庐镐,只是post參數(shù)不一致恩商,第1頁(yè)的“pageNum”是1,第2頁(yè)的“pageNum”是2必逆,第3頁(yè)的“pageNum”是3怠堪,以此類推。

image
image

因此我們嵌套循環(huán)即可名眉,代碼如下:

for pageNum in range(1,3):#為演示粟矿,下載1-2頁(yè)的年報(bào)
    get_and_download_pdf_flie(pageNum) #執(zhí)行以上定義的下載單頁(yè)年報(bào)pdf的函數(shù)

全套代碼如下:


import requests
import re
#定義爬取函數(shù)
#1、對(duì)單個(gè)頁(yè)面進(jìn)行請(qǐng)求损拢,返回?cái)?shù)據(jù)信息——以第一頁(yè)為例
saving_path='C:\\Users\\chenwei\\Desktop\\巨潮資訊年報(bào)'#設(shè)置存儲(chǔ)年報(bào)的文件夾陌粹,把文件夾改成你自己的
import requests
def get_and_download_pdf_flie(pageNum):
    url='http://www.cninfo.com.cn/new/hisAnnouncement/query'
    pageNum=int(pageNum)
    data={'pageNum':pageNum,
        'pageSize':30,
        'column':'szse',
        'tabName':'fulltext',
        'plate':'', 
        'stock':'',
        'searchkey':'',
        'secid':'',
        'category':'category_ndbg_szsh',
        'trade':'', 
        'seDate':'2021-03-26~2021-09-26',
        'sortName':'',
        'sortType':'', 
        'isHLtitle':'true'}
    headers={'Accept':'*/*',
        'Accept-Encoding':'gzip, deflate',
        'Accept-Language':'zh-CN,zh;q=0.9',
        'Connection':'keep-alive',
        'Content-Length':'181',
        'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',
        'Host':'www.cninfo.com.cn',
        'Origin':'http://www.cninfo.com.cn',
        'Referer':'http://www.cninfo.com.cn/new/commonUrl/pageOfSearch?url=disclosure/list/search',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',
        'X-Requested-With':'XMLHttpRequest'}
    r=requests.post(url,data=data,headers=headers)
    result=r.json()['announcements']#獲取單頁(yè)年報(bào)的數(shù)據(jù),數(shù)據(jù)格式為json福压。獲取json中的年報(bào)信息掏秩。
#2.對(duì)數(shù)據(jù)信息進(jìn)行提取
    for i in result:
        if re.search('摘要',i['announcementTitle']):#避免下載一些年報(bào)摘要等不需要的文件
            pass
        else:
            title=i['announcementTitle']
            secName=i['secName']
            secName=secName.replace('*','')#下載前要將文件名中帶*號(hào)的去掉,因?yàn)槲募?guī)則不能帶*號(hào)荆姆,否則程序會(huì)中斷
            secCode=i['secCode']
            adjunctUrl=i['adjunctUrl']
            down_url='http://static.cninfo.com.cn/'+adjunctUrl
            filename=f'{secCode}{secName}{title}.pdf'
            filepath=saving_path+'\\'+filename
            r=requests.get(down_url)
            with open(filepath,'wb') as f:
                f.write(r.content)
            print(f'{secCode}{secName}{title}下載完畢')#設(shè)置進(jìn)度條
#3.設(shè)置循環(huán)蒙幻,下載多頁(yè)的年報(bào)
for pageNum in range(1,3):#為演示,下載1-2頁(yè)的年報(bào)
    get_and_download_pdf_flie(pageNum)

代碼效果:

進(jìn)度條效果(可不設(shè)置)

image

文件下載效果:

image

以上就是今天的分享胞枕,每天進(jìn)步一點(diǎn)點(diǎn)杆煞。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。
  • 序言:七十年代末决乎,一起剝皮案震驚了整個(gè)濱河市队询,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌构诚,老刑警劉巖蚌斩,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異范嘱,居然都是意外死亡送膳,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門丑蛤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)叠聋,“玉大人,你說(shuō)我怎么就攤上這事受裹÷挡梗” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵棉饶,是天一觀的道長(zhǎng)厦章。 經(jīng)常有香客問(wèn)我,道長(zhǎng)照藻,這世上最難降的妖魔是什么袜啃? 我笑而不...
    開(kāi)封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮幸缕,結(jié)果婚禮上群发,老公的妹妹穿的比我還像新娘。我一直安慰自己冀值,他們只是感情好也物,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著列疗,像睡著了一般滑蚯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抵栈,一...
    開(kāi)封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天告材,我揣著相機(jī)與錄音,去河邊找鬼古劲。 笑死斥赋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的产艾。 我是一名探鬼主播疤剑,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼滑绒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了隘膘?” 一聲冷哼從身側(cè)響起疑故,我...
    開(kāi)封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弯菊,沒(méi)想到半個(gè)月后纵势,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡管钳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年钦铁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片才漆。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡牛曹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出醇滥,到底是詐尸還是另有隱情躏仇,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布腺办,位于F島的核電站,受9級(jí)特大地震影響糟描,放射性物質(zhì)發(fā)生泄漏怀喉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一船响、第九天 我趴在偏房一處隱蔽的房頂上張望躬拢。 院中可真熱鬧,春花似錦见间、人聲如沸聊闯。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)菱蔬。三九已至,卻和暖如春史侣,著一層夾襖步出監(jiān)牢的瞬間拴泌,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工惊橱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚪腐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓税朴,卻偏偏與公主長(zhǎng)得像回季,于是被迫代替她去往敵國(guó)和親家制。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容