NodeJSでsitemapをパースしてURLを抽出する。

2018-09-25
javascript%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0node.jssitemap
    

目次

概要

NodeJSでsitemap.xmlからURLを抽出する方法のメモ。 ちょっとググるとsitemap-stream-parserなんてものがありましたが、正直イケてませんでした。

PythonならBeautifulSoupという強力なライブラリがありますが、 せっかくなのでNodeJS自作しました。

環境 + 利用したもの

macOS NodeJS v10.10.0 sync-request ※同期処理でリクエストを投げる xml2json *XMLをJSONに変換するモジュール

実装

実装で気をつけたポイント

sitemap.xmlはURLがそのまま記述されているパターンのものと、 子のxmlのパスが記述されているパターンがあります。

ちょっとググるとこの点を考慮していないものも見受けられますが、 紹介する実装はこの点を考慮しました。

シンプルに配列を返すパターン

const request = require('sync-request');
const parser = require('xml2json');

const url = "https://tech-blog.s-yoshiki.com/sitemap.xml"
console.log(JSON.stringify(getSitemap(url)))

function getSitemap(sitemap_url) {
    var result = []
    var response = request(
        'GET',
        sitemap_url
    );

    if (response.statusCode !== 200) {
        console.log("Status Code (function) : " + response.statusCode);
        return;
    }

    var data = JSON.parse(
        parser.toJson(
            response.getBody('utf8')
        )
    )
    if (data["urlset"]) {
        if (data["urlset"]["url"].length > 0) {
            data["urlset"]["url"].forEach((v) => {
                result.push(v)
            })
        } else if (data["urlset"]["url"]) {
            result.push(data["urlset"]["url"])
        }
    }

    if (!data["sitemapindex"] || !data["sitemapindex"]["sitemap"]) {
        return result
    }

    if (data["sitemapindex"]["sitemap"].length > 0) {
        data["sitemapindex"]["sitemap"].forEach((v) => {
            Array.prototype.push.apply(result, getSitemap(v.loc));
        })
    } else if (data["sitemapindex"]["sitemap"]["loc"]) {
        result.push(getSitemap(v.loc))
    }
    return result
}

非同期実行にする場合

getSitemap(url, (v)=> {
    console.log(v)
}, (err) => {
    console.log(err)
})

function getSitemap(sitemap_url, success_callback, err_callback) {
    var response = request(
        'GET',
        sitemap_url
    );

    if (response.statusCode !== 200) {
        err_callback(response)
        return;
    }

    var data = JSON.parse(
        parser.toJson(
            response.getBody('utf8')
        )
    )
    if (data["urlset"]) {
        if (data["urlset"]["url"].length > 0) {
            data["urlset"]["url"].forEach((v) => {
                success_callback(v)
            })
        } else if (data["urlset"]["url"]) {
            success_callback(data["urlset"]["url"])
        }
    }

    if (!data["sitemapindex"] || !data["sitemapindex"]["sitemap"]) {
        return;
    }

    if (data["sitemapindex"]["sitemap"].length > 0) {
        data["sitemapindex"]["sitemap"].forEach((v) => {
            getSitemap(v.loc, success_callback, err_callback)
        })
    } else if (data["sitemapindex"]["sitemap"]["loc"]) {
        getSitemap(v.loc, success_callback, err_callback)
    }
}

出力

出力例として、下記のような出力がされます。

{ loc: 'https://tech-blog.s-yoshiki.com/2018/01/13/',
  lastmod: '2018-05-03T05:45:57+00:00',
  changefreq: 'monthly',
  priority: '1.0' }
{ loc: 'https://tech-blog.s-yoshiki.com/2018/01/10/',
  lastmod: '2018-09-09T07:59:35+00:00',
  changefreq: 'monthly',
  priority: '1.0' }
{ loc: 'https://tech-blog.s-yoshiki.com/2018/01/5/',
  lastmod: '2018-01-22T12:15:57+00:00',
  changefreq: 'monthly',
  priority: '1.0' }
{ loc: 'https://tech-blog.s-yoshiki.com/blog_history/',
  lastmod: '2018-09-24T15:38:10+00:00',
  changefreq: 'weekly',
  priority: '0.3' }
{ loc: 'https://tech-blog.s-yoshiki.com/contents/',
  lastmod: '2018-06-16T14:48:38+00:00',
  changefreq: 'weekly',
  priority: '0.3' }
{ loc: 'https://tech-blog.s-yoshiki.com/about-me/',
  lastmod: '2018-07-28T13:28:55+00:00',
  changefreq: 'weekly',
  priority: '0.3' }
    

関連記事

Node.js で作成した REST API を Docker化
Node.jsでREST APIを作成 コンテナ化 コンテナ化定義 コンテナ化作業 参考 Node.js で作成した REST API を Docker化した際のメモです。 Node.jsでREST APIを作成 まずはNode.js…

JavaScriptで優先度付きキューを実装する
優先度付きキューについて ソース 参考 JavaScriptで優先度付きキュー (プライオリティキュー) を実装する 優先度付きキューについて 具体的には次のような機能があります。 キューに対して要素を優先度付きで追加 (push…

next_permutationをJSで実装する
ソース 使い方 参考 C++で提供されている順列を生成する next_permutation のJS実装です。 ソース 順列が存在する場合はtrueを返し、そうでなければfalse…

[JS]ラジアンから度数に度数からラジアンに変換する
コード 度数からラジアンへ ラジアンから度数へ サンプル ラジアンから度数に度数からラジアンに変換する際のスニペット。 コード 度数からラジアンへ ラジアンから度数へ サンプル

JS/TSのclassでclass名を取得する
コード JS/TSのconstructorを利用して自分自身のクラス名を取得する際のメモ。 コード このコードの結果は次のようになります。

JSで32ビット符号付き整数に対してのビット演算でハマった
具体例 参考にしたサイト JSでサブネットマスクの計算を行おうとしたとき、ビット演算でハマりました。その時のメモです。 JSでサブネットマスクの計算 JSでビット演算子を利用する場合 3…

JSでIPアドレスがサブネットマスクで指定した範囲内にあるか判定する
IPアドレスが指定した範囲内にあるかどうか判定 参考にしたサイト JSでIPアドレス(IPv4)が指定したサブネットの範囲に含まれるか判定するロジックを作った時の記録です。 IPアドレスが指定した範囲内にあるかどうか判定 処理としては、IP…

プログラムの数値計算で発生する誤差の種類 丸め誤差・打ち切り誤差・桁落ち
はじめに 誤差の種類 丸め誤差 打ち切り誤差 桁落ち 情報落ち 桁溢れ誤差 参考にしたサイト コンピュータで出てくる誤差はいくつかありますが、 それらをコードに落として整理しました。 はじめに 例えば の計算の答えは 0.6666666666…

JSでサブネットマスクの計算
JSによるサブネットマスク関連の計算 IPv4アドレス文字列をNumber型に変換する CIDR と サブネットの相互変換 ネットワークアドレス と ブロードキャストアドレス クラス 改めて計算方法を整理する 参考にさせていただいたサイト JSでIPv…

AWS Amplify に Next.js (SSG) で作ったアプリをデプロイする
はじめに 操作 Next.js (React) アプリの作成、Gitへのプッシュ AWS Amplifyでプロジェクト作成 参考にしたサイト この記事では、React / Next.js アプリケーションを作成し、AWS Amplify…

最新の投稿

Node.js で作成した REST API を Docker化
Node.jsでREST APIを作成 コンテナ化 コンテナ化定義 コンテナ化作業 参考 Node.js で作成した REST API を Docker化した際のメモです。 Node.jsでREST APIを作成 まずはNode.js…

JavaScriptで優先度付きキューを実装する
優先度付きキューについて ソース 参考 JavaScriptで優先度付きキュー (プライオリティキュー) を実装する 優先度付きキューについて 具体的には次のような機能があります。 キューに対して要素を優先度付きで追加 (push…

AWS Amplify で コンテナベースのデプロイを行い REST API を構築
検証した環境 やってみる 初期準備 パイプラインを確認 終了処理 参考 AWS Amplify で コンテナベースのデプロイを行い REST API を構築した際のメモです。 検証した環境 amplify 5.1.…

Pythonでソケット通信を実装しメッセージの送受信を行う
ソース server.py client.py 動かしてみる 参考 Pythonでソケット通信を実現する方法です。 ソース server.py サーバ側のソースです。 client.py…

next_permutationをJSで実装する
ソース 使い方 参考 C++で提供されている順列を生成する next_permutation のJS実装です。 ソース 順列が存在する場合はtrueを返し、そうでなければfalse…

応用情報技術者試験の合格体験記
受験時のステータス 受験結果 対策 スケジュール 午前問題 午後問題 参考書等 令和…

[JS]ラジアンから度数に度数からラジアンに変換する
コード 度数からラジアンへ ラジアンから度数へ サンプル ラジアンから度数に度数からラジアンに変換する際のスニペット。 コード 度数からラジアンへ ラジアンから度数へ サンプル

CentOS8 に Python + OpenCV をインストール
インストール テスト CentOS8 で標準で提供されているパッケージで Python + OpenCV 環境を構築する方法です。 検証した環境は CentOS8.3 (Docker) です。 インストール まず opencv…

[Perl] CentOS8 に plenv をインストール
インストール Step1 事前準備 Step2 PATHを通す (README通りにインストール) Step2 PATHを通す ($HOME以外にplenvをインストール) Step3 Perlインストール Step4 cpanmインストール CentOS…

JS/TSのclassでclass名を取得する
コード JS/TSのconstructorを利用して自分自身のクラス名を取得する際のメモ。 コード このコードの結果は次のようになります。

Tags

Dates

s-yoshiki
s-yoshiki
githubtwitterqiita
Web作ってますが、インタラクティブなプログラミングも好きです。
JavaScript / Vue / node.js / PHP / AWS / OpenCV
© 2021   404 motivation not found