【高級篇】RSS的世界:Huginn篇(中)

差點就放棄寫Huginn篇了,一是我平時折騰的那些網(wǎng)站全是靜態(tài)網(wǎng)頁,feed43就可以搞定了,Huginn簡直宰牛刀。二是Huginn使用起來需要一定門檻,比如要有服務器,沒服務器那就用云開發(fā)平臺吧,還得備著“梯”*zi,部署的時候得需要一些計算機知識吧,我就看個老頭官網(wǎng)消息,感覺更沒必要折騰Huginn了??
先更新中篇的內(nèi)容,就是關于Huginn如何使用。前篇關于Huginn的部署,我打算講在Heroku里部署以及獲取Huginn管理員權限。后篇是針對用Heroku部署Huginn產(chǎn)生的休眠問題如何解決,用服務器部署Huginn完全不用看后篇哈~
先說明一下哈,以下內(nèi)容是針對靜態(tài)網(wǎng)頁的抓取步驟指南,如果需要抓取動態(tài)網(wǎng)頁(大型網(wǎng)站有一些用的是動態(tài),普通網(wǎng)站還是靜態(tài)為主),其實就在以下步驟之前多一步,用Phantom Js Cloud Agent渲染動態(tài)網(wǎng)頁成靜態(tài)頁面后接下文的步驟。

第一步,先抓取概要信息。

先看一下用來做例子的網(wǎng)站,Chage的官網(wǎng)(我咋這么喜歡用C來開刀呢~??~)
先登錄Huginn,然后在左上角處點擊創(chuàng)建新代理(New?Agent)


然后選擇代理類型(type),輸入web就能出現(xiàn)Website Agent,選擇它。
這時出現(xiàn)具體設置的頁面,大概分成三個區(qū)域,左上為填寫代理基本信息與各個代理之間承接關系等等,左下為具體的代碼,右邊一大塊都是幫助說明。(幫助說明十分重要!一定要多看)

下面先看基本信息區(qū)。
代理類型(Type)不用動
名稱(Name)自己隨便起一個就行,比如“第一步”,或者網(wǎng)站名,或者“摘要”,自己能看明白的名字就好。
日程(Schedule)根據(jù)實際需要設置,比如你抓取的內(nèi)容更新比較頻繁,就把時間間隔設置的小一些,Every 5m、Every 10m之類的。
控制(Controllers)不用填寫
事件保留時間(Keep?events),實際使用要設置成forever,要不工作幾天就不工作了。
來源端(Sources),就是說你需要不需要其他代理的數(shù)據(jù),一般創(chuàng)建第一個代理這項不用填。立即執(zhí)行(Propagate immediately) 打勾。
接收端(Receivers),就是說你這里抓取的信息要傳遞給下一步的代理,一般創(chuàng)建第一個代理這項不用填。
場景分類(Scenarios),就是把這一系列的代理打個組這個分類,比較方便查看,可填可不填。


代碼區(qū)主要用到的有最右上角的切換視圖(Toggle View),試運行(Dry Run),這里提供兩種視圖,一種是下面的這種帶綠條的(圖一),一種是純代碼的那種(圖二)。


關于切換視圖(Toggle View)有個小技巧,就是用圖二的視圖寫好代碼,然后點擊Toggle View,如果能正常切換回帶綠條的視圖,說明代碼寫的沒問題,如果切換失敗,提示出錯什么的,就說明代碼寫的有問題,需要再檢查一遍代碼,尤其是符號。
這個切換視圖小技巧特別適合像我這種沒寫過代碼的人,因為我對符號沒意識,不是丟個,就是丟個;“”,代碼總是報錯……??
下面開始寫代碼。

第一行expected_update_period_in_days,我理解的應該是給代理設置一個更新周期,在這個周期里網(wǎng)頁沒有新消息更新,Huginn會認定為網(wǎng)站沒有工作(work),這項很雞肋,不用管。
先填寫url,就是你要抓取的網(wǎng)頁網(wǎng)址。
類型(type),基本都是html
模式(mode),這里有三種,all
、on_change
、merge。(具體見下圖)

一般來說第一步抓取用的是on_change模式,到中間這一層需要上一步的數(shù)據(jù)傳遞過來所以要用混合模式(merge)。
下面該填寫具體的抓取代碼了,先看一下老頭的網(wǎng)站,按F12調(diào)出查看器。

這里可以看出要抓取的內(nèi)容都在inf_box這一層里面,里面包括網(wǎng)址信息,標題內(nèi)容,時間信息等等。(如何用F12找到具體位置,我是憑感覺來的,反正是在中間位置,火狐瀏覽器右擊有個檢查,可以直接定位到大概位置。)
下面先寫提?。╡xtract)里的url信息,從上圖可以看到,網(wǎng)址在class="inf_box"的下面。
<div class="inf_box">
<a href="/information/media/detail-462.php">
根據(jù)huginn的幫助指南里面的舉例:"url": { "xpath": "//*[@class="blog-item"]/a/@href", "value": "."(我習慣用xpath來寫,用css來寫也是一樣的),稍稍改一下就是下面這段代碼:
"url": {
? ? ? ? "xpath": "//*[@class=\"inf_box\"]/a/@href",
? ? ? "value": "."
? ? }
這里面的//*[@class=\"inf_box\"]/a/@href,咋解釋呢……,//*?就是網(wǎng)頁前面的代碼全部省略,只找class是inf_box的那部分,然后 /a/@href 對應的 <a href="/information/media/detail-462.php">這一行,value用的 .?就是?<a href=的所有值。
注:代碼是靈活的,不唯一!
? ? "url": {
? ? ? "xpath": "//*[@class=\"inf_box\"]/a",
? ? ? ?"value": "@href"
? ? }
這樣寫也一樣可以抓出來網(wǎng)址,解釋出來就是找class是inf_box的那部分,對應到后面的<a,value的值取得是href的值。


? 點擊右上角的Toggle View來回切換幾遍,先保證代碼沒問題,然后點擊Dry Run試運行。

點擊Dry Run。

能看到正確的輸出結果,url那一行寫的沒問題,再添加標題(title)

從上圖可以看到,標題信息(title)在class="inf_txt"的旁邊。
<p class="inf_txt">12月度、ラジオコメント出演情報!</p>
根據(jù)上面所講的步驟,寫出title的代碼:
? ? "title": {
? ? ? "xpath": "//*[@class=\"inf_txt\"]",
? ? ? "value": "string(.)"
? ? }
代碼寫法不唯一,也可以寫成下面這種:
??? "title": {
? ? ? "xpath": "//*[@class=\"inf_txt\"]",
? ? ? "value": "./node()"
? ? }
解釋一下這兩種value,一個是string(.),應該是指class是inf_txt里包含的所有字符串,再具體我也不能說清楚啦,我也沒學過計算機……?字符串是啥我也不懂……反正就大概這個意思啦。另一種是./node(),就是取括號外的值,<p class="inf_txt">12月度、ラジオコメント出演情報!</p> 這里面的“12月度、ラジオコメント出演情報!”正好在兩個<>的外面,“./node()”正好可以用。
還可以用normalize-space(.),這個是去除文本中的空格和回車的值。

先點擊右上角的Toggle View切換幾遍視圖看看代碼有沒有問題,再點擊Dry Run試運行。
下面貼出四種不同value的輸出結果。




嘛,value就那么幾種寫法,大不了挨個試一下看看哪個效果好 ??
再根據(jù)上面的步驟把日期信息也抓出來。

實際使用中,沒必要把value值折騰這么多,我做例子才弄這么多value值,千萬別被我?guī)芷??
Dry Run一下。

這時候還有一個問題,url抓出來是沒有域名的,這在RSS閱讀器里不認的,接下來需要給一個模板(template)。模版和提?。╡xtract)是同級,寫在提?。╡xtract)的下方。
? "template": {
? ? "url1": "{{ url | to_uri: _response_.url }}"
? }
指定一個新的url1,url1是剛剛抓取的url的“延伸”,我感覺我解釋不清了,可以理解為給剛剛抓的url一個“前綴”把網(wǎng)址補全。這里一定要注意別丟了符號?,我總是忘記大括號還有逗號。



大功告成!url1已經(jīng)顯示出正確的網(wǎng)址!
如果仔細看的話,會發(fā)現(xiàn)這樣抓出來的和 feed43?抓出來的東西是一樣的。??


到了這里,可以進行第三步直接輸出XML訂閱地址,因為RSS閱讀器都有獲取全文功能,我們把url1這個網(wǎng)址告訴RSS閱讀器,閱讀器會自動加載出全文,如果閱讀器獲取的全文排版很亂,我們才會做第二步,就是用Huginn獲取全文,再輸出XML訂閱添加到閱讀器里。

第二步,根據(jù)剛剛獲取到的url1網(wǎng)址,獲取文章全文。
創(chuàng)建新的代理。

這里要填寫來源(Sources)了,來源就是剛剛第一步創(chuàng)建的代理。其他的根據(jù)自身情況填寫。
代碼區(qū)要注意,url要寫剛剛獲得的url1地址 {{url1}},模式要選擇merge。

先進入網(wǎng)站看一下F12,找到正文所對應的位置。

可以找到正文內(nèi)容都在class="inf_detail_txt"的代碼中。
<p class="inf_detail_txt">現(xiàn)在決まっているラジオコメント出演情報です。……</p>
所以在extract里添加article或者text,名稱可以自己隨便取,只要你能記住就行。
根據(jù)上面講到的內(nèi)容寫好代碼。

Dry Run一下。

這時出現(xiàn)這樣的界面,隨便點擊一個上面的url。

這時再點擊Dry Run。
下面列出四種不同value值的輸出結果。




通過對比可以看出,"value": "./node()"是非常完美的。"value": "string(.)"不包括<br>的換行符,這樣排版會亂。"value": "normalize-space(.)"只有文本信息,這樣排版很密。"value": "."是最完整的信息。
用"value": "./node()"或者"value": "."都可以。
保存一下,這樣第二步就完成了。

終于到第三步也就是最后一步,輸出RSS訂閱地址!碼字碼的我都累了……
再創(chuàng)建一個新的代理。選擇Date Out Agent

可能有人要問了,下面不是有個RSS嘛,那個不是輸出RSS訂閱啊,是把別人的RSS作為來源輸入進來……
基本信息和之前差不多,來源選擇剛剛創(chuàng)建的代理。如果你跳過了第二步,那來源就是第一步的代理,如果你做了第二步用huginn來獲取全文,此時的來源就是第二步的代理。

剩下的代碼就簡單多了。
secrets:是輸出XML文件的文件名,可以改個自己好記的名稱。
template部分見下圖,都是自己自命名的。
item部分要仔細填寫!
title是第一步代理里面的title。
description是第二步代理里的article,如果沒做第二步,可以把這行刪掉不寫。
link是第二步代理里面的url。
pubDate是第一步代理里面的時間。
可能有人要問了,為啥這里又能指定第一步代理里的信息,又能指定第二步代理的信息,還記得第二步里模式mode選的是merge嗎?選擇了merge后,就把這兩步代理的信息都合并了,所以這里可以各種指定。

保存
點擊你剛剛創(chuàng)建的RSS輸出代理,就看到輸出的xml文件了。

把這個xml地址添加到你的RSS閱讀器里就全部完成了!

再補充一點,如果把上面的都做完后發(fā)現(xiàn)events里是空的沒抓到信息,不急,run一下第一步創(chuàng)建的代理。

Huginn就自動刷新了,然后就能看到新的events出現(xiàn)~

哎喲我的媽呀,可算是把huginn的RSS用法寫完了,看不懂沒關系,多動手寫一寫,試一試,報錯就檢查符號有沒有忘記,好像沒啥要再強調(diào)的東西了。
希望這篇小文能幫到有需要的人~??~

【安利向】RSS的世界:cv13449742
【進階篇】RSS的世界:RSSHub篇:cv13543035
【進階篇】RSS的世界:Feed43篇:cv13544223