iT邦幫忙

1

PYTHON 想寫個天氣的爬蟲 請問資料要去哪邊撈 台灣 世界的都可以給

PYTHON 想寫個天氣的爬蟲 請問資料要去哪邊撈

1 個回答

13
japhenchen
iT邦大師 1 級 ‧ 2021-03-30 15:47:26
最佳解答
看更多先前的回應...收起先前的回應...
熊大叔 iT邦新手 5 級 ‧ 2021-03-30 16:00:09 檢舉

感謝大神
收下學習了

雷伊 iT邦高手 1 級 ‧ 2021-03-30 16:25:16 檢舉

前輩真的好強

有點借花獻佛的感覺,之前有幫解一個folium的題目順便學到如何用google map繪圖咩..

這邊強者真多 /images/emoticon/emoticon41.gif

不過 我剛看一下這個好像是 pm2.5 不是 天氣 溫度 下雨或出太陽 這種的 我需要的是這種的說

是python寫的無誤,每10分鐘產生一次html靜態頁面,不過算不上真爬蟲,因為空氣品質資料是公開的格式(csv,json,xml)不用dom parser就能把資料分解開來

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import folium
import jsonpickle
import requests
import re
import os
import datetime
import colorsys
import math

ismain = False
testName = 'AQI'

#取得空品最大值與最小值轉換成相對色彩值
def colorWVB(From=[0,0,0],To=[360,100,100],r=0,min=0,max=30):
    #colorMin = colorsys.hsv_to_rgb(360,0,100)
    #colorMax = colorsys.hsv_to_rgb(272,100,43)
    sColor='white'
    cH = [From[0],To[0]]
    cS = [From[1],To[1]]
    cV = [From[2],To[2]]
    if max>min:
        vR = (r-min)/(max-min)
        sH = ((cH[-1]-cH[0])*vR+cH[0])/360
        sS = ((cS[-1]-cS[0])*vR+cS[0])/100
        sV = ((cV[-1]-cV[0])*vR+cV[0])/100
        rgb = colorsys.hsv_to_rgb(sH,sS,sV)
        sColor = "rgb({0},{1},{2})".format(int(rgb[0]*255),int(rgb[1]*255),int(rgb[2]*255))
    return sColor
    
    
#把空品質數轉換成RGB(數值愈高顏色愈深),我好像用錯色彩模型了
def color_producer(r,min=0,max=30):     
    cn="white"
    cr=0.7
    vRange = max-min
    vDiff = vRange / 4
    if r<=min+vDiff :
        cn = colorWVB([360,0,100],[112,100,100],r,min,min+vDiff) #'green' 
    elif r>min+vDiff and r<=min+vDiff*2:
        cn = colorWVB([112,100,100],[58,100,79],r,min+vDiff*1,min+vDiff*2) #'yellow' 
    elif r>min+vDiff*2 and r<=min+vDiff*3:
        cn = colorWVB([58,100,79],[0,100,71],r,min+vDiff*2,min+vDiff*3) #'red' 
    else:
        cn = colorWVB([0,100,71],[291,100,54],r,min+vDiff*3,min+vDiff*4) #'purple' 
    return [cn,cr]


#以下為主程式
isdigit = re.compile(r'^\d+\.*\d*$')
localhtml = "taiwan.html"
pm25_url ='https://data.epa.gov.tw/api/v1/aqx_p_432?format=json&api_key=9be7b239-557b-4c10-9775-78cadfc555e9'
html = requests.get(pm25_url)
localtime = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')
json = jsonpickle.decode(html.text)
#把json檔變成python可用的diction/list
vMin = 999999
vMax = 0 
for j in json['records']:
    pm2p5 = j[testName]
    if isdigit.match(pm2p5) is not None:
        vQ = int(pm2p5)
        if vQ < vMin :
            vMin = vQ
        if vQ > vMax :
            vMax = vQ


center = (23.5, 121)
# 動用到folium產生google map,把相對應的數值依GPS定位點繪製圓型跟套用色彩
m = folium.Map(location=center, zoom_start=8,title="全台空氣品質("+testName+")即時監測圖況")
folium.map.Marker(
    location=(23.2,121.4),
    icon=folium.DivIcon(
        icon_size=(300,36),
        icon_anchor=(0,0),
        html="<div style='text-align:center;font-size:1.6em;color:red;background-color:yellow;'>全台空氣品質("+testName+")即時監測圖況</div><div style='text-align:center;'>{0}</div>".format(localtime)),
    ).add_to(m)

fg = folium.FeatureGroup(name="PM2.5")
vLevel = (vMin if vMin>0 else 1)/(vMax if vMax>0 else 1)

for j in json['records']: 
    pm2p5 = j[testName]
    if j["Latitude"]!= "" and j["Longitude"]!="" and isdigit.match(pm2p5) is not None:
        r = int(pm2p5)
        cc = color_producer(r,vMin,vMax)
        loc = (j["Latitude"],j["Longitude"])
        fg.add_child(folium.CircleMarker(
            location=loc, 
            radius = r*vLevel, 
            tooltip=str(r)+'\n'+j["SiteName"],
            fill_color=cc[0], 
            color = 'grey', 
            fill_opacity=cc[1]))
m.add_child(fg)                    


#把網頁存下來,並加一些meta符合facebook / line的分享資訊

currpath = "/var/www/html/"+localhtml
loc = 'TAIWAN '+testName
title_html = '<div style="z-index:5000;text-align:center;font-size:2.0em;background-color:transparent;position:fixed;top:0px;left:300px;">{}</div>'.format(loc)   
m.get_root().html.add_child(folium.Element(title_html))
m.get_root().header.add_child(folium.Element('<meta property="og:title" content="全台空氣品質('+testName+')即時監測圖況" />'))
m.get_root().header.add_child(folium.Element('<meta property="og:type" content="article" />'))
m.get_root().header.add_child(folium.Element('<meta property="og:image" content="http://music.mihodb.com/taiwanpm25.jpg" />'))
m.get_root().header.add_child(folium.Element('<meta property="og:url" content="http://music.mihodb.com/taiwan.html" />'))
m.get_root().header.add_child(folium.Element('<meta property="og:description" content="資料來自: 行政院環境保護署。環境資源資料開放平臺 https://data.epa.gov.tw " />'))
m.save(currpath)

#就醬!

雄雄弄上來,草草寫註解,看了傷眼真的SORRY

不會唷 非常感謝 :)

不知我是不是用錯線性色彩模型HSV,抓出來的顏色似乎沒有我想的那麼美好,有興趣的人可以一起聊聊

samshum iT邦新手 5 級 ‧ 2021-03-31 17:41:44 檢舉

強!

淺水員 iT邦研究生 2 級 ‧ 2021-04-01 00:32:44 檢舉

顏色變化這樣也許比較簡單:

  • H從 240(藍色,代表最低) 往 0(紅色,代表最高) 變化
  • S 跟 V 都 100

如果是要同時改變 H 與其他數值
必須有經驗的視覺設計配出來才比較符合直覺

或是直接參考 https://env.healthinfo.tw/air/ 的配色

淺水員
謝啦,改起來好看多了,果然美學是天生的!

色彩模型這樣改起來簡單好區分

def color_producer(rin,minin=0,maxin=30):     
    cr=0.7
    cn = colorWVB(From=[240,100,100],To=[0,100,100],r=rin,min=minin,max=maxin)
    return [cn,cr]

https://ithelp.ithome.com.tw/upload/images/20210401/20117954XJzWA4kvOx.jpg

我要發表回答

立即登入回答