8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Crawlyを試してみる(Elixir)

Last updated at Posted at 2020-06-20

はじめに

elixir         1.10.3-otp-23
erlang         23.0.1

What is Crawly ?

Crawly, a high-level web crawling & scraping framework for Elixir.

クローラーに必要なこと全部入りライブラリというところでしょうか。

セッションの中では以下の内容を熱っぽく語られていました。

  • 他言語製のなにかにインスパイアを受けてElixirでつくっちゃおう
  • ドキュメントを充実させる
  • 電池入ではめ込んですぐにでも使えるもの
  • Robots.txtに従ったり、JavaScriptのコンテンツをいい感じ(!?)にしたり
  • アクセスの都度User-Agentを変えたりする
  • を作りました!

0. 準備

  • Elixirをインストールしましょう
  • 手前味噌ですがインストールなどを参考にしてください

1. プロジェクトをつくってREADME等に書いてあることをそのまま写します

  • まずプロジェクトをつくります
$ mix new crawly_example --sup
$ cd crawly_example
  • 次に依存関係を解決します
mix.exs
  defp deps do
    [
      {:crawly, "~> 0.10.0"},
      {:floki, "~> 0.26.0"}
    ]
  end
$ mix deps.get
  • サンプルモジュールを写します
  • 作者 さんがErlang Solutionsの中の人のようで、スクレイピングするサイトはサンプルをそのまま使わせてもらいます
lib/crawly_example/esl_spider.ex
defmodule EslSpider do
  use Crawly.Spider

  alias Crawly.Utils

  @impl Crawly.Spider
  def base_url(), do: "https://www.erlang-solutions.com"

  @impl Crawly.Spider
  def init(), do: [start_urls: ["https://www.erlang-solutions.com/blog.html"]]

  @impl Crawly.Spider
  def parse_item(response) do
    {:ok, document} = Floki.parse_document(response.body)
    hrefs = document |> Floki.find("a.more") |> Floki.attribute("href")

    requests =
      Utils.build_absolute_urls(hrefs, base_url())
      |> Utils.requests_from_urls()

    title = document |> Floki.find("article.blog_post h1") |> Floki.text()

    %{
      :requests => requests,
      :items => [%{title: title, url: response.request_url}]
    }
  end
end
config/config.exs
use Mix.Config

config :crawly,
  middlewares: [
    {Crawly.Middlewares.UserAgent,
     user_agents: ["Crawly Bot", "Crawly Bot 1.0", "Crawly Bot 2.0", "Awesome Bot"]}
  ],
  pipelines: [
    Crawly.Pipelines.JSONEncoder,
    {Crawly.Pipelines.WriteToFile, folder: "/tmp", extension: "jl"}
  ]

2. 実行

  • 動かしてみましょう
$ iex -S mix
iex> Crawly.Engine.start_spider(EslSpider)

3. 結果確認

$ cat /tmp/EslSpider_2020_06_20_00_42_16_073891.jl
{"url":"https://www.erlang-solutions.com/blog.html","title":""}
{"url":"https://www.erlang-solutions.com/blog/welcome-to-our-new-blog.html","title":"Welcome to our new blog!!"}
{"url":"https://www.erlang-solutions.com/blog/mongooseim-1-6-1-is-released.html","title":"MongooseIM 1.6.1 is releasedMongooseIM 1.6.1 is released"}
{"url":"https://www.erlang-solutions.com/blog/secure-shell-for-your-erlang-node.html","title":"Secure Shell for Your Erlang NodeSecure Shell for Your Erlang NodeStarting upWrapping in an application"}
{"url":"https://www.erlang-solutions.com/blog/mongooseim-1-6-riak-devops-love-and-so-much-more.html","title":"MongooseIM 1.6: Riak, DevOps love, and so much more!"}
{"url":"https://www.erlang-solutions.com/blog.html","title":""}
{"url":"https://www.erlang-solutions.com/blog/welcome-to-our-new-blog.html","title":"Welcome to our new blog!!"}
  • EslSpider.parse_itemの結果のitemsに指定した形のものがファイルに書き出されるようです

  • ファイル名の日時のところは適宜読み替えてください

その他

  • Use-Agentをランダムに切り替える処理は、たぶんココ

Wrapping Up

  • Enjoy!!!
iex> [87, 101, 32, 97, 114, 101, 32, 116, 104, 101, 32, 65, 108, 99, 104, 101, 109, 105, 115, 116, 115, 44, 32, 109, 121, 32, 102, 114, 105, 101, 110, 100, 115, 33]
8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?