手把手教你爬取美國(guó)疫情實(shí)時(shí)數(shù)據(jù)

? ???作者:劉早起早起
? ? ?來(lái)源:早起python
大家好,最近一直有讀者在后臺(tái)留言說(shuō)早起能不能寫一下怎么獲取國(guó)外的疫情數(shù)據(jù)、美國(guó)疫情數(shù)據(jù)怎么爬之類的。為了滿足各位,今天就說(shuō)一下如何爬取美國(guó)疫情數(shù)據(jù)。

廢話不多說(shuō),直接開始,只需一臺(tái)電腦,按照下面的順序一步一步執(zhí)行,爬不下來(lái)數(shù)據(jù)你打我,文末不提供源碼,源碼一字不少全在文中。首先感謝讀者@荷月十九提供的目標(biāo)網(wǎng)站(不然我肯定直接找個(gè)API
)
https://coronavirus.1point3acres.com/?code=001XKpTM0fAHk92cYwUM0iSrTM0XKpTF打開這個(gè)網(wǎng)站,會(huì)吧

長(zhǎng)這樣?但是我們需要拿的數(shù)據(jù)是?

現(xiàn)在目標(biāo)很明確,把上面這一堆數(shù)據(jù)取下來(lái),下面有請(qǐng)Python出場(chǎng)

打開Notebook,導(dǎo)入以下包
import?requests
import?json
import?re
import?pandas as?pd
from?bs4 import?BeautifulSoup如果有人留言怎么打開,怎么導(dǎo)入我會(huì)直接當(dāng)場(chǎng)去世,接著設(shè)置下URL和headers,不用F12,URL就是上面的URL
url?= 'https://coronavirus.1point3acres.com/?code=001XKpTM0fAHk92cYwUM0iSrTM0XKpTF'
headers?= {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'}這兩句復(fù)制粘貼執(zhí)行謝謝,我們繼續(xù),下一步直接請(qǐng)求數(shù)據(jù)
res?= requests.get(url,headers=headers)這一句就是使用Requests使用get方法向服務(wù)器請(qǐng)求數(shù)據(jù),我們來(lái)看一下返回的值

哦豁,報(bào)錯(cuò)了,從報(bào)錯(cuò)代碼來(lái)看說(shuō)明返回的并不能解析為json數(shù)據(jù),沒事不慌,bs4登場(chǎng),我們用美麗的湯試試
soup = BeautifulSoup(res.text)
soup
搞定?,接下來(lái)干嘛?我們想要的數(shù)據(jù)都在這湯(soup)里了,取出來(lái)不就完事了,這時(shí)候F12就不得不登場(chǎng)了,回到瀏覽器剛剛的頁(yè)面按下F12

為了再照顧一下不熟悉的讀者,我已經(jīng)標(biāo)注了你F12之后要干嘛,先點(diǎn)擊位置1處的小箭頭,它就變成了藍(lán)色,再點(diǎn)擊頁(yè)面中美國(guó)確診的總?cè)藬?shù)的數(shù)字,你戳它一下,右邊的頁(yè)面就會(huì)自動(dòng)定位到前端頁(yè)面中該數(shù)字的位置,從標(biāo)注3中可以看到這個(gè)數(shù)字被存儲(chǔ)在一個(gè)名為strong的標(biāo)簽中,并且class屬性為jsx-1831266853,OK請(qǐng)執(zhí)行下面代碼
t = soup.find_all('strong', class_="jsx-1831266853")
這段代碼具體是什么意思呢?就是從soup中找標(biāo)簽為'strong',class為"jsx-1831266853"的內(nèi)容?

返回了一個(gè)list,我們要的數(shù)據(jù)都在里面,拿總確診人數(shù)來(lái)說(shuō),怎么取出來(lái)?
total_confirmed?= int(t[0].text)上面這行代碼不難看懂吧,首先取出t的第0個(gè)位置元素,再用.text函數(shù)取出中間的數(shù)字,再將這個(gè)數(shù)字轉(zhuǎn)換為int,這不就把美國(guó)確診總?cè)藬?shù)取出來(lái)了嗎。不過(guò)話說(shuō)這有啥用啊,自己百度也能得到啊,別急,我們?cè)侔迅鱾€(gè)州的數(shù)據(jù)拿下

讓我們故技重施?,回到瀏覽器頁(yè)面中,F(xiàn)12定位到各個(gè)州的位置,戳一下看看數(shù)據(jù)存儲(chǔ)在哪些標(biāo)簽中,看不懂的話回去看上一張圖,結(jié)果我們發(fā)現(xiàn)好多div啊,點(diǎn)開一個(gè)就是一行數(shù)據(jù),再觀察觀察發(fā)現(xiàn)每一行的數(shù)據(jù)都被一個(gè)屬性是class="jsx-742282485 stat row"的標(biāo)簽包住?

下面就好辦了,使用soup故技重施?
s?= soup.find_all('div', class_="jsx-742282485 stat row")不難理解吧,將所有含屬性是class="jsx-742282485 stat row"的div標(biāo)簽取出來(lái),來(lái)看下結(jié)果

有點(diǎn)亂,但是不用慌我們通過(guò)len(s)可以發(fā)現(xiàn)返回的list長(zhǎng)度為57,而上面剛好有57行(不用數(shù)了,我已經(jīng)數(shù)過(guò)了),所以這57行的數(shù)據(jù)都在里面了,不用慌,一行一行取唄。
我們先嘗試取出第一行的數(shù)據(jù),看看套路是什么,搞定了寫一個(gè)循環(huán)不就完事了。所以再回去瀏覽器看看第一行的數(shù)據(jù)怎么存儲(chǔ)的?

可以看到,我們剛剛?cè)〕隽?7個(gè)div標(biāo)簽,一個(gè)div標(biāo)簽里面有5個(gè)span,而前4個(gè)span中分別存儲(chǔ)了州名、確診、死亡、致死率,所以我們的思路就對(duì)每一個(gè)div取出這4個(gè)span中的內(nèi)容,先取第一行?
name = s[0].find_all('span')[0].text
k = s[0].find_all('span')[1].text
confirmed = (int(re.findall(r"\d+\.?\d*",k)[0])*1000?+ int(re.findall(r"\d+\.?\d*",k)[1])) if?','?in?k else?int(k)
deaths = int(s[0].find_all('span')[2].text)
rate = s[0].find_all('span')[3].text等等,4個(gè)數(shù)據(jù)為什么要5行,有沒有注意到,確診數(shù)據(jù)由于比較大,比如紐約確診人數(shù)是46093,但是網(wǎng)頁(yè)里面是46,093,多了一個(gè),這個(gè),會(huì)導(dǎo)致我們之后可視化不方便。所以使用兩行代碼來(lái)解決這個(gè)問(wèn)題?
k = s[0].find_all('span')[1].text
confirmed = (int(re.findall(r"\d+\.?\d*",k)[0])*1000?+ int(re.findall(r"\d+\.?\d*",k)[1])) if?','?in?k else?int(k)我稍微解釋下,第一行把數(shù)字取出來(lái)是這樣46,093,第二行先用正則表達(dá)式取出數(shù)字再拼接成正常的格式,如果看不懂也沒關(guān)系,這不是本期重點(diǎn),總之這兩行就是把數(shù)字整理下
好了,到這里基本就算結(jié)束了,接下來(lái)我們創(chuàng)建一個(gè)空dataframe
df?= pd.DataFrame(columns= ['Location','Confirmed','Deaths','Fatality rate'])
最后寫一個(gè)循環(huán)重復(fù)執(zhí)行剛剛的操作就搞定
for?i in?range(len(s)):
????name = s[i].find_all('span')[0].text
????k = s[i].find_all('span')[1].text
????confirmed = (int(re.findall(r"\d+\.?\d*",k)[0])*1000?+ int(re.findall(r"\d+\.?\d*",k)[1])) if?','?in?k else?int(k)
????deaths = int(s[i].find_all('span')[2].text)
????rate = s[i].find_all('span')[3].text
????
????data = [name,confirmed,deaths,rate]
????df.loc[i] = data上面這個(gè)也不難看懂把,對(duì)每一行取出數(shù)據(jù)并存到dataframe中,如果看不懂那你一定沒做過(guò)Pandas120題系列,我們來(lái)看下最終取到的數(shù)據(jù)

登登登登,美國(guó)各個(gè)州的疫情數(shù)據(jù)就成功取下來(lái)了,最后可以使用df.to_excel('filename.xlsx')存儲(chǔ)到本地。

以上就是爬取美國(guó)疫情數(shù)據(jù)的全部過(guò)程,也不難吧!如果需要這個(gè)頁(yè)面中更多的數(shù)據(jù)完全可以重復(fù)上述步驟,并且這個(gè)網(wǎng)站實(shí)時(shí)更新數(shù)據(jù),如果定時(shí)執(zhí)行就能獲得時(shí)間序列數(shù)據(jù),這些就不再多說(shuō)了。拿到數(shù)據(jù)之后就能做一些分析可視化?

◆?◆?◆ ?◆?◆
長(zhǎng)按二維碼關(guān)注我們
數(shù)據(jù)森麟公眾號(hào)的交流群已經(jīng)建立,許多小伙伴已經(jīng)加入其中,感謝大家的支持。大家可以在群里交流關(guān)于數(shù)據(jù)分析&數(shù)據(jù)挖掘的相關(guān)內(nèi)容,還沒有加入的小伙伴可以掃描下方管理員二維碼,進(jìn)群前一定要關(guān)注公眾號(hào)奧,關(guān)注后讓管理員幫忙拉進(jìn)群,期待大家的加入。
管理員二維碼:
