qiitaのトレンドをスクレイピングするコードを作成

qiitaのトレンドをスクレイピングしよう!!

これから、暇な時にいろんなクローラーを作って行きたいと思います。 ホントは、スクレイピングしたデータをみんなに共有できるようなものを作りたいのですが、それをしてしまうと色々厄介なことになりそうなので、そのソースコードを公開することにします。

ソースコードの場所

https://github.com/itayayuichiro/ruby-scraping-docker/tree/qiita_crawler この「qiita_crawler」というブランチをcloneしてください。

実行手順

※dockerが入っているのが前提になっています。(自分でrubyの環境がある方は5からで問題ありません)
  1. このリポジトリをクローンする
  2. docker-compose build
  3. docker-compose up -d
  4. docker-compose exec play bash
  5. bundle install --path .bundle
  6. bundle exec ruby qiita_crawler.rb
6.を実行すると
{:title=>"「設計なんて不要でしょ」について", :likesCount=>252},
 {:title=>"私が async/await、promise をちゃんと理解するまでのステップ1,2,3", :likesCount=>112},
 {:title=>"C言語がコンパイル~実行されるまで", :likesCount=>73},
 {:title=>"えっ?YDD(嫁駆動開発)は試したことがないの?", :likesCount=>77},
 {:title=>"C++初心者のみんな、単体テストとCIを組めるようになって君もライブラリ製作者の仲間入りしよう!", :likesCount=>35},
 {:title=>"[最新論文]MirrorGANをKerasで実装した話", :likesCount=>47},
 {:title=>"Pythonで粘菌ネットワーク", :likesCount=>52},
 {:title=>"【10日間でポートフォリオ作成に挑戦】1日目:要件定義〜記事投稿のCRUD", :likesCount=>41},
 {:title=>"マークアップエンジニアになって一年が経った今、自分の処女作から学ぶ。", :likesCount=>69},
 {:title=>"GAE Go 1.11 ランタイムが公式には 2nd gen ではなくなった件について", :likesCount=>22},
 {:title=>"【初心者向け】Hugo + GitHub Pagesで静的なポートフォリオを作る", :likesCount=>23},
 {:title=>"待ち焦がれたCollectionGroupがCloud Firestoreへやってきた。", :likesCount=>63},
 {:title=>"勉強会を支える技術: Twitterでライブ配信する方法", :likesCount=>20},
 {:title=>"Jetson Nano関係のTIPSまとめ", :likesCount=>24},
 {:title=>
   "Vue!!!SVG!!!「もうcanvasは時代遅れなんだね・・・あれ、でもcanvasで作ったほうが早くない?」 ⇛ 1時間でテトリスを作ってみた",
  :likesCount=>48},
 {:title=>"AWS GlueでETL(概念と運用)", :likesCount=>10},
 {:title=>"[WIP]html&CSS プログレスバー", :likesCount=>15},
 {:title=>"DjangoをTerraformでFargateにデプロイする話", :likesCount=>16},
 {:title=>"MySQL8.0におけるGROUP集計・並び替え", :likesCount=>7},
 {:title=>"VirtualBoxをダウンロードできない場合の対処法", :likesCount=>26},
 {:title=>"Rubyで学ぶWebサーバーアーキテクチャ(Preforking, ThreadPool, イベント駆動モデル)",
  :likesCount=>12},
 {:title=>"C++erは一体どこから来たのか。", :likesCount=>11},
 {:title=>
   "【警鐘】[改元][Windows][.NET] 「令和」対応パッチで画面が横に伸びる、文字が見切れる — Windows Update 手動更新はちょっと待った方がいい",
  :likesCount=>6},
 {:title=>"で、実際DateFormatterの生成コストってどれくらい重いの?", :likesCount=>8},
 {:title=>"macOSでお手軽Mastodon開発", :likesCount=>6},
 {:title=>"紀元前1世紀のシーザー暗号を現代でも使ってみよう", :likesCount=>16},
 {:title=>"ScalazよりもCatsを使いましょう", :likesCount=>7},
 {:title=>"[Windows]*と?以外のワイルドカード", :likesCount=>6},
 {:title=>"GitLab CI が想像以上にお手軽だった", :likesCount=>9},
 {:title=>"RaspberryPi ZeroでおうちkubernetesしようとしたらARMがつらかった話", :likesCount=>9}
このようなJSONが出力されると思います。 これを自由に使ってください。

簡単な解説

# qiitaのトップにアクセスする
uri = URI.parse("https://qiita.com/")
request = Net::HTTP::Get.new(uri)

req_options = {
  use_ssl: uri.scheme == "https",
}

response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(request)
end

# そのレスポンスをHTMLをパースするnokogiriにわたす
doc = Nokogiri::HTML.parse(response.body.toutf8, nil, 'utf-8')

# そして、トレンドの情報は下記のHTMLの属性にねじ込まれているので抽出してJSONでパース
json_data = JSON.parse(doc.css('.p-home_main div')[0].attribute("data-hyperapp-props").value)
result = []
json_data['trend']['edges'].each do |record|
  result.push({
    :title => record['node']['title'],
    :likesCount => record['node']['likesCount'],
  })
end
pp result
ざっとこんな感じです。 記事のIDなども取れるのでここにカスタマイズしてください。 以上!!