経緯
https://github.com/kamranahmedse/developer-roadmap
上記の記事に以前のlsコマンド同様、お題があったのでやってみることにした。
とりあえず、タイトルと投稿者(ユーザ)を取得してJSONで保存することをゴールとする。
実装
Redditからhtml取得
ここは大したことはしていない。文字化けを考慮し、UTF8に変換している。
$url = 'https://www.reddit.com/r/programming/';
$html = file_get_contents($url);
$html = mb_convert_encoding($html,'UTF8','ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
DOMDocumentに変換
$dom = new DOMDocument();
@$dom->loadHTML($html);
DOMXpathでパース
DOMXpathのquery()を使えば深い階層を探索可能。タグの階層は自分でブラウザで確かめたほうが楽しいので、一応隠蔽しておく。記事に関するDOMNodeListが得られるので、foreachを用い、各記事からタイトル、ユーザを取得する。
$xpath = new DOMXpath($dom);
$articles_node = $xpath->query("//div[contains(@class,'classname')]/div/fuga");
$articles = [];
foreach($articles_node as $node){
$titles_node = $xpath->query("./hoge/h3",$node);
$article['title'] = $titles_node->item(0)->nodeValue;
$users_node = $xpath->query("./fuga/a",$node);
$article['user'] = $users_node->item(0)->nodeValue;
$articles[] = $article;
}
JSON形式で出力する
上記で作った配列をJSONに変換し、ファイルに保存する。見やすさのためと「/」がエスケープされるのを防ぐため、json_encode()にオプションを追加する。
$article_json = json_encode($articles,JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
file_put_contents('reddit_articles.json',$article_json);
動かしてみる
> php get-reddit.php
> cat reddit_articles.json
[
{
"title": "Serverless: 15% slower and 8x more expensive",
"user": "u/pimterry"
},
{
"title": "Nim version 1.0 released",
"user": "u/miran1"
},
{
"title": "An interview with Jean-Baptiste Kempf, president of VideoLAN and lead developer of VLC",
"user": "u/berlinparisexpress"
},
{
"title": "Announcing .NET Core 3.0",
"user": "u/ben_a_adams"
},
{
"title": "ReactOS 0.4.12 released",
"user": "u/pdp10"
},
{
"title": "What happened to Hadoop",
"user": "u/alexeyr"
},
{
"title": "Reference manual for the C Programming Language 1975",
"user": "u/ryvnf"
},
{
"title": "Crystal 0.31.0 released! Now with multi-threading preview",
"user": "u/Corait"
}
]%
完全なスクリプトはgithubに上げてある。