iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 23
0
影片教學

用Django架構建置專屬的LINEBOT吧系列 第 23

[Day 23]用Django架構建置專屬的LINEBOT吧 - 網路爬蟲(I)

Python的網路爬蟲實作

對聊天機器人開發來說,
網路爬蟲算是常用的基礎功,
特別是針對python程式語言的開發,
有興趣的朋友可以閱讀這篇Python網路爬蟲的系列文,

網路爬蟲本身就是一門深入的學問,
筆者也是因為網路爬蟲的應用而入坑的,
初學者可以在本機用簡單的網站直接進行測試,
之後要接到LINE BOT的時候再看要怎麼對訊息進行前處理囉~

網路爬蟲實作-從雷達回波圖片處理方式偵測是否快要下雨了

如題,雖然現在的氣象預報資料已經很容易查詢也隨手可得了,
但總是會希望能夠在我所在的位置快要下雨的半小時、一小時前收到通知呀,
所以就用網路爬蟲抓取的雷達回波圖片來實現這件事情吧,
雷達回波的圖片如下:

https://ithelp.ithome.com.tw/upload/images/20201007/20121176lToDywIPO0.png

假設黃色區域是下比較大雨的地方,
那麼我們可以用前幾篇提到的OPENCV影像處理基礎來做處理,
偵測我們所在的位置是否有黃色以上的顏色出現就知道是否有下雨了,

這個單元我想採取倒敘法的方式進行,所以我這邊先丟一個已經可以運行的程式碼,
在接著補充說明如何逐步實現從LINE收到下雨偵測通知的訊息,

直接先上程式碼,這邊先建立一個Weather_Predict.py檔案:

#Weather_Predict.py

import requests 
import datetime
import time

from cv2 import cv2 as cv 
import numpy as np
import urllib.request

#設定偵測的中心點x,y
center = [1605,1435]

# URL到图片
def url_to_image(url):
    resp = urllib.request.urlopen(url)
    # bytearray將數據轉換成(返回)一個新的字節數組
    # asarray 複製數據,將結構化數據轉為ndarray
    image = np.asarray(bytearray(resp.read()), dtype="uint8")
    # cv2.imdecode()函數將數據解碼成OPENCV圖像格式
    image = cv.imdecode(image, cv.IMREAD_COLOR)
    # return the image
    return image

while True:
	now = datetime.datetime.now()
	url = 'https://opendata.cwb.gov.tw/fileapi/v1/opendataapi/O-A0058-003?Authorization=rdec-key-123-45678-011121314&format=JSON'
	res_get = requests.get(url)

	#將抓到的字串轉成dict
	radar_echo = res_get.json()

	#從dict中抓到圖片URL
	image_url = radar_echo['cwbopendata']['dataset']['resource']['uri']
	image = url_to_image(image_url)

	#根據中心點位置,將雷達回波圖中心點前後100大小的圖片切下來
	image=image[center[1]-100:center[1]+100,center[0]-100:center[0]+100]

	#把切下來的圖中的B、G、R波段分離
	B,G,R=cv.split(image)

	#將圖片數值進行運算,exR=超紅指數
	exR = 2*np.max(R)-np.max(G)-np.max(B)
	print('exR=',exR,'日期時間=',now)
	print('雷達回波圖的網址=',image_url)

	#如果切下來的圖片中有偏黃色、紅色的顏色,則發出提醒警告
	if np.max(exR)>=150:#這邊設定exR超過多少要回報,建議設定>=100
		print('快要下雨啦!!!')
		print(image_url)
		time.sleep(60*120)#如果發出提醒,則就睡兩小時
	else:
		time.sleep(60*10)#如果沒有下雨跡象,則10分鐘偵測一次

這整段複製後啟動,即可執行每十分鐘在指定位置進行偵測的動作,
運作的流程如下:
1.設定中心點(需要先取得一張雷達回波的實體圖片,以實體圖片中想要關注的x,y座標為中心點)
2.寫一個將網頁圖片轉為OPENCV圖像格式的函數
3.在政府的OPEN DATA中,以requests套件的requests.get爬取雷達回波資料

雷達回波圖的OPEN DATA長這樣

{
 "cwbopendata": {
  "@xmlns": "urn:cwb:gov:tw:cwbcommon:0.1",
  "identifier": "d95b710f-9067-4132-a1b4-b776cb3f0f58",
  "sender": "weather@cwb.gov.tw",
  "sent": "2020-10-07T15:06:00+08:00",
  "status": "Actual",
  "msgType": "Issue",
  "scope": "Public",
  "dataid": "A0058-003",
  "source": "Meteorological Satellite Center",
  "dataset": {
   "datasetInfo": {
    "datasetDescription": "資料說明",
    "parameterSet": {
     "parameter": [
      {
       "parameterName": "經度範圍",
       "parameterValue": "118.0-124.0"
      },
      {
       "parameterName": "緯度範圍",
       "parameterValue": "20.5-26.5"
      },
      {
       "parameterName": "解析度",
       "parameterValue": "3600x3600"
      }
     ]
    }
   },
   "resource": {
    "resourceDesc": "雷達整合回波圖-臺灣(鄰近地區)_無地形",
    "mimeType": "image/png",
    "uri": "https://opendata.cwb.gov.tw/fileapi/opendata/MSC/O-A0058-003.png"
   },
   "time": {
    "obsTime": "2020-10-07T15:00:00+08:00"
   }
  }
 }
}

4.另爬取到的json資料為radar_echo
5.radar_echo['cwbopendata']['dataset']['resource']['uri']取得雷達回波圖
6.將雷達回波圖丟到步驟1.的函數中,獲得以OPENCV格式讀取的圖檔
7.以圖檔中關注位置x,y座標為中心,取得200x200大小的圖檔令其為image(大小可隨需求調整)
8.分離image的B、G、R波段,並以圖片中的B、G、R最大值進入公式2R-G-B計算超紅指數exR(Excess Red)
9.如果exR出現大於100的數值,則代表切出來的關注區域中有下較大雨的情況
10.若符合下雨判定條件,則回傳所設定的訊息,並休息2小時,否則休息10分鐘

實際運行狀況如下,
https://ithelp.ithome.com.tw/upload/images/20201007/20121176OY9dduqJQj.jpg

如果把切下來的小張圖片儲存在電腦裡的話,
也能看得到是否為自己關注的區域,

https://ithelp.ithome.com.tw/upload/images/20201007/20121176FEuJmi9QBD.png

今天這篇透過requests套件將OPEN DATA的資料抓下來,
並且用OPENCV的方式從網路上的圖片直接擷取圖片數值以進行分析,
下一篇就要來繼續討論如何使用現有的資訊串接到LINE BOT上面並讓他持續監測提醒囉。

實際操作影片:


上一篇
[Day 22]用Django架構建置專屬的LINEBOT吧 - 將文字訊息轉成語音內容
下一篇
[Day 24]用Django架構建置專屬的LINEBOT吧 - LINE Notify
系列文
用Django架構建置專屬的LINEBOT吧30

尚未有邦友留言

立即登入留言