国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

feedparser學(xué)習(xí)與實(shí)戰(zhàn)——基于Node.js的Feed解析器

Half / 582人閱讀

摘要:因?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)換 Stream

Feedparser是一個(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 , feedburnerpheedo 這些擴(kuò)展。舉例:如果一個(gè)feed的article同時(shí)包含了 itunes:imagemedia: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,那么 metaarticletitledescription 屬性都會(huì)將HTML標(biāo)簽剝離。如果你需要這些HTML元素,你可以從 meta["atom:subtitle"]["#"] 這個(gè)屬性取得。

meta屬性列表

title

description

link (網(wǎng)站鏈接)

xmlurl

date (最近的日期)

pubdate (原始出版日期)

author

language

image (一個(gè)對(duì)象,包含 urltitle 屬性)

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)?requestfeedparser 之間的通訊是通過(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

相關(guān)文章

  • 機(jī)學(xué)習(xí) | 樸素貝葉斯

    摘要:由于近期學(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)換...

    yuxue 評(píng)論0 收藏0
  • 前端每周清單年度總結(jié)盤(pán)點(diǎ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ī)缀踔蛔隽?..

    jackwang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<