亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

用Python和Pandas以及爬蟲技術(shù)統(tǒng)計(jì)歷史天氣

系統(tǒng) 1519 0

背景

最近在計(jì)劃明年從北京rebase到深圳去,所以最近在看深圳的各個(gè)方面。去年在深圳呆過一段時(shí)間,印象最深的是,深圳總是突然就下雨,還下好大的雨。對(duì)于我這種從小在南方長(zhǎng)大但是后面又在北京呆了2年多的人來說,熟悉而又無奈。

今天早上本來想隨便瀏覽瀏覽一個(gè)天氣網(wǎng)站,看看深圳的歷史天氣如何的,但是,一不小心發(fā)現(xiàn),這家網(wǎng)站竟然直接能用API來抓數(shù)據(jù),這~~~還不抓一波,省的自己一個(gè)月一個(gè)月地看。

先上最后的效果圖:

所有的code都在我的GitHub上:boydfd

下面從幾個(gè)方面講一講我是怎么做的:

  1. 爬取數(shù)據(jù)
  2. 用pandas顯示數(shù)據(jù)
  3. 功能擴(kuò)展
  4. 遇到的坑

爬取數(shù)據(jù)

先是在http://tianqi.2345.com上面瀏覽了一下深圳的6月份天氣。然后發(fā)現(xiàn)點(diǎn)切換月份的時(shí)候,網(wǎng)址沒有變,那應(yīng)該有請(qǐng)求API吧,看看這個(gè)API長(zhǎng)啥樣吧。

發(fā)現(xiàn)返回值就是純JS代碼,那就解析一下吧:

  1. 去掉 var = 和最后的 ;
  2. 用到 demjson 解析成Python的 List[Dict] 對(duì)象。
  3. 轉(zhuǎn)成pandas的 DataFrame
  4. 加上我們的date字段
          
            date = '201905'
weather = requests.get('http://tianqi.2345.com/t/wea_history/js/{date}/59493_{date}.js'.format(date=date)).text.split('=')[1][:-1]
weather = demjson.decode(weather)['tqInfo']
df = pd.DataFrame(weather)
df['month'] = date
          
        

結(jié)果是這樣的:

用Pandas顯示數(shù)據(jù)

太多雨天

我們可以看到,有各種雷陣雨啊,陰轉(zhuǎn)雨啊,雨轉(zhuǎn)陰之類的,這樣看到的天氣太雜了,所以我就統(tǒng)一了一下,按照雨、多云、陰、晴的順序來排序,先出出現(xiàn)的關(guān)鍵詞優(yōu)先級(jí)更高。

寫一個(gè)函數(shù)來處理之:

          
            rain = '雨'
rain_index = ' ' + rain
cloudy = '多云'
cloudy_index = ' ' + cloudy
overcast = '陰'
overcast_index = ' ' + overcast
sunny = '晴'
sunny_index = ' ' + sunny
def weath_category(row):
    tianqi = row['tianqi']
    if tianqi.find(rain) != -1:
        return rain_index
    if tianqi.find(overcast) != -1:
        return overcast_index
    if tianqi.find(cloudy) != -1:
        return cloudy_index
    return sunny_index
          
        

多個(gè)月的數(shù)據(jù)

一個(gè)月的數(shù)據(jù)不夠啊,我們想要很多個(gè)月的數(shù)據(jù),那就寫得函數(shù)來生成月份吧。

          
            def date_generate(start, end):
    start = datetime.strptime(start, '%Y%m')
    end = datetime.strptime(end, '%Y%m')
    while True:
        next_start = start + relativedelta(months=1)
        yield start.strftime('%Y%m')
        if next_start > end:
            break
        start = next_start
          
        

畫圖

分好類,爬了多個(gè)月份的數(shù)據(jù),就剩最終的畫圖部分了。使用Pandas提供給我們的函數(shù),可以很容易就畫出圖來。

          
            def plot_weather(start, end):
    df = read_weather(start, end).dropna().reset_index()
    df['weather'] = df.apply(weath_category, axis=1)
    
    from pylab import rcParams
    rcParams['figure.figsize'] = 40, 10
    weather_df = df.groupby(['month', 'weather']).aqi.count().unstack().reset_index()
    weather_df.plot.bar(x='month', y=[rain_index, overcast_index, cloudy_index, sunny_index])
          
        

功能擴(kuò)展

現(xiàn)在只能收集到一個(gè)月的數(shù)據(jù),想收集多個(gè)月的數(shù)據(jù),還都自己去頁(yè)面上找城市代表的code是啥,太低效了。

這個(gè)網(wǎng)站這么容易爬,那就再試試能不能找到調(diào)用code的API。

啊哦,一不小心找到了所有的code,哈哈哈。

那就在JS里面提取一下。

  1. 先把所有的JS代碼都復(fù)制到瀏覽器的console里, 結(jié)果長(zhǎng)這樣:

  1. 將其轉(zhuǎn)換成字符串。
          
            provqx.flatMap(a => a).join('|')
          
        
  1. 在Python里處理它。
          
            def line_to_city_code(line):
    return line.split(' ')[1].split('-')

def get_city_to_code():
    city_code_list = list(map(line_to_city_code, city_code.split('|')))
    return {city_code[0]: city_code[1] for city_code in city_code_list if len(city_code) == 2}
          
        

這樣我們就拿到所有的code了,只需要輸入城市,開始時(shí)間,結(jié)束時(shí)間,一張漂亮的圖就出來了,我還寫了個(gè)類稍微封裝了一下,只需要這樣就能使用了:

          
            Weather('深圳').plot_weather('201701', '201906')
          
        

遇到的坑

以前在電腦里面處理過一次,就是matplotlib畫圖中文亂碼的事情,這次換了新電腦又碰到了。所以又搞了一次,

大概的步驟可以參考https://www.jianshu.com/p/8ed59ac76c06

我為了以防下次再經(jīng)歷一次,就寫了個(gè)腳本自動(dòng)處理這件事,目前只支持macOS和Python3。
腳本也在我的GitHub:bash,

直接執(zhí)行下面的bash腳本就可以解決這個(gè)問題:

          
            curl -o- https://raw.githubusercontent.com/boydfd/one_step_solve/master/matplotlib_chinese.sh | bash
          
        

更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 日韩看片网站 | 天堂成人精品视频在线观 | 天天碰免费视频 | 男人懂的网站 | 青青青爽国产在线视频 | 极品福利 | 中文字幕亚洲无线码在线一区 | 国产一级做a爱免费视频 | 精品国产视频在线观看 | 国产成人久久综合二区 | 色偷偷亚洲女人天堂观看欧 | 亚洲国产精品久久久久婷婷老年 | 亚州精品一区二区三区 | s8国产成人精品视频 | 欧美人成在线 | www四虎影视 | 免费a级特黄国产大片 | 天天操天天曰 | 亚洲伊人久久大香线蕉啊 | 黄色在线免费观看网站 | 久久久www免费看片 久久久不卡 | 国产精品久久久久毛片 | 99热在线观看 | 91福利精品老师国产自产在线 | 欧美在线精品一区二区三区 | a集毛片| 久久久久久久免费 | 亚洲v在线| 国产99在线 | 天天插天天干天天射 | 国产精品美女久久久久 | 开心激情四房 | 亚洲欧美色综合一区二区在线 | 免费国内精品久久久久影院 | 日韩欧美毛片 | 久久免费视频在线 | a视频在线| 久久久久9 | 国产亚洲精品久久 | 中文字幕一区二区区免 | 免费精品国产福利片 |