ElixirでWebスクレイピング
Webページの取得にHTTPoison, HTMLのパースにFlokiを利用します。
HTTPoison
GitHub - edgurgel/httpoison: Yet Another HTTP client for Elixir powered by hackney
Floki
実行環境を整える
プロジェクトの作成
$ mix new scraper_sample
関連モジュールの取得
mix.exsに依存関係を記述し取得します。
# mix.exs defmodule NetseaCrawler.Mixfile do use Mix.Project # .... def application do [applications: [:logger, :floki, :httpoison]] end defp deps do [ {:floki, "~> 0.10.0"}, {:httpoison, "~> 0.9.0"}, ] end end
$ mix deps.get Running dependency resolution Dependency resolution completed certifi: 0.4.0 floki: 0.10.0 hackney: 1.6.1 ...
iexの起動
以下のコマンドでiexを起動するとプロジェクトの環境が読み込まれるので、依存モジュールを参照することができます。
$ iex -S mix
スクレイピングしてみる
試しにelixirのページのコミットメッセージを取得してみます。
HTTPoisonでWebページを取得する
iex(1)> ret = HTTPoison.get! "https://github.com/elixir-lang/elixir" iex(2)> %HTTPoison.Response{body: body} = ret
これで変数bodyにHTMLが入ります。
Flokiでパース
ブラウザの「要素の調査」とかでHTMLの構造を把握します。
コミットメッセージは table.files > td.message > span で取れそうなのでFloki.findをパイプライン演算子でつなげていきます。(XPathで書けなそうなのでネストが深いと結構面倒)
iex(3)> Floki.find(body, "table.files") |> ...(3)> Floki.find("td.message") |> ...(3)> Floki.find("span") |> ...(3)> Enum.map(fn(span) -> Floki.text(span) end) ["Make batch style more consistent (#4944)", "Refactor and optimize aggregations over lists", "Fix a typo in the iex man page (#4655)", "Start v1.4.0-dev", "Move .gitattributes files to repo root", "Include docs zip in the publish process", "Use 18.2 instead of 18.2.1", "Integer.digits/2 & Integer.undigits changes (#4868)", "Small fixes in comments and documentation (#4744)", "Add Elixir Forum to list of help channels (#5121)", "Copyright requires just the starting year", "Properly check for earlier Erlang versions, closes#5090", "Add missing NOTICE file", "Add link to security mailing list", "Start v1.4.0-dev", "Start v1.4.0-dev", "Update rebar to rebar 2.1.0-pre. This (among other things) fixes a cr…", "Use proper case for proper nouns and acronyms", "Rebar3 dependency support"]
エラー処理とか全くしてない状態なので、今度はその辺突っ込んでみようかと。
- 作者: Dave Thomas,笹田耕一,鳥井雪
- 出版社/メーカー: オーム社
- 発売日: 2016/08/19
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る