滑滑手機、刷刷動態,每天都有許多好文章出現,能細嚼慢嚥的時間卻很少。你是不是也跟我一樣,有時候急著趕車、急著回覆別人訊息,一不留神,就把剛才那篇文章忘得一乾二凈?
平時,我會使用 Google Keep 或 EverNote 記錄些簡短訊息,如果遇見不錯的網站或文章,除了加入書籤外,也會使用臉書提供的珍藏功能,把感興趣的內容儲存起來,等有空的時候再慢慢欣賞。
當我接觸越來越多東西,漸漸地,就會發現時間寶貴,生命也應該要浪費在美好事物上呀。
在網路世界走馬看花,越看會越花,所以這陣子我試著主動出擊,把重點聚焦在感興趣的特定領域,就像是看論文做研究一樣,深入地去思考並了解一件事。
剛好,這陣子敗入了 Kobo 電子書閱讀器 ,發現他可以連結 Pocket 帳戶,自動把儲存的網路文章同步至閱讀器中,整個超棒棒啊。比起手機,他的螢幕更大,而且電子紙可以保護眼睛,這樣我閱讀效率應該可以往上提升吧 (至少不會被訊息甚麼的外務干擾 XDD)
總之最近我撈了很多網路文章,也就記錄一下如何使用 Pocket API,如何實作 Oauth 認證取得 token,然後附上一個 NodeJS 的範例。
什麼是 Pocket?
看到什麼喜歡的東西,就把它收進口袋吧!這個 Pocket 服務正如其名,就是要讓你方便的搜集網路文章、圖片與影片,等你忙完的時候,再泡杯咖啡,找個位子坐下,然後細細品味。
Pocket 支援各種平台,也推出了瀏覽器擴充套件,不論你用手機或是電腦,只要覺得這網站不錯,輕輕點一下 Pocket 按鈕就能將網頁儲存起來。
但我們今天的重點是使用 API 呀,產品介紹就不多談了,如果你有興趣,可以前往 Pocket 網站,或是下載 Chrome 擴充套件。
Pocket 網站 Pocket Chrome 擴充套件
使用 Pocket API
Pocket API 其實沒幾隻,就是驗證、新增、修改、刪除而已,畢竟儲存文章的服務也沒有很複雜。翻完文件,應該會發現複雜的地方就是 OAuth 驗證,必須取得 Access token 才能進行其他操作。文件在此,聰明人可以自行前往閱讀 XD
Pocket 開發者平台
根據說明,驗證流程分為五個步驟,條列如下:
- 取得 Consumer Key
- 取得 Request Token
- 導向 Pocket 頁面讓用戶進行授權
- 接受 Callback
- 取得 Access Token
首先,我們要先申請一個 Pocket 服務。請進入開發者平台,點選「Create a New App」,選擇要授予的權限,例如我想要新增文章,就只有勾選 Add。
完成之後會得到一組 Consumer Key,如下圖。
接著就是要透過這組 Consumer Key 去跟 Pocket Server 溝通拉。
我使用 node-getpocket 這個套件來取得 Auth URL。因為不是寫網頁,所以要自己把下方這串 URL 貼去瀏覽器,用戶驗證完後才會得到 Access Token。不過這裡要注意的是,必須要起一個 Server 來接收 Callback,詳情看程式碼就知道了。
https://getpocket.com/auth/authorize?request_token=xxxxx&redirect_uri=http://localhost:3000/connect/getpocket
點選授權後, 就會看見 Access Token。
我看網路上的討論,都說這組 access_token 沒有期限,也就是說取得後就能盡情使用,不用再次驗證。假如 token 外洩的話,也不用擔心,把你剛剛申請的 app 刪除,重新跑一次流程就行了。
NodeJS 程式碼
關於 node-getpocket 的使用,請參考 GitHub。起 server 驗證的部分我則是參考這篇。
var GetPocket = require('node-getpocket');
var myID = "xxxx";
var config = {
consumer_key: myID,
redirect_uri: 'http://localhost:3000/connect/getpocket'
};
function getRequestToken(){
var pocket = new GetPocket(config);
var params = {
redirect_uri: config.redirect_uri
};
pocket.getRequestToken(params, function(err, resp, body) {
if (err) {
console.log('Oops; getTokenRequest failed: ' + err);
}
else {
var json = JSON.parse(body);
var request_token = json.code;
console.log(request_token); // print request_token
getAuthorizeURL(pocket, request_token); // print auth URL
oAuth(request_token);
}
});
}
function getAuthorizeURL(pocket, request_token){
var config = {
consumer_key: myID,
request_token: request_token,
redirect_uri: 'http://localhost:3000/connect/getpocket'
};
var url = pocket.getAuthorizeURL(config);
console.log(url);
}
function oAuth(key){
var options = {
server: {protocol:'http', host:'localhost:3000'},
getpocket: {
key: myID,
callback:'/getpocket_callback'
}
}
var express = require('express')
, session = require('express-session');
var Grant = require('grant-express')
, grant = new Grant(options);
var app = express();
app.use(session({secret:'very secret'}));
app.use(grant);
app.get('/getpocket_callback', function (req, res) {
res.end(JSON.stringify(req.query, null, 2));
console.log(req.query.access_token); // // print access_token
})
app.listen(3000, function () {
console.log('Express server listening on port ' + 3000);
});
};
getRequestToken();
爬取網路文章,以文案的美為例
假如是 WordPress 部落格文章,可以透過 RSS 訂閱服務撈資料,但如果是普通網站呢?像我最近關注一個很棒的文案教學站「文案的美」,裡頭有很多關於文案寫作、邏輯思考的文章,想要把這些資料存起來,還是要自己動手寫爬蟲啦 XD
以往我都用 Python,現在換成 Node 純粹是要練習寫 JavaScript,還是不習慣一堆 Callback 啦嗚嗚。至於怎麼爬,我就不多做說明啦,直接貼 Code 囉。
var Crawler = require("crawler");
var access_token= 'xxx';
var c = new Crawler({
maxConnections : 10,
callback : function (error, res, done) {
if(error){
console.log(error);
}else{
var $ = res.$;
$('h6').each(function(i, elem) {
var title = $(this).text();
var url = $(this).find('a').attr('href');
if(title) send2pocket(title, url);
});
}
done();
}
});
// fetch all the links
var myID = "xxx";
var config = {
consumer_key: myID,
access_token: access_token
};
var pocket = new GetPocket(config);
var N = 23;
for(i=1;i<N;i++){
c.queue('http://www.copywriter.com.tw/teaching/?offset='+i.toString());
}
function send2pocket(title, url){
var parms = {
url,
title,
tags: '文案的美',
};
pocket.add(parms, function(err, resp) {
err ? console.log(err) : console.log(resp);
});
}
抓取完成圖,全部入袋 ^^