undefined

bokuweb.me

Elixir + Phantomjsでスクレイピングしてスクリーンショットとニュースの見出しをとる

Elixir関連の記事を眺めていたら以下の記事を見つけた。面白そうなので試してみる。

Scraping a Website with Elixir – Robert Lord

core.garbage-collection.net

基本的には上記の記事に沿う。

PhantomJSのインストール

npm --save phantomjs

pakcage.jsonrun scriptを追加。

...(省略)
  "scripts": {
    "phantomjs": "phantomjs --webdriver=5555",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
...(省略)

プロジェクトの作成

mix new elixir_scraping_sample

mix.exsHoundを追加。最新は0.7.6。(0.7.2を使っているとタイムアウトでちょくちょく失敗した。)

defmodule ElixirScrapingSample.Mixfile do
  use Mix.Project

  def project do
    [app: :elixir_scraping_sample,
     version: "0.0.1",
     elixir: "~> 1.1",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     deps: deps]
  end

  # Configuration for the OTP application
  #
  # Type "mix help compile.app" for more information
  def application do
    [applications: [:logger, :hound]]
  end

  defp deps do
    [
      {:hound, "~> 0.7.6"}
    ]
  end
end

ライブラリをインストール

mix deps.get

Houndとは?

ブラウザの自動化ができるっぽい。

Features
* Can run multiple browser sessions simultaneously. See example.
* Supports Selenium (Firefox, Chrome), ChromeDriver and PhantomJs.
* Supports Javascript-heavy apps. Retries a few times before reporting error.
* Implements the WebDriver Wire Protocol.

README – hound v0.7.6

スクレイピングするコード

以下でyahoo.co.jpにアクセスし、ページタイトル、ニュースの見出し、スクリーンショットを取得する。 find_elementfind_all_within_elementなどで要素を取得し、visible_textでテキストを取得している。 セレクタのストラテジには次を指定できる。:css, :class, :id, :name, :tag, :xpath, :link_text, :partial_link_text

  • lib/elixir_scraping_sample.ex
defmodule ElixirScrapingSample do
  use Hound.Helpers

  def start do
    url = "http://yahoo.co.jp"
    IO.puts "access to #{url} ..."
    Hound.start_session()
    navigate_to url
    IO.puts page_title()
    IO.inspect find_element(:class, "emphasis")
            |> find_all_within_element(:tag, "li")
            |> Enum.map(fn(x) -> visible_text x end)
    take_screenshot "screenshot-test.png"
  end
end

実行

npm run phantomjs
mix run -e ElixirScrapingSample.start
Compiled lib/elixir_scraping_sample.ex
Generated elixir_scraping_sample app
access to http://yahoo.co.jp ...
Yahoo! JAPAN
["指定廃棄物 福島が受け入れへ写真",
 "中絶施設で銃撃3人死亡 米写真",
 "RVRの開発部長 なぜ諭旨退職写真",
 "94歳が運転 90歳はね死なす動画NEW",
 "実習船で同級生から2カ月暴行NEW",
 "速報JリーグCS 浦和対G大阪写真LIVE",
 "内山信二 次の再ブレイク枠か写真",
 "桐谷美玲 知的路線で人気拡大写真NEW"]

スクリーンショット

f:id:bokuweb:20151128184416p:plain

以上です。なかなか良い。

github.com