python把excel填充到网页_Python获取某网页数据并写入excel
首先請(qǐng)大家諒解,尤其是消金和財(cái)務(wù)的同仁,作為服務(wù)臺(tái)的工作很細(xì)很碎,你們的問題我正在處理,很快就會(huì)上線。
在年前放假的前兩天,同業(yè)的征征叫住了筆者,指著某票據(jù)交易所的界面問道,這上面的數(shù)據(jù)能不能復(fù)制下來。
筆者看了一下這個(gè)破界面,心里暗道這個(gè)不直接可以選中復(fù)制,然后粘貼到excel里不就OK,但畢竟是同業(yè)部提出來的問題,肯定沒那么簡(jiǎn)單,所以征征指出了一個(gè)嚴(yán)肅的問題:
這個(gè)網(wǎng)頁(yè)沒有批量導(dǎo)出的功能,也就是說如果他要看一個(gè)月的利率或者收益率,需要像個(gè)傻子一樣依次點(diǎn)擊日期,再?gòu)?fù)制粘貼到表里,2021年第一季度都快過了一半了,怎么還會(huì)有這么浪費(fèi)人力的系統(tǒng)?是可忍,孰不可忍?!
于是筆者研究了一下這個(gè)網(wǎng)站,打算寫一個(gè)爬蟲,替同業(yè)部節(jié)省一點(diǎn)人力資源,不要把寶貴的時(shí)間浪費(fèi)在這種低端工作中。
所謂的爬蟲說到底就是哲學(xué)的三個(gè)終極問題:我是誰?我從哪來?我要去哪?錯(cuò)了,是數(shù)據(jù)結(jié)構(gòu)是什么樣的?數(shù)據(jù)從哪里獲取?數(shù)據(jù)最后要呈現(xiàn)到什么狀態(tài)?
首先看數(shù)據(jù)結(jié)構(gòu):從圖上看,數(shù)據(jù)非常簡(jiǎn)單,不同的日期、期限有著不同的利率和收益率,而且只有工作日有數(shù)據(jù),節(jié)假日與周末沒有數(shù)據(jù)。
再看數(shù)據(jù)如何獲取?
這個(gè)網(wǎng)頁(yè)是個(gè)明顯的動(dòng)態(tài)網(wǎng)頁(yè),而且有反爬蟲機(jī)制,使用最簡(jiǎn)單的urllib庫(kù)直接就被503拒絕掉,此時(shí)有兩種方案:方案A,使用selenium庫(kù),模擬點(diǎn)擊日期,然后復(fù)制數(shù)據(jù),最后導(dǎo)出。但是這個(gè)方法有很大的缺陷,首先是要在電腦上安裝高版本的谷歌瀏覽器(這個(gè)不難)和對(duì)應(yīng)的webdriver(這個(gè)就有點(diǎn)麻煩了),其次點(diǎn)擊時(shí)會(huì)調(diào)用一個(gè)谷歌瀏覽器進(jìn)程,眾所周知谷歌瀏覽器進(jìn)程是出了名的吃內(nèi)存,一旦瀏覽器卡住(同業(yè)的老爺機(jī)是必然會(huì)被卡住的)就前功盡棄,最重要的是這種模擬點(diǎn)擊的方式為了繞過反爬蟲機(jī)制每次操作不能太快,所以效率低下。
只能使用方案B:使用requests和fake_useragent庫(kù)偽造成正常用戶來獲取信息。
說起來簡(jiǎn)單,干起來也不復(fù)雜,只需要導(dǎo)入兩個(gè)庫(kù)即可:
然后使用fake_useragent偽造一個(gè)正常的head:
然后重點(diǎn)來了,開始分析這個(gè)網(wǎng)頁(yè),看是如何進(jìn)行交互的:
打開谷歌瀏覽器,打開開發(fā)者工具,刷新網(wǎng)頁(yè),隨便查詢幾個(gè)日期,在Network中的XHR仔細(xì)觀察,發(fā)現(xiàn)了端倪:雖然這是個(gè)動(dòng)態(tài)網(wǎng)頁(yè)(我猜用的Ajax),但是是用的POST請(qǐng)求數(shù)據(jù),然后服務(wù)器返回了一個(gè)JSON值。
返回的值如下:
這正是我們需要的。
OK,需求分析完畢,正式開始整代碼,首先要獲取開始日期和結(jié)束日期,為了避免無效請(qǐng)求,要排除掉周末,所以做了如下操作:
用戶輸入開始和結(jié)束日期,然后生成每一天,存到一個(gè)列表中,再依次讀取這個(gè)列表中的日期,拼接到偽造的POST請(qǐng)求中。
說起來簡(jiǎn)單,做起來就有點(diǎn)麻煩,關(guān)鍵在于Python中各種數(shù)據(jù)類型的轉(zhuǎn)換非常復(fù)雜,一點(diǎn)也不像Java嚴(yán)謹(jǐn)(php萬歲)。
首先是獲取開始和結(jié)束日期,然后生成每一天,把每一天添加進(jìn)循環(huán)中(之所以這么干是因?yàn)镻ython的循環(huán)看起來簡(jiǎn)單,用起來復(fù)雜,嵌套起來會(huì)很可怕,所以干脆拆開循環(huán))
然后使用datetime判斷是否為工作日,如果是工作日,就繼續(xù):
因?yàn)橛脩糨斎氲氖莥yyymmdd格式(20210210),但是post請(qǐng)求時(shí)yyyy-mm-dd格式,所以需要進(jìn)行格式轉(zhuǎn)換,先轉(zhuǎn)換成字符串,在提取前四位、中二位、后二位,用橫杠連接:
然后把拼接完畢的日期寫入payload中,配合偽造的head數(shù)據(jù)向服務(wù)器請(qǐng)求數(shù)據(jù):
然后使用 BeautifulSoup和lxml整理數(shù)據(jù),再使用看起來很復(fù)雜、寫起來很復(fù)雜但熟悉了以后很簡(jiǎn)單的正則表達(dá)式處理數(shù)據(jù):
為了防止太過分,所以加點(diǎn)間隔時(shí)間,避免引起對(duì)方的警覺:
最后把獲取的數(shù)據(jù)存到dataframe,寫入到excel中,搞定!
最后,一個(gè)爬蟲寫了70多行也是醉了。
總結(jié)
以上是生活随笔為你收集整理的python把excel填充到网页_Python获取某网页数据并写入excel的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Kotlin——初级篇(二):变量、常量
- 下一篇: 需要换个环境