tech.guitarrapc.cóm

Technical updates

はてなブログの全エントリーURLを取得する

このブログ、実はhttpのままです。 はてなブログをやめるか考えているのですが、いったんhttps対応を進めましょう。

困るのがmixed content なのですが、とっかかりとしてこのブログの全URLを取得します。

目次

sitemap の取得

全記事のURLを取得するときに考えるのが、Google Web Master でどうやってクローラーにヒントを出しているかです。ご存知の通り、こういう時に使うのがサイトマップです。

f:id:guitarrapc_tech:20190106035311p:plain

ということで、全記事のURL取得は安直にサイトマップから辿ればいいでしょう。

はてなブログのsitemap は、ブログURL + /sitemap.xml でpagenation付sitemapindexを取得できます。 このブログならこのような感じです。

<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <loc>http://tech.guitarrapc.com/sitemap.xml?page=1</loc>
    <lastmod>2019-01-06</lastmod>
  </sitemap>
  <sitemap>
    <loc>http://tech.guitarrapc.com/sitemap.xml?page=2</loc>
    <lastmod>2019-01-06</lastmod>
  </sitemap>
  <sitemap>
    <loc>http://tech.guitarrapc.com/sitemap.xml?page=3</loc>
    <lastmod>2019-01-06</lastmod>
  </sitemap>
  <sitemap>
    <loc>http://tech.guitarrapc.com/sitemap.xml?page=4</loc>
    <lastmod>2019-01-06</lastmod>
  </sitemap>
  <sitemap>
    <loc>http://tech.guitarrapc.com/sitemap.xml?page=5</loc>
    <lastmod>2019-01-06</lastmod>
  </sitemap>
</sitemapindex>

あとは、各sitemapごとにアクセスして、記事URLを拾うだけです。

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>http://tech.guitarrapc.com/entry/2015/11/19/030028</loc>
    <lastmod>2015-11-19</lastmod>
  </url>
  <url>
    <loc>http://tech.guitarrapc.com/entry/2015/11/11/032544</loc>
    <lastmod>2016-09-24</lastmod>
  </url>
   <!-- ..... continue -->
</urlset>

結果がurl一覧で取れればいい感じに使えそうです。

http://tech.guitarrapc.com/ 
http://tech.guitarrapc.com/about 
http://tech.guitarrapc.com/entry/2019/01/05/060326 
http://tech.guitarrapc.com/entry/2019/01/05/044741 
http://tech.guitarrapc.com/entry/2018/12/22/235927 
http://tech.guitarrapc.com/entry/2018/09/29/165215 
http://tech.guitarrapc.com/entry/2018/09/29/154004 
http://tech.guitarrapc.com/entry/2018/09/29/151114 
..... continue

sitemap は所定のフォーマットに沿っているxmlなので適当に処理します。

今回はPowerShell、C#、Golang それぞれで書いてリポジトリにおいておきました。順にみていきます。

github.com

PowerShell

PowerShell 6.0以降 で動作します。(5.0で動かす場合は、Invoke-WebRequest-UseBasicParsing スイッチを追加するといいでしょう)

gist.github.com

特別に難しいことはないのですが、PowerShellの場合はXML型が担保できれば要素名をキーとして辿ることができます。 nullの取り扱いがゆるいこともあり、シンプルに書けます。

    [xml]$index = $res.Content
    $sitemaps = $index.sitemapindex.sitemap.loc

CSharp

C# 7.3 w/.NET Core 2.2 で動作します。*1

gist.github.com

C# でXMLだと、namespaceを毎度指定することになるのですこし面倒な感じがあります。

XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
var sitemaps = XElement.Parse(res).Descendants(ns + "loc").Select(x => x.Value).ToArray();

Golang

go-sitemapを使うとシンプルになります。

github.com

gist.github.com

練習なので、既存のパッケージを使わずstructを定義して、xmlのUnmarshal で割り当ててみます。

gist.github.com

安直に書いてみたのですが、こんな感じなのでしょうか? slice で要素数が事前にわからないので拡張に任せるのがいやなのと、要素確保をした場合に最初のappendで無駄になるのはどうするといいのかなぁ。

まとめ

とりあえず全ブログ記事URLが取れたので、次はmixed content の警告です。

*1:C# 8.0 / .NET Core 3.0 でも動作します。