サイトリニューアルの時にたまに便利なツールを作った話
個人的にサイトリニューアル案件で「毎回使うわけではないけどたまに『あれできたら早いのに』って時に便利なツール」を作ってGitHubに公開しました。
(とはいってもひな型は同僚が作ってあって、私はそれを自分の要求に合わせてカスタムしただけ…)
どちらも大量のURLを一括で処理するツールで、用途もニッチなので年に2〜3回使うかどうか…って感じではあるのですが、必要になる時は膨大な物量が相手なのであるとめちゃくちゃ助かる系です。特に時間。
ページの特定の要素内のHTMLを一括で抜き出すツール「scraping_getHTML」
GitHubリポジトリはこちらhttps://github.com/mathme/scraping_getHTML
使用例
現行サイトにある1000件超のニュース記事を新サイトに移行したいが、新旧サイトのCMSでコンテンツ部分のフィールド構造が大きく異なるためCSVでのインポートはリスクが高く、しかし予算の都合で移行作業にコストもかけられない。
旧ニュースは今後変更がない前提で「HTMLコード流し込みでOK」で握ったため、コンテンツを括っている親要素(div=“target_class”)の中のHTML記述を丸ごと抜き出したい。
使い方
ページID(一意であれば何でもOK)と対象のURLをカンマ区切りで記述したテキストファイルを作って、getHTML.jsで要素のセレクタを指定してコマンドを叩くだけ。
IDをファイル名にしたテキストファイルが自動で生成されます。
パーサにcheerioを使っているので、対象要素の指定はjQueryライクに記述できる。
if (response.status === 200){
targetelm = $('.target_class').html(); //HTMLを取得したい要素を指定
}
ページのステータスをチェックして200ならtitle、301/302なら転送先URLを取得するツール「scraping_getMeta」
こちらもGitHubで公開済み
https://github.com/mathme/scraping_getMeta
使用例
サーバにあるHTMLファイルの一覧をクライアントから支給されて、そのリストにあるページのtitleを一覧化したい。ついでにサーバ側でリダイレクトがかかっていたらどこに転送されているかも知りたい、みたいなとき。
なんでこれを作ったか
サイトリニューアルの案件では、対象サイトのボリューム確認や作業の組み立てのためにプロジェクト初期に「全ページリスト」を必ず作るのですが、このときのリストの作り方として
サイトマップXMLからリストを作る
「Integrity Pro」などリンクチェックツールを使ってトップページからのリンク経由でリストを作る
などがありますが、たまにサイトマップXMLがなかったり、リンクチェックツールでページネーションが大量にあるアーカイブページの先を拾いきれなかったりすることがあったりして、取得漏れはわりと経験します。
そうでなくても意図的にリンクを張ってない孤立ページなんかもあったりするので、静的なサイトの場合はやはりサーバにあるHTMLのリストをもらうのが一番確実。
特に大規模リニューアルではこういうパターンの全ページリスト作成をすることがままあります。
しかしこの規模になるとページ数は余裕で1,000を超えて万に届くこともあるので、リストを作った後にページタイトルを取ろうとするとめちゃくちゃめんどくさい。
一番手軽なのはスプレッドシートで「IMPORTXML」を使うやり方ですが、処理がめちゃくちゃ遅いうえ、100件とか一度に処理を実行すると固まってしまう。1万件とかどんだけかかるんだっていう。
ここで、先に書いた「scraping_getHTML」を使えばtitle要素自体は取れるのですが、あちらは移行に使うのが目的のツールなので結果がIDごとのファイルに分割されてしまっていまいち使い勝手がよろしくないです。
1つのファイルで出力したいし、ついでにページに認証がかかっていたらそのステータス情報もほしいし、サーバリダイレクトされてたら転送先のURLも知りたい…となったので、じゃあもう別のツールにしてしまえということで作ったのが「scraping_getMeta」です。
使い方
1行1URLで記述したテキストファイルを作って、getMeta.jsを叩くだけ。
アウトプットファイルファイルに、URL、ステータス、title、(301/302の場合)転送先URLが記述されます。
26,000URLまでは動作確認済み。
title以外にdescriptionも取りたいとかあれば、getMeta.jsに変数宣言追加して取得し、最後にファイル出力する変数に結合すればOKです。
使ってるライブラリとか
axios … HTTP Clientライブラリ。URLにアクセスしてデータ取ってくる
cheerio … HTMLパーサ。axiousで取得してきたレスポンスのうちデータ部分をいろいろするためのもの
fs … ファイル操作するためのモジュール
readline … 読み込んだデータを1行ずつ処理するためのモジュール
axiosのエラー時処理ざっくりしすぎでは?
それはほんとうにすまない。
自分で使う分には今のところ十分なので…何か起こったらその都度手を入れればいいかの気持ちでやってます…
リダイレクトがあったら全部エイヤで301扱いしたりとか。
もしなにか「ここおかしくね?」などお気づきの点があったらissueでご指摘ください。