楊恩波,張 祝,付瑞瀅,鄒海東
(1.貴州省銅仁市氣象局,貴州 銅仁 554300;2.貴州省銅仁市氣象防災(zāi)減災(zāi)中心,貴州 銅仁 554300;3.貴州省松桃苗族自治縣氣象局,貴州 松桃 554100)
近年來新媒體技術(shù)的應(yīng)用有效提高了政府部門間協(xié)作效率,同時(shí)在擴(kuò)大公共氣象服務(wù)覆蓋面上發(fā)揮了重要作用。以微信為例,省、市、縣三級氣象部門通過加入其他職能部門工作交流群,可及時(shí)將服務(wù)信息發(fā)送到相關(guān)部門,對常規(guī)服務(wù)手段形成了有利補(bǔ)充[1];通過關(guān)注微信公眾號(hào),公眾亦可及時(shí)有效地獲取氣象部門的權(quán)威預(yù)報(bào)及服務(wù)信息。貴州省氣象服務(wù)中心在2019年投入運(yùn)行的微信機(jī)器人已實(shí)現(xiàn)將預(yù)警信號(hào)靶向發(fā)布至受影響地區(qū)的目標(biāo)群,而常規(guī)預(yù)報(bào)、決策氣象服務(wù)材料等內(nèi)容的發(fā)送仍依賴于各級氣象部門值班服務(wù)人員手動(dòng)操作,面對服務(wù)對象較多的現(xiàn)狀,這一做法費(fèi)時(shí)費(fèi)力,且存在漏發(fā)的可能,如何提高服務(wù)效率是急需解決的問題。
目前針對微信公眾號(hào)的信息推送技術(shù)擁有微信官方的技術(shù)支持,但針對普通微信號(hào)的自動(dòng)化技術(shù)受限制較多。有開發(fā)者利用網(wǎng)頁版微信開放協(xié)議[2]開發(fā)了相關(guān)微信自動(dòng)化工具,但該方法不具備普適性,部分微信賬號(hào)特別是新申請的賬號(hào)無法使用網(wǎng)頁版微信開放協(xié)議;部分開發(fā)者使用其他相關(guān)通信協(xié)議實(shí)現(xiàn)了微信自動(dòng)化功能,但使用方法未開源,且未獲得官方認(rèn)可,存在一定違規(guī)風(fēng)險(xiǎn)。
本文介紹基于UI Automation技術(shù)[3-4](以下簡稱UIA)的桌面版微信軟件自動(dòng)化的應(yīng)用,實(shí)現(xiàn)對桌面版微信程序的控制,從而達(dá)到自動(dòng)轉(zhuǎn)發(fā)文字類、文件類(含圖片)等信息的目的,減輕服務(wù)人員的工作壓力并提升工作效率,同時(shí)以12379網(wǎng)站為例介紹預(yù)警信息的獲取及入庫等關(guān)鍵步驟執(zhí)行過程,以FTP方式為例介紹文件類信息的獲取及入庫過程。
本文所介紹的關(guān)鍵技術(shù)為通過UIA實(shí)現(xiàn)對桌面版微信程序的控制,從而達(dá)到使其自動(dòng)執(zhí)行指定操作的目的。UIA是由微軟公司開發(fā)的界面自動(dòng)化測試框架,為技術(shù)人員提供通過編程控制Windows操作系統(tǒng)絕大多數(shù)程序界面元素的方法,從而實(shí)現(xiàn)模擬相關(guān)操作。該框架主要用于桌面程序編寫階段對界面穩(wěn)定性進(jìn)行測試,支持Win32應(yīng)用程序、.NET Windows窗體應(yīng)用程序和WPF應(yīng)用程序。
為減小開發(fā)難度,利用Python語言開發(fā),UIA采用封裝后的UI Automation模塊[3],界面使用PyQt5構(gòu)建,使用SQLite輕型數(shù)據(jù)庫實(shí)現(xiàn)任務(wù)記錄及日志記錄等功能,數(shù)據(jù)庫讀寫使用Python自帶的sqlite3庫。使用Request庫實(shí)現(xiàn)12379網(wǎng)站預(yù)警信息獲取[5],使用FTPlib模塊實(shí)現(xiàn)文件類信息的獲取[6];消息發(fā)送過程中為提高執(zhí)行速度借助Pyperclip模塊實(shí)現(xiàn)對剪貼板的控制[7]。
如圖1所示,應(yīng)用的主要運(yùn)行流程為主進(jìn)程依據(jù)時(shí)鐘定時(shí)連接SQLite數(shù)據(jù)庫,檢索是否存在待發(fā)消息,如果有則依據(jù)消息類型分別通過UIA操控桌面版微信執(zhí)行不同的信息發(fā)送操作,并及時(shí)在數(shù)據(jù)庫中將發(fā)送完的消息標(biāo)記為已執(zhí)行。SQLite數(shù)據(jù)庫中的消息記錄由信息采集/入庫程序負(fù)責(zé),該功能可集成于主程序中,通過多線程的方式開啟,也可使用獨(dú)立程序執(zhí)行。
圖1 應(yīng)用運(yùn)行流程Fig.1 The logic diagram of the app
桌面版微信界面中涉及自動(dòng)控制的元素主要包含5個(gè):主界面、搜索框、消息輸入框、打開文件按鈕、發(fā)送按鈕。使用UI Automation對桌面版微信軟件進(jìn)行解析,經(jīng)梳理后關(guān)鍵元素相關(guān)數(shù)據(jù)如表1所示。獲得相關(guān)元素?cái)?shù)據(jù)后可通過指定程序根據(jù)控件的深度及控件名稱來查找控件的位置,并進(jìn)行操作。
表1 微信軟件關(guān)鍵元素解析表Tab.1 The Analyzing result of WeChat's key elements
若要完成查找“銅仁氣象微信工作群”,并進(jìn)入消息編輯界面,方法如下:
import uiautomation as auto
wechatWindow=auto.WindowControl(searchDepth=1,ClassName=′WeChatMainWndForPC′)
TargetName=‘銅仁氣象微信工作群’
wechatWindow.SendKeys(′{Ctrl}f′, waitTime=1.0)
search.SendKeys(TargetName, waitTime=1.0)
choice=wechatWindow.TextControl(searchDepth=12, Name=′′)
if choice.Exists(maxSearchSeconds=3):
choice.Click(simulateMove=False)
return True
else:
wechatWindow.SendKeys(′{Esc}′)
return False
若要在消息輸入框中輸入“天氣預(yù)報(bào)”4個(gè)字并發(fā)送,方法如下:
import uiautomation as auto
wechatWindow=auto.WindowControl(searchDepth=1,ClassName=′WeChatMainWndForPC′)
msg=“天氣預(yù)報(bào)”
edit=wechatWindow.TextControl(searchDepth=4) # 查找消息輸入框
edit.SendKeys(msg)
edit.SendKeys(′{Enter}′)
若要打開指定位置的雨量圖并發(fā)送,方法如下:
import uiautomation as auto
wechatWindow=auto.WindowControl(searchDepth=1,ClassName=′WeChatMainWndForPC′)
file_path=′D: ain.png′
sendfilebtn=wechatWindow.ButtonControl(searchDepth=14, Name=′發(fā)送文件′)
filepathinput=wechatWindow.EditControl(searchDepth=4, Name=′文件名(N):′)
fileopenbtn=wechatWindow.SplitButtonControl(Name=′打開(O)′)
sendfilebtn.Click(simulateMove=False)
filepathinput.SendKeys(′%s′ %file_path)
fileopenbtn.Click(simulateMove=False, waitTime=1.0)
edit.SendKeys(′{Enter}′)
在實(shí)際操作過程中可通過Pyperclip模塊將消息內(nèi)容存儲(chǔ)在剪貼板中,同時(shí)利用發(fā)送快捷鍵(Ctrl+C/V)的方式提升執(zhí)行速度及效率。
數(shù)據(jù)庫包含2張表,表名分別為Schedule(用于存儲(chǔ)消息記錄)和Log(用于存儲(chǔ)日志),表結(jié)構(gòu)如表2、表3所示:
表2 Schedule表結(jié)構(gòu)Tab.2 The structure of Schedule Table
表3 Log表結(jié)構(gòu)Tab.3 The structure of Log Table
目前,各級氣象臺(tái)在國家突發(fā)事件預(yù)警信息發(fā)布系統(tǒng)中發(fā)布預(yù)警信號(hào)后,信息將逐級匯總到國家級服務(wù)器,同時(shí)在12379網(wǎng)站(www.12379.cn)上呈現(xiàn),通過解析12379網(wǎng)站的alarm_list_all.html文件,將數(shù)據(jù)返回為json格式,然后逐一檢索每一條預(yù)警信號(hào),判斷是否有指定地點(diǎn)氣象臺(tái)新發(fā)布的預(yù)警信號(hào),方法如下:
alarmsite=′http://www.12379.cn/data/alarm_list_all.html′
alarmzone=‘銅仁市氣象臺(tái)’
def readalarm():
alarm=msgpara()[′alarmmsg′]
alarmjson=requests.get(alarmsite)
alarmjson.encoding=′utf-8′
alarmjson=json.loads(alarmjson.text)[′alertData′] # 舊的預(yù)警信號(hào)
i=0
while i if alarmzone in alarmjson[i][′description′]: alarm=(alarmjson[i][′description′]) break else: alarm=msgpara()[′alarmmsg′] i=i+1 return alarm 取得需要入庫的預(yù)警信號(hào)文本內(nèi)容后將其寫入SQLite數(shù)據(jù)庫Schedule表中即可,寫入時(shí)需指定好需要發(fā)布的對象,即表2中target字段。 在應(yīng)用開發(fā)過程中,曾嘗試局域網(wǎng)共享及FTP服務(wù)器等2種方式獲取文件類消息,二者均可實(shí)現(xiàn)設(shè)計(jì)目標(biāo)。綜合考慮網(wǎng)絡(luò)安全及銅仁市氣象臺(tái)業(yè)務(wù)環(huán)境等因素后,采取了FTP服務(wù)器作為唯一途徑。具體做法為: ①預(yù)報(bào)員將需要發(fā)布的文檔或圖片上傳到FTP服務(wù)器指定目錄; ②信息采集程序(主要使用FTPlib模塊)定時(shí)掃描FTP服務(wù)器中指定目錄,如果發(fā)現(xiàn)其中有文件,則將文件下載至本地,將本地路徑(對應(yīng)表2中content字段)等信息寫入SQLite數(shù)據(jù)庫Schedule表中,同時(shí)刪除FTP服務(wù)器中的文件。 ③主程序監(jiān)測到文件類待發(fā)消息并執(zhí)行完發(fā)送流程后,將本地文件刪除。 基于本文所介紹方法開發(fā)的微信機(jī)器人軟件已在銅仁市氣象局正式投入運(yùn)行。最新版本在完善文件類消息發(fā)送功能后于2021年4月下旬開始運(yùn)行。截止目前共計(jì)向30余個(gè)黨政工作交流群及公眾氣象服務(wù)群轉(zhuǎn)發(fā)各類信息505條。其中文本類消息(含預(yù)警信號(hào)和1060121短信)209條,文檔類消息160條(主要是決策氣象服務(wù)材料),圖片類消息136條,在歷次重大天氣過程中第一時(shí)間為政府相關(guān)部門應(yīng)對重大天氣過程提供了服務(wù)信息,同時(shí)為部分公眾提供日常氣象預(yù)報(bào)作為出行的參考。 本文介紹了基于UI Automation技術(shù)的桌面版微信自動(dòng)化方法,為解決相關(guān)自動(dòng)化需求提供了新的開發(fā)思路。該方法可解決因微信賬號(hào)權(quán)限無法使用網(wǎng)頁版微信開放協(xié)議的難題,同時(shí)避免使用第三方微信自動(dòng)化閉源協(xié)議,安全性較高。需要注意的是該方法無法實(shí)現(xiàn)消息發(fā)送的并發(fā),即需要向目標(biāo)群或好友逐一發(fā)送。盡管執(zhí)行效率低于基于網(wǎng)頁版API的相關(guān)工具,但相較于人工發(fā)送的方式已經(jīng)有了很大提高,避免了漏發(fā)、誤發(fā)等問題,同時(shí)對微信賬號(hào)安全無影響。此外,該方法也可用于對值班人員的告警提醒,如在達(dá)到特定告警條件時(shí),向值班人員撥打微信語音電話。2.5 FTP方式獲取文件類消息
3 應(yīng)用成效
4 結(jié)束語