まちカドまぞくのプロマイド一覧をシェル芸で作る
やること
- まちカドまぞくプロマイド一覧ページをシェル芸で作る.
動機
- この度ローソンプリントからアニメ「まちカドまぞく」の素晴らしい各シーンを切り取ったプロマイドが公開された.
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">TVアニメ「まちカドまぞく」のキャラクター・1話~12話の名シーンをブロマイドとして店内マルチコピー機サービス「ローソンプリント」で販売開始♪
詳しくは→<a href="https://t.co/ByNiJOMOHY">https://t.co/ByNiJOMOHY</a><a href="https://twitter.com/hashtag/ローソン?src=hash&ref_src=twsrc^tfw">#ローソン</a> <a href="https://twitter.com/hashtag/ローソンプリント?src=hash&ref_src=twsrc^tfw">#ローソンプリント</a> <a href="https://twitter.com/hashtag/まちカドまぞく?src=hash&ref_src=twsrc^tfw">#まちカドまぞく</a> <a href="https://t.co/2VeUvwnQpz">pic.twitter.com/2VeUvwnQpz</a></p>— ローソンマルチコピー機 (@lawsonmulticopy) <a href="https://twitter.com/lawsonmulticopy/status/1232138192423464960?ref_src=twsrc^tfw">February 25, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
- しかしカットの枚数が全576枚と多く, 20枚/1pで**28+1p(16枚)**にページネーションされており, お気に入りの画像を探すのが大変だった.
- 「じゃあMarkdownで一覧を作ろう!」と思った.
やった
結論
- 結局1行のワンライナーになった.
curl -s 'https://lawson-print.com/products/categories/machikado?page=[1-29]'|egrep -B8 '<span>まちカドまぞく__[^<]+'|sed -r 's/^\t+//g;/^$/d;s/^--/@/g;1s/^/\n/'|awk -F\\n '{print substr($2,34,43)"\n"substr($8,10,29)"\n"substr($9,7)}' RS=@|ruby -e 'u="https://lawson-print.com";`dd`.split(?\n).each_slice(3).to_a.uniq.map{|a,b,c|puts"## [#{c.scan(/^[^<]+/)[0]}](#{u+b})\n![img](#{u+a})"}'>mazoku.md
分解
- きれいにしたもの
#!/bin/bash
curl -s 'https://lawson-print.com/products/categories/machikado?page=[1-29]' |
egrep -B8 '<span>まちカドまぞく__[^<]+' | sed -r 's/^\t+//g;/^$/d;s/^--/@/g;1s/^/\n/' |
awk -F\\n '{print substr($2,34,43)"\n"substr($8,10,29)"\n"substr($9,7)}' RS=@ |
ruby -e 'u = "https://lawson-print.com"
`dd`.split(?\n).each_slice(3).to_a.uniq.map { | a, b, c |
puts "## [#{ c.scan(/^[^<]+/)[0] }](#{ u+b })\n![img](#{ u+a })"
}' > mazoku.md
やったこと
- 以下, ワンライナーは目がつかれるので分解して解説する
1行目: クロール
curl -s 'https://lawson-print.com/products/categories/machikado?page=[1-29]' |
- 29ページあるプロマイド一覧ページのソースを取得.
- ここで得られる出力は, Chromeなら
view-source:https://lawson-print.com/products/categories/machikado
で確認できる. -
curl
コマンドの-s
は進捗状況やエラーを表示せず, 取得したページソースだけを出力するやつ. - 引数URLの一部が連番なら
[START-END]
で指定できる.(ここでは1-29
)
2行目: プロマイド名, プロマイド詳細ページURL, 画像URL部分の切り出し
egrep -B8 '<span>まちカドまぞく__[^<]+' | sed -r 's/^\t+//g;/^$/d;s/^--/@/g;1s/^/\n/' |
-
grep
コマンドの-B <int>
は, 検索に引っかかった行のn行前を一緒に表示する.(n行後は-A <int>
) -
egrep
コマンドはgrep -E
と同じく, 検索語での拡張正規表現を有効にする. - ここでは
画像リンク行~プロマイド詳細ページリンク行~プロマイド名行
を切り出している.
<img class="img-responsive" src="/media/23eb44c3-94e2-4f7b-8bd6-9829e262fb92" />
</div>
<!-- Item details -->
<div class="item-details">
<!-- Name -->
<h5>
<a href="/products/describe/1017190001">
<span>まちカドまぞく__01 L</span><br />
--
<img class="img-responsive" src="/media/e90a3d50-2557-478f-8088-bcec9e4418a2" />
</div>
<!-- Item details -->
<div class="item-details">
<!-- Name -->
<h5>
<a href="/products/describe/1017190002">
<span>まちカドまぞく__01 2L</span><br />
--
(略)
-
sed
コマンドの-r
は拡張正規表現を有効化し,+
,\t
,(
,)
,|
をエスケープ無しで使用できる. - ここでは:
- ページソースのインデントを削除(
s/^\t+//g
) - 空行削除(
/^$/d
) -
grep
のレコードセパレータ--
を<-- -->
と区別するため@
に置換(s/^--/@/g
) - 後続の
awk
で1行目を$2
に入れるため改行を挿入する(1s/^/\n/
)
- ページソースのインデントを削除(
(空行)
<img class="img-responsive" src="/media/23eb44c3-94e2-4f7b-8bd6-9829e262fb92" />
</div>
<!-- Item details -->
<div class="item-details">
<!-- Name -->
<h5>
<a href="/products/describe/1017190001">
<span>まちカドまぞく__01 L</span><br />
@
<img class="img-responsive" src="/media/e90a3d50-2557-478f-8088-bcec9e4418a2" />
</div>
<!-- Item details -->
<div class="item-details">
<!-- Name -->
<h5>
<a href="/products/describe/1017190002">
<span>まちカドまぞく__01 2L</span><br />
@
(略)
3行目: 不要行の削除, 必要部分の抽出
awk -F\\n '{print substr($2,34,43)"\n"substr($8,10,29)"\n"substr($9,7)}' RS=@ |
-
awk
コマンドのフィールドセパレータを改行(\n
), レコードセパレータ(RS
)を@
に設定. - こうすると
@
までの各行が変数$1~$9
までに順に入る. -
substr(str,N,L)
は文字列のN
文字目からL
文字切り出す.
/media/23eb44c3-94e2-4f7b-8bd6-9829e262fb92
/products/describe/1017190001
まちカドまぞく__01 L</span><br />
/media/e90a3d50-2557-478f-8088-bcec9e4418a2
/products/describe/1017190002
まちカドまぞく__01 2L</span><br />
(略)
4~7行目: Markdownに整形(Ruby)
u = "https://lawson-print.com"
`dd`.split(?\n).each_slice(3).to_a.uniq.map { | a, b, c |
puts "## [#{ c.scan(/^[^<]+/)[0] }](#{ u+b })\n![img](#{ u+a })"
}
- 標準入力を
dd
で受け取って行ごとに配列に入れ,each_slice(3).to_a
で3要素ずつで配列内配列を作る. -
uniq
は新着リリース欄に表示されたものを削除している. - 各要素を以下のMarkdown形式にして出力.
## [プロマイド名](詳細ページリンク)
![img](画像リンク)
-
> mazoku.md
で出力して完成!
## [まちカドまぞく__01 L](https://lawson-print.com/products/describe/1017190001)
![img](https://lawson-print.com/media/23eb44c3-94e2-4f7b-8bd6-9829e262fb92)
## [まちカドまぞく__01 2L](https://lawson-print.com/products/describe/1017190002)
![img](https://lawson-print.com/media/e90a3d50-2557-478f-8088-bcec9e4418a2)
(略)
まとめ
- シェル上でクローリングからスクレイピングまでをやった.
- 実行しながらデバッグしやすく, 感覚的にパイプで処理を繋いで書けて気持ちいい.
- まちカドまぞく1~5巻発売中!
Discussion