摘要:因?yàn)檫@里用到了異步編程的事件監(jiān)聽(tīng),所有的動(dòng)作都是異步操作,如果通過(guò)上述兩個(gè)辦法取出的值都是。但需要注意,在調(diào)用的地方也需要異步編程編碼問(wèn)題在抓取非英文網(wǎng)頁(yè)時(shí),總會(huì)遇到編碼問(wèn)題,中文也不例外。
node-feedparser
這篇文章是我學(xué)習(xí)node-feedparser的時(shí)候所寫(xiě)的,前半部分是翻譯了node-feedparser在github上的原文(英語(yǔ)不好,如果翻譯有誤,還請(qǐng)見(jiàn)諒。),當(dāng)中也夾雜了一些自己解釋?zhuān)缓蟀氩糠值膶?shí)戰(zhàn)是我結(jié)合 compressed.js ,同時(shí)自己在實(shí)際運(yùn)用中的小結(jié),現(xiàn)在拿出來(lái)和大家分享,希望大家給予指正。
文章信息時(shí)間 / 2017年3月9日
版本號(hào)
Node.js: v6.10.0
node-feedparser: v2.1.0
request: v2.79.0
iconv-lite: v0.4.15
項(xiàng)目地址 / https://github.com/danmactoug...
目錄Feedparser 基于Node.js的RSS,Atom,RDF強(qiáng)勁解析器
如何安裝
用法
feedparser可選參數(shù)
例子
API
feedparser解析后能得到什么?
meta屬性列表
article屬性列表
貢獻(xiàn)
License
實(shí)戰(zhàn)
處理數(shù)據(jù)
取得數(shù)據(jù)
編碼問(wèn)題
錯(cuò)誤捕捉
Feedparser 基于Node.js的RSS,Atom,RDF強(qiáng)勁解析器Feedparser是一個(gè)基于基于Node.js的強(qiáng)勁解析器,可以解析包括RSS,Atom和RDF信息
它有一對(duì)特性是你在其他的Feed解析器中不常見(jiàn)的:
它可以解析一些相對(duì)URL鏈接(例如Tim Bray"s "ongoing"這個(gè)Feed)
它可以正確地解析一些XML命名空間(包含那些非常規(guī)的Feed——用主要的一些Feed元素來(lái)定義的非常規(guī)命名空間)
說(shuō)明:對(duì)第二條的理解是,通常Feed的XML命名是固定的一些標(biāo)簽,但是Feedparser同樣可以對(duì)一些非常規(guī)的XML進(jìn)行解析,這就是強(qiáng)大之處。
如何安裝npm install feedparser用法
這個(gè)例子能簡(jiǎn)要地示范feedparser的基本概念:
請(qǐng)注意在學(xué)習(xí)基本的示范的同時(shí),也要學(xué)習(xí)簡(jiǎn)化的范例compressed.js文件,這樣也能夠讓你更全面地開(kāi)展工作。
var FeedParser = require("feedparser"); var request = require("request"); // 需要引入一個(gè)request,用于抓取Feed var req = request("http://somefeedurl.xml") var feedparser = new FeedParser([options]); req.on("error", function (error) { // 解決任何的request請(qǐng)求錯(cuò)誤 // 這個(gè)是request包的錯(cuò)誤提示 }); req.on("response", function (res) { var stream = this; // 這里的this是req(所請(qǐng)求request文件),是stream文件類(lèi)型 if (res.statusCode !== 200) { this.emit("error", new Error("Bad status code")); } else { stream.pipe(feedparser); } }); feedparser.on("error", function (error) { // 處理feedparser的錯(cuò)誤 // 這個(gè)是feedparser包的錯(cuò)誤提示 }); feedparser.on("readable", function () { // 此時(shí)已經(jīng)獲取到Feed信息,在這里可以進(jìn)行你的操作了 var stream = this; // 這里的this是feedparser, 也是stream文件類(lèi)型 var meta = this.meta; // 注意:這個(gè)meta是在feedparser的實(shí)例中一直可以獲得。 //Meta其實(shí)是RSS等一些的元信息,在后面會(huì)介紹到,一般來(lái)說(shuō)Meta信息都是重復(fù)的。 var item; while (item = stream.read()) { console.log(item); //在這里輸出每一條Feed信息。 } });feedparser可選參數(shù)
normalize:設(shè)置false讓Feedparser的默認(rèn)值失效。無(wú)論這個(gè)Feed的形式,這個(gè)參數(shù)都能將其解析成一個(gè)包含RSS2.0格式,正確屬性的對(duì)象。序列化后的形式如以下所示(只進(jìn)入第一層):
//通過(guò)bash輸出: 屬性名:rss:@ 值:[object Object] 屬性名:rss:title 值:[object Object] 屬性名:rss:link 值:[object Object] 屬性名:rss:author 值:[object Object] 屬性名:rss:guid 值:[object Object] 屬性名:rss:category 值:[object Object] 屬性名:rss:pubdate 值:[object Object] 屬性名:rss:comments 值:[object Object] 屬性名:rss:description 值:[object Object] 屬性名:meta 值:[object Object]
addmeta:設(shè)置false讓Feedparser的默認(rèn)值失效。讓每一個(gè)Feed的article信息都加入Meta信息。個(gè)人建議可以設(shè)置為true,一般來(lái)說(shuō),每個(gè)Feed的Meta信息都是唯一的,而article信息不同,只要第一次獲取Meta后,就可以只需要article信息。
feedurl:Feed的URL地址。FeedParser能非常優(yōu)秀地處理相對(duì)url,但是一些Feed在使用相對(duì)url時(shí),并不聲明xml:base信息。盡管feedparser非常有效,但是在我們處理feed和嘗試著處理這些相對(duì)url之前,我們?nèi)匀徊荒苤纅eed的url。如果我們發(fā)現(xiàn)了feed的url,我們將會(huì)返回并處理那些我們已經(jīng)得到的相對(duì)url,但這將會(huì)消耗一段時(shí)間(并非很長(zhǎng))。如果你想要確信我們不對(duì)相對(duì)url進(jìn)行預(yù)處理(或者feedparser無(wú)法處理相對(duì)url),你應(yīng)該設(shè)置feedurl選項(xiàng),否則,你就當(dāng)沒(méi)看見(jiàn)過(guò)它吧~
resume_saxerror:設(shè)置false讓Feedparser的默認(rèn)值失效。這個(gè)選項(xiàng)能夠拋出error中的SAXError錯(cuò)誤,并自動(dòng)進(jìn)行后續(xù)的解析。在我的測(cè)試中,SAXErrors并不常錯(cuò)誤,所以開(kāi)啟這個(gè)選項(xiàng)通常對(duì)你很有幫助。如果你想要完全掌握和處理錯(cuò)誤,并在任意點(diǎn)中止解析feed的話(huà),可以嘗試用這個(gè)選項(xiàng)。
例子在這里查看例子 examples 。
API 轉(zhuǎn)換 StreamFeedparser是一個(gè)stream轉(zhuǎn)換器(關(guān)于stream你可以在nodejs官網(wǎng)閱讀),從XML文件轉(zhuǎn)換為Javascript的objects對(duì)象。
每一個(gè)可讀的區(qū)塊都是一個(gè)對(duì)象,這個(gè)對(duì)象代表feed中的article信息。
發(fā)出的項(xiàng)目meta - 被解析后,稱(chēng)作feed的 meta
error - 任何時(shí)候Feedparser發(fā)出的錯(cuò)誤(包括SAXError, Feedparser error等)
feedparser解析后能得到什么?Feedparser對(duì)每一個(gè)Feed都會(huì)解析出 meta 和一個(gè)或更多的 articles。
不論Feed的形式如何, meta 和每一個(gè) article 都包含一個(gè)RSS2.0規(guī)范同時(shí)加上規(guī)范化后的屬性的信息流。舉個(gè)例子,一個(gè)Atom feed會(huì)有一個(gè) meta.description 屬性,但是同樣會(huì)有一個(gè) meta["atom:subtitle"] 屬性。
這個(gè)規(guī)范化后的屬性是用于向用戶(hù)提供一個(gè)規(guī)范的接口——當(dāng)你不知道feed的形式,或者搞不清不同feed形式之間的差異時(shí),用這個(gè)接口就可以方便獲取feed信息。不過(guò)當(dāng)你需要原始信息的時(shí)候會(huì)依然會(huì)保留給你使用。此外,F(xiàn)eedparser還提供了一些大眾化的命名空間擴(kuò)展,例如 itunes , media , feedburner 和 pheedo 這些擴(kuò)展。舉例:如果一個(gè)feed的article同時(shí)包含了 itunes:image 或 media:thumbnail ,那么這兩個(gè)的url地址都會(huì)保存到article的 image.url 屬性中。
所有的屬性都會(huì)進(jìn)行初始化,設(shè)置為 null (空數(shù)組或者空對(duì)象都會(huì)有恰當(dāng)?shù)膶傩裕_@個(gè)能夠節(jié)省你很多時(shí)間來(lái)檢查屬性是否為 undefined ,例如,當(dāng)你使用jade模板的時(shí)候。
除此之外,所有的屬性(包含命名空間)都使用小寫(xiě)字母("xmlUrl" and
"pubDate"仍然提供向下兼容)。“好用”取代了“原生”——衷心希望你能不必為駱駝拼寫(xiě)法而煩惱。
如果你設(shè)置normalize為true,那么 meta 和 article 的 title 和 description 屬性都會(huì)將HTML標(biāo)簽剝離。如果你需要這些HTML元素,你可以從 meta["atom:subtitle"]["#"] 這個(gè)屬性取得。
meta屬性列表title
description
link (網(wǎng)站鏈接)
xmlurl
date (最近的日期)
pubdate (原始出版日期)
author
language
image (一個(gè)對(duì)象,包含 url 和 title 屬性)
favicon (favicon的鏈接——只提供給Atom feeds)
copyright
generator
categories (一個(gè)字符串?dāng)?shù)組)
article屬性列表title
description (通常是完整的標(biāo)題內(nèi)容)
summary (通常是文章摘錄)
link
origlink
permalink
date
pubdate
author
guid
comments
image
categories
source
enclosures
meta
貢獻(xiàn)在這里查看所有代碼 -> contributors。
License(The MIT License)
實(shí)戰(zhàn) 處理數(shù)據(jù)feedparser.on("readable", function() { var item; while (item = this.read()) { //一般我們?cè)谶@里獲取數(shù)據(jù),在上面提到的,feedparser一共會(huì)輸出兩種信息,一種是規(guī)范化后的RSS2.0,另一種是原有的。 //原有信息的獲取:(推薦這種) console.log(item.meta.title); console.log(item.title); //RSS2.0信息的獲取: console.log(item["meta"]["rss:title"]["#"]); console.log(item["rss:title"]["#"]); } });
需要注意的是你無(wú)法通過(guò)return將上述的數(shù)據(jù)從函數(shù)中取出,也無(wú)法通過(guò)在外定義變量,在內(nèi)賦值取出。因?yàn)檫@里用到了異步編程的事件監(jiān)聽(tīng),所有的動(dòng)作都是異步操作,如果通過(guò)上述兩個(gè)辦法取出的值都是undefined。那么如何取出這些數(shù)據(jù)?這里有兩個(gè)辦法:
取得數(shù)據(jù)因?yàn)閒eedparser使用的是異步編程的辦法,所以無(wú)法通過(guò)常規(guī)方法取出值,不過(guò)仍然有以下兩種辦法:
直接在函數(shù)中進(jìn)行操作
使用Promise封裝
/* * 在函數(shù)中直接進(jìn)行操作不再演示 * 這里主要演示Promise封裝 */ new Promise((resolve, reject)=>{ //這里是一些request操作代碼,暫時(shí)省略 feedparser.on("readable", function() { var item; while (item = this.read()) { resolve(item); } }).then((result)=>{ //在這里可以用then繼續(xù)操作 console.log(result.title); //也可以return一個(gè)Promise對(duì)象,并在其他地方調(diào)用這個(gè)Promise。 //但需要注意,在調(diào)用Promise的地方也需要異步編程 return result; }).catch((err)=>{ console.log(err); });編碼問(wèn)題
在抓取非英文網(wǎng)頁(yè)時(shí),總會(huì)遇到編碼問(wèn)題,中文也不例外。比如新浪新聞的編碼是"utf-8",但是騰訊新聞的編碼是"gb3212"。feedparser雖然強(qiáng)大,但不負(fù)責(zé)解決這些問(wèn)題,這個(gè)時(shí)候需要我們引入 iconv-lite ,來(lái)解決編碼問(wèn)題。
var url = "http://www.example.xml"; var req = request(url); var feedparser = FeedParser(); var encode = "utf-8"; req.on("response", function (res) { console.log(res.statusCode); // 200 console.log(res.headers["content-type"]); // "image/png" }).pipe(iconv.decodeStream(encode)) //在iconv-lite可以直接調(diào)用 .pipe(feedparser);
因?yàn)?request 和 feedparser 之間的通訊是通過(guò)stream流的,而 iconv-lite 正好又有對(duì)于Stream流的API接口,所以直接調(diào)用即可。如果感興趣或者有需要的同學(xué)還可以去查看 iconv-lite 的官方文檔查看其它的方法。
錯(cuò)誤捕捉在整個(gè)抓取Feed的過(guò)程中,會(huì)遇到很多的錯(cuò)誤,如何處理這些錯(cuò)誤?這里借鑒一下官方文檔所提到的 compressed.js 中的方法,它將所有的錯(cuò)誤處理寫(xiě)成一個(gè)函數(shù),然后在每次事件監(jiān)聽(tīng)的地方,調(diào)用處理錯(cuò)誤函數(shù)即可完成。
//錯(cuò)誤處理函數(shù): function done(err) { if (err) { console.log(err, err.stack); return process.exit(1); } process.exit(); } //事件監(jiān)聽(tīng)調(diào)用done // ...省略 req.on("error", done); // ...省略 feedparser.on("error", done); feedparser.on("end", done); feedparser.on("readable", function() { // ...省略 });
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/86839.html
摘要:由于近期學(xué)業(yè)繁重,所以我就不說(shuō)廢話(huà)了,直接上代碼樸素貝葉斯進(jìn)行文本詞匯分類(lèi)詞表到向量的轉(zhuǎn)換創(chuàng)建實(shí)驗(yàn)樣本,返回的是進(jìn)行詞條切分后的文檔集合,還有一個(gè)類(lèi)別標(biāo)簽侮辱性的非侮辱性的代表侮辱性文字代表正常言論創(chuàng)建一個(gè)包含在所有文檔中出現(xiàn)的不重復(fù)的詞的 由于近期學(xué)業(yè)繁重QAQ,所以我就不說(shuō)廢話(huà)了,直接上代碼~ 樸素貝葉斯進(jìn)行文本詞匯分類(lèi) from numpy import * #詞表到向量的轉(zhuǎn)換...
摘要:前端每周清單年度總結(jié)與盤(pán)點(diǎn)在過(guò)去的八個(gè)月中,我?guī)缀踔蛔隽藘杉拢ぷ髋c整理前端每周清單。本文末尾我會(huì)附上清單線(xiàn)索來(lái)源與目前共期清單的地址,感謝每一位閱讀鼓勵(lì)過(guò)的朋友,希望你們能夠繼續(xù)支持未來(lái)的每周清單。 showImg(https://segmentfault.com/img/remote/1460000010890043); 前端每周清單年度總結(jié)與盤(pán)點(diǎn) 在過(guò)去的八個(gè)月中,我?guī)缀踔蛔隽?..
閱讀 1537·2021-11-04 16:10
閱讀 2774·2021-09-30 09:48
閱讀 2838·2019-08-29 11:31
閱讀 1577·2019-08-28 18:22
閱讀 3225·2019-08-26 13:44
閱讀 1319·2019-08-26 13:42
閱讀 2844·2019-08-26 10:20
閱讀 753·2019-08-23 17:00