前言
說一下這個想法的由來折汞。其實最初目的不是為了獲取天氣的误证,這只是一個練習(xí)而已继薛。最初是想自動獲取公司的出勤情況,提醒我前一天有沒有忘記打卡的雷厂。公司打卡是由網(wǎng)站可以查詢的惋增,有時忘記了或者系統(tǒng)出錯,可能當(dāng)天打卡沒有打上改鲫,不去查看的話就記為缺勤了(這可是關(guān)乎工資啊啊啊啊)林束,于是想到了每天定時執(zhí)行一次查詢?nèi)蝿?wù)像棘,要是差到有缺勤記錄就在登錄系統(tǒng)時發(fā)出提示。所以作為一個初學(xué)者我就自然想到怎么獲取網(wǎng)站固定信息了壶冒。由于在公司是內(nèi)網(wǎng)缕题,無法在家測試,所以就寫個查詢天氣的腳本來確定基本的腳本結(jié)構(gòu)胖腾。
原理
原理呢烟零,其實就是字符串的處理。我知道可以用網(wǎng)站的api發(fā)出請求咸作,然后返回數(shù)據(jù)锨阿,這樣更加方便快捷。但是记罚,我不是學(xué)軟件的不會這個墅诡,233333。當(dāng)然 這不是理由桐智,可以去學(xué)末早,只是有更簡便的方式。我選擇將網(wǎng)頁源碼下載下來然后分析字符獲取字段说庭,畢竟如果登錄網(wǎng)頁能看到信息然磷,那么在網(wǎng)頁的html里應(yīng)該也有這個字段。那么現(xiàn)在大概的步驟就明確了:
- 下載網(wǎng)頁源碼刊驴。
- 查看源碼姿搜,分析關(guān)鍵字段的特征,從而能夠查找匹配。
這種方式只適合不需要網(wǎng)頁交互的查詢痪欲,假如查詢時還要輸入密碼這些就不能查到了悦穿。只要在瀏覽器直接輸入網(wǎng)址就能訪問的網(wǎng)頁可以用這種方法查詢需要的信息业踢。
詳細(xì)分析
在這里我選取中國天氣網(wǎng)上海天氣來作為查詢的網(wǎng)址。首先用瀏覽器將網(wǎng)頁另存為html格式知举,然后查看文本內(nèi)容(在這里推薦使用代碼編輯器查看瞬沦,瀏覽器有瀏覽網(wǎng)頁源碼功能的也可以查看雇锡。我將網(wǎng)頁文件傳到樹莓派用vim查看了,后面perl也是在樹莓派上寫)曙痘。用vim查看代碼边坤,然后搜索日期,天氣應(yīng)該是按日期來排的茧痒。太幸運了旺订,直接就搜到了:
實在是easy啊超燃。那么我們來分析這一行。
<input type="hidden" id="hidden_title" value="10月27日20時 周五 晴轉(zhuǎn)多云 16/22°C" />
這一行的分析思路有以下幾點:
- 這一句是通過搜索日期的到的劳闹,那么我們可以在代碼中使用查找日期來定位這一行本涕。
- 我們需要的天氣信息在
value=
關(guān)鍵詞后面用雙引號包起來的字段菩颖,我們可以在定位行后在行里定位字符串value=
,相信這不難做到。最簡單粗暴的方式就是用數(shù)組把每個字符保存起來晦闰,然后一個一個遍歷。這一行的字符也不多跪妥,占用內(nèi)存也不大声滥。 - 我還發(fā)現(xiàn),我需要的字段被雙引號
"
包起來纽疟,那么我聯(lián)想到perl中的split
函數(shù)憾赁×迹可以將這一行用split
函數(shù)將字符分解為以"
隔開的列表,這樣我們只要訪問列表元素就可以了颓芭。
代碼實現(xiàn)
首先使用shell的curl
命令下載網(wǎng)頁柬赐。這里解釋一下為什么不用perl
的命令(當(dāng)然是因為技術(shù)不好啊_)肛宋。perl對網(wǎng)絡(luò)的操作好像需要一些模塊酝陈,不知道這些模塊是安裝perl
時自帶的還是需要額外添加毁涉,也不確定公司的perl
是不是帶有這些模塊。但是shell的curl
命令是自帶的穆壕,我就使用shell命令來下載網(wǎng)頁了喇勋。在perl
中調(diào)用shell命令表達如下:
`curl -o wether.html http://www.weather.com.cn/weather/101020100.shtml`
注意兩邊的單引號川背!網(wǎng)址中的101020100.shtml
指的是上海的天氣頁面贰拿,不清楚具體城市編碼方式膨更,可以一個一個去網(wǎng)站查詢看团赏。命令中的-o wether.html
參數(shù)指的是將下載的網(wǎng)頁另存為wether.html
文件。
下載好網(wǎng)頁后就可以以文本方式讀取網(wǎng)頁內(nèi)容了斜纪。在處理文件字符之前层扶,我們需要獲得查詢的關(guān)鍵字都办,也就是日期。獲得關(guān)鍵字后去讀取文件每一行势木,并判斷當(dāng)前行是否包含關(guān)鍵字歌懒,包含關(guān)鍵字則將當(dāng)前行分解為列表及皂,得到列表就可以輸出天氣信息了。
最后得到代碼如下:
#!/usr/bin/perl -w
`curl -o wether.html http://www.weather.com.cn/weather/101020100.shtml`;
if ( ! open HTML,'<','wether.html' ) {
die "cannot open:$!"; #文件打開失敗提示
}
$date =`date`; #獲取當(dāng)前時間
chomp($date);
@date_list = split /\s+/,$date; #將獲取到的時間以空格分解板驳,提取出日期若治。也可以通過控制
#獲取時間命令的參數(shù)來直接獲得日期感混。比如 date "+%m月%d日"
#這樣就可以直接獲取"x月x日"格式的時間
while (defined ($line = <HTML>)) { #讀取文件每一行到$line變量里
$gre=(grep /$date_list[2]/,$line) + (grep /value=/,$line);#如果有日期浩习,又有value關(guān)鍵詞,則認(rèn)為找到了
if ($gre == 2){
@val_list=split /"/,$line; #將文本行以"為分隔符分解字段
print $val_list[5]."\n"; #天氣信息在列表元素5里
last;
}
}
close HTML;
以上就是代碼實現(xiàn)過程洽蛀,很簡單的幾行就搞定了。方法很偏門啊峡碉,慎用鲫寄。
運行結(jié)果
想要獲取更準(zhǔn)確更實時的數(shù)據(jù)也可以在網(wǎng)頁中繼續(xù)查找地来,主要是字符串的定位問題未斑。更簡單粗暴的方式是查看數(shù)據(jù)在哪一行蜡秽,直接跳到那一行去分解字符串獲取數(shù)據(jù)缆镣,這就免得去分析查找的關(guān)鍵字怎么獲取了。但這種方法的前提是網(wǎng)頁的內(nèi)容變動不太大寞蚌,需要的信息總是出現(xiàn)在那一行钠糊。就天氣來說眠蚂,網(wǎng)頁內(nèi)容還是比較固定的逝慧,可以采用這種方式。