http://masalib.hatenablog.com/entry/2016/10/27/022048
を昔に作ったのですが
初心者が環境を用意するのが難しいので
今回はnode.jsでダウンロードするプログラムで作りなおした
はてなブログ記事はxmlで取得できるのですが
再帰プログラムにしないといけない所がめんどくさい所です
なぜnode.jsなのか
環境のインストールがwindows7以外が簡単!!
node.jsはインストールさえ終わってしまえば
環境依存がすくない言語です
そちらの言語ではてなブログの記事データを取得しました
環境を用意する
プロジェクトのフォルダを作成する
mkdir sitedownload cd sitedownload
cheerio-httpcliのモジュールをインストールする
npm install cheerio-httpcli
はてなの記事のURLやIDとパスワードを用意する
1・APIキーを確認する
はてなブログのダッシュボード
=> 設定
=> 詳細設定
=> AtomPub
ルートエンドポイントとAPIキーをメモる
2・はてなIDを取得する
はてなブログのダッシュボード
=> 設定
http://blog.hatena.ne.jp/masalib/masalib.hatenablog.com/config
↑ここ
またはアカウト設定
プログラム
// モジュールの読込 var client = require('cheerio-httpcli'); var request = require('request'); var URL = require('url'); var fs = require('fs'); var path = require('path'); //共通の設定 //階層の指定() var LINK_LEVEL = 99; //基準となるページURL var TARGET_URL = "https://blog.hatena.ne.jp/masalib/masalib.hatenablog.com/atom/entry" //既出のサイトを定義する。(既出のサイトは無視をする機能があるため。) var list = {}; //メイン処理 downloadRec(TARGET_URL, 0); //downloadRec( "a aa "+ TARGET_URL, 0); //indexOfの動作確認 //指定のurlを最大レベルlevelまでダウンロードする function downloadRec(url, level){ //最大レベルのチェックをする (最大レベルになるまでループさせるため) if (level >= LINK_LEVEL) return; //既出のサイトは虫をする。 if (list[url]) return; //基準ページ以外なら無視をする //----------------------------------------------------------- var us = TARGET_URL.split("/"); // console.log(us); //出力::[ 'http:', '', 'nodejs.jp', 'nodejs.org_ja', 'docs', 'v0.10', 'api' ] us.pop(); //popメソッドを使用して、配列の最後の要素を削除します。 //console.log(us.pop()); //出力::api // console.log(us); //出力::[ 'http:', '', 'nodejs.jp', 'nodejs.org_ja', 'docs', 'v0.10' ] var base = us.join("/"); //joinメソッドは配列の各要素を指定の文字列で連結し、結果の文字列を返します。 // console.log(base); //出力::http://nodejs.jp/nodejs.org_ja/docs/v0.10 if (url.indexOf(base) < 0 ) return; //hatenaのidとpasswordを入力する var user = 'masalib'; var password = 'password'; client.set('headers', { Authorization: 'Basic ' + new Buffer(user + ':' + password).toString('base64') }); // HTMLを取得する client.fetch(url, {}, function( err, $, res){ //リンクされているページを取得 $("link").each(function(idx){ // タグのリンク先を得る var href = $(this).attr('href'); if (!href) return; //href属性を取得できない時の処理 // タグのリンク先を得る var href = $(this).attr('href'); if ($(this).attr('rel') == 'next'){ console.log($(this).attr('rel')); console.log($(this).attr('href')); } else { return; } // 絶対パスを相対パスに変更 href = URL.resolve(url, href); //'#' 以降を無視する(a.html#aa と a.html#bb は同じものとする) href = href.replace(/\#.+$/, "") //末尾の#を消す downloadRec(href, level + 1); }); // ページを保存 (ファイル名を決定する) if ( url.substr(url.length - 1, 1) == '/'){ url += "index.html"; //インデックスを自動追加する。 } //var savepath = url.split("/").slice(2).join("/"); var savepath = url.split("/").slice(6).join("/"); //slice::配列の一部を取り出して新しい配列を返します。 savepath = "./xml/" + savepath; savepath = savepath.replace( /\?/g , "_" ) ; savepath = savepath.replace( /\=/g , "_" ) ; savepath = savepath + ".xml"; console.log(savepath); //nodejs.jp/nodejs.org_ja/docs/v0.10/download //保存先のディレクトリが存在するか確認をする。 checkSaveDir(savepath); console.log(savepath); //nodejs.jp/nodejs.org_ja/docs/v0.10/download fs.writeFileSync(savepath, $.html()); }); } //保存先のディレクトリが存在するか確認をする。 function checkSaveDir(fname){ //ディレクトリ部分だけ取り出す var dir = path.dirname(fname); //ディレクトリを再帰的に作成する。 var dirlist = dir.split("/"); var p = ""; for ( var i in dirlist ) { p += dirlist[i] + "/"; if (!fs.existsSync(p)) { fs.mkdirSync(p); } } }
このプログラムでxmlがダウンロードができました
記事xmlのデータを解析して、imgのデータをダウンロードするのを作りたいです
このプログラムは以下を参考にした
サイトをまるごとダウンロードをする - it-tech-dm’s blog
2017/09/19追記
windowsだとファイル保存できないので保存ファイル名を変更
2017/09/26追記
SSl化で変わるかも・・・orz