しばたテックブログ

PowerShellを中心に気分で書いている技術ブログです。

はてなブログのエントリ一覧をPowerShellで取得する

小ネタです。

blog.shibata.tech

で少し触れたはてなブログのエントリ一覧を取得する方法を紹介します。

sitemap.xmlからエントリ一覧を取得する

はてなブログに限った話ではなく一般的な話として、SEO対策でクローラー向けにサイトのトップにsitemap.xmlを置いているサイトが多くあります。

はてなブログにもこのsitemap.xml*1が用意されており、以下のスクリプトでエントリの一覧を取得することができます。

$url = 'ブログのURL'
$res = Invoke-WebRequest -Uri ([IO.Path]::Combine($url, 'sitemap.xml'))
if ($res.StatusCode -ne 200) {
    return
}
# sitemapの場合
Write-Output ([xml]$res.Content).urlset.url.loc
# sitemap indexの場合
foreach ($loc in ([xml]$res.Content).sitemapindex.sitemap.loc) {
    $res2 = Invoke-WebRequest -Uri $loc
    if ($res2.StatusCode -ne 200) {
        continue
    }
    Write-Output ([xml]$res2.Content).urlset.url.loc
}

実行結果はこんな感じです。

f:id:stknohg:20180621231023p:plain

sitemap.xmlは単体でサイト内のリンクを記述している場合と、別のxmlファイルへのリンクを記述している場合があるので両者に対応しておく必要があります。
このスクリプトでは両方のケースの値を無理矢理取得しようとする単純な作りにしています。

はてなブログAtomPubを使ってエントリ一覧を取得する

はてなブログではAtom Publishing Protocol(AtomPub)によるAPIが提供されています。

このAPIを使うと、エントリの一覧や、タイトル、エントリ内容などにアクセスすることができます。
エントリの一覧を取得するには以下の様なスクリプトを実行すればOKです。

# 設定
# IDや認証情報ははてなブログの詳細設定から確認可能
$hatenaId = 'はてなID'
$blogId = 'ブログID'
$cred = Get-Credential -UserName $hatenaId

# エントリ取得(下書き含む)
$entries = & {
    function GetXmlContent ([string]$Uri, [PSCredential]$Credential) {
        $result = [PSCustomObject]@{
            Content = $null;
            NextUri = $null;
        }
        $ret = Invoke-WebRequest -Uri $Uri -Credential $Credential
        if ($ret.StatusCode -ne 200) {
            return $result
        }
        $xml = [xml]$ret.Content
        $result.Content = $xml.feed.entry
        $result.NextUri = $xml.feed.link | Where-Object rel -eq next | Select-Object -ExpandProperty href
        return $result
    }

    $result = GetXmlContent -Uri "https://blog.hatena.ne.jp/$hatenaId/$blogId/atom/entry" -Credential $cred
    Write-Output $result.Content
    while (-not [string]::IsNullOrEmpty($result.NextUri)) {
        $result = GetXmlContent -Uri $result.NextUri -Credential $cred
        Write-Output $result.Content
    }
}

# 適当に出力
$entries | ForEach-Object {
    [PSCustomObject]@{
        Title = $_.Title;
        Url = $_.link | Where-Object rel -eq alternate | Select-Object -ExpandProperty href;
        IsDraft = $_.control.draft -eq 'yes';
        #Content = $_.content.'#text';
    }
} | Format-List

実行結果はこんな感じです。

f:id:stknohg:20180621231406p:plain

このサンプルでは簡単のためにBasic認証を使用しています。
実際にスクリプトを利用する場合は自己の責任において認証方法を選択してください。

スクリプトの内容に特に目を見張るところはありませんが、ページネーションのために内部関数を用意したくらいが工夫したところでしょうか。

なお、出力形式はかなり適当なので適宜カスタマイズして利用するのがオススメです。

【補足】 Gist

当初、上記スクリプトはGistに上げていました。
補足としてリンクを記載しておきます。

*1:昔はsitemap_index.xmlだったらしい