需同时添加 floki 依赖用于解析 HTML;管理 UI 默认占用 localhost:4001,可用 start_http_api?: false 关闭;浏览器渲染需额外配置,README 未给出具体步骤
mix new quickstart --sup
# 在 mix.exs 加入 {:crawly, "~> 0.17.2"} 和 {:floki, "~> 0.33.0"} 后执行:
mix deps.get
iex -S mix run -e "Crawly.Engine.start_spider(BooksToScrape)"README 未说明硬件要求,仅要求 Elixir ~> 1.14,支持 GNU/Linux、Windows、macOS X 和 BSD
Elixir 编写的高层网页爬取与结构化数据抽取框架,适合做数据挖掘与归档
基于 Elixir 的高层网页爬取与抓取框架,用并发和容错能力帮你快速搭建爬虫、批量提取网页数据。
核心能力
- 用 Crawly.Spider 回调定义 base_url、init 和 parse_item
- 内置 DomainFilter、UniqueRequest、UserAgent 等中间件
- 用 Pipeline 做字段校验、去重、JSON 编码和写文件
- 默认在 localhost:4001 提供管理 UI 与 REST API
- 可配置浏览器渲染抓取 AJAX 异步页面
容易踩的坑
- 0.15.00.15.0 Release最新正式版2023-04-11 · 2023-04-11 08:16 UTC
What's Changed
- Created a simple management Web UI. Try it on localhost:4001
- Added the possibility of creating spiders with the help of the YML format. Read more here: https://github.com/elixir-crawly/crawly/blob/master/documentation/spiders_in_yml.md
- Added the possibility to run Crawly (and your scraping projects) without Elixir. Read more here: https://github.com/elixir-crawly/crawly/blob/master/documentation/standalone_crawly.md
- Added generators for Crawly spiders and configuration files to reduce boilerplate
- Improved UniqueRequest middleware so that it can store hashes instead of complete URLs (special thanks to @serpent213)
- Added SameDomainFilter middleware, my favorite, which will probably deprecate the need to rely on the base_url in the future. Again thanks to @serpent213!
- 0.13.0Release 0.13.02021-02-05 · 2021-02-05 20:22 UTC
查看更新说明
- Bugfix for start_urls size (now it's possible to have very large start URLs)
- Split business logs from other logs. Per spider logging
- Send logs to CrawlyUI (optional)
- Allow to override more spider options:
- closespider_itemcount
- closespider_timeout
- concurrent_requests_per_domain (number of started workers)
- Change on_spider_log_callback (now it also gets the crawl_id)
- Parse pipelines
- 0.12.02020-11-16 · 2020-11-16 20:01 UTC
这个版本没有写更新说明。
- 0.11.0Release 0.11.02020-10-07 · 2020-10-07 08:26 UTC
这个版本没有写更新说明。
- 0.10.0Release 0.10.02020-05-18 · 2020-05-18 09:27 UTC
查看更新说明
The release includes the following improvements:
- WriteToFile pipeline now adds timestamps to filenames
- WriteToFile pipeline will now create a folder if missing
- SendToUI item pipeline will send data to experimental CrawlyUI management dashboard
- Other smaller features
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Crawly
Overview
Crawly is an application framework for crawling web sites and extracting structured data which can be used for a wide range of useful applications, like data mining, information processing or historical archival.
Requirements
- Elixir
~> 1.14 - Works on GNU/Linux, Windows, macOS X, and BSD.
Quickstart
-
Create a new project:
mix new quickstart --sup -
Add Crawly as a dependencies:
# mix.exs defp deps do [ {:crawly, "~> 0.17.2"}, {:floki, "~> 0.33.0"} ] end -
Fetch dependencies:
$ mix deps.get -
Create a spider
# lib/crawly_example/books_to_scrape.ex defmodule BooksToScrape do use Crawly.Spider @impl Crawly.Spider def base_url(), do: "https://books.toscrape.com/" @impl Crawly.Spider def init() do [start_urls: ["https://books.toscrape.com/"]] end @impl Crawly.Spider def parse_item(response) do # Parse response body to document {:ok, document} = Floki.parse_document(response.body) # Create item (for pages where items exists) items = document |> Floki.find(".product_pod") |> Enum.map(fn x -> %{ title: Floki.find(x, "h3 a") |> Floki.attribute("title") |> Floki.text(), price: Floki.find(x, ".product_price .price_color") |> Floki.text(), url: response.request_url } end) next_requests = document |> Floki.find(".next a") |> Floki.attribute("href") |> Enum.map(fn url -> Crawly.Utils.build_absolute_url(url, response.request.url) |> Crawly.Utils.request_from_url() end) %Crawly.ParsedItem{items: items, requests: next_requests} end endNew in 0.15.0 :
It's possible to use the command to speed up the spider creation, so you will have a generated file with all needed callbacks:
mix crawly.gen.spider --filepath ./lib/crawly_example/books_to_scrape.ex --spidername BooksToScrape -
Configure Crawly
By default, Crawly does not require any configuration. But obviously you will need a configuration for fine tuning the crawls: (in file:
config/config.exs)import Config config :crawly, closespider_timeout: 10, concurrent_requests_per_domain: 8, closespider_itemcount: 100, middlewares: [ Crawly.Middlewares.DomainFilter, Crawly.Middlewares.UniqueRequest, {Crawly.Middlewares.UserAgent, user_agents: ["Crawly Bot"]} ], pipelines: [ {Crawly.Pipelines.Validate, fields: [:url, :title, :price]}, {Crawly.Pipelines.DuplicatesFilter, item_id: :title}, Crawly.Pipelines.JSONEncoder, {Crawly.Pipelines.WriteToFile, extension: "jl", folder: "/tmp"} ]New in 0.15.0:
You can generate example config with the help of the following command:
mix crawly.gen.config -
Start the Crawl:
iex -S mix run -e "Crawly.Engine.start_spider(BooksToScrape)" -
Results can be seen with:
$ cat /tmp/BooksToScrape_<timestamp>.jl
Running Crawly without Elixir or Elixir projects
It's possible to run Crawly in a standalone mode, when Crawly is running as a tiny docker container, and spiders are just YMLfiles or elixir modules that are mounted inside.
Please read more about it here:
Need more help?
Please use discussions for all conversations related to the project
Browser rendering
Crawly can be configured in the way that all fetched pages will be browser rendered, which can be very useful if you need to extract data from pages which has lots of asynchronous elements (for example parts loaded by AJAX).
You can read more here:
Simple management UI (New in 0.15.0) {#management-ui}
Crawly provides a simple management UI by default on the localhost:4001
It allows to:
- Start spiders
- Stop spiders
- Preview scheduled requests
- View/Download items extracted
- View/Download logs
NOTE: It's possible to disable the Simple management UI (and rest API) with the
start_http_api?: false options of Crawly configuration.
You can choose to run the management UI as a plug in your application.
defmodule MyApp.Router do
use Plug.Router
...
forward "/admin", Crawly.API.Router
...
end

Experimental UI [Deprecated]
Now don't have a possibility to work on experimental UI built with Phoenix and LiveViews, and keeping it here for mainly demo purposes.
The CrawlyUI project is an add-on that aims to provide an interface for managing and rapidly developing spiders. Checkout the code from GitHub
Documentation
Roadmap
To be discussed
Articles
- Blog post on Erlang Solutions website: https://www.erlang-solutions.com/blog/web-scraping-with-elixir.html
- Blog post about using Crawly inside a machine learning project with Tensorflow (Tensorflex): https://www.erlang-solutions.com/blog/how-to-build-a-machine-learning-project-in-elixir.html
- Web scraping with Crawly and Elixir. Browser rendering: https://medium.com/@oltarasenko/web-scraping-with-elixir-and-crawly-browser-rendering-afcaacf954e8
- Web scraping with Elixir and Crawly. Extracting data behind authentication: https://oltarasenko.medium.com/web-scraping-with-elixir-and-crawly-extracting-data-behind-authentication-a52584e9cf13
- What is web scraping, and why you might want to use it?
- Using Elixir and Crawly for price monitoring
- Building a Chrome-based fetcher for Crawly
Example projects
- Blog crawler: https://github.com/oltarasenko/crawly-spider-example
- E-commerce websites: https://github.com/oltarasenko/products-advisor
- Car shops: https://github.com/oltarasenko/crawly-cars
- JavaScript based website (Splash example): https://github.com/oltarasenko/autosites
Contributors
We would gladly accept your contributions!
Documentation
Please find documentation on the HexDocs
Production usages
Using Crawly on production? Please let us know about your case!
Copyright and License
Copyright (c) 2019 Oleg Tarasenko
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
How to release:
- Update version in mix.exs
- Update version in quickstart (README.md, this file)
- Commit and create a new tag:
git commit && git tag 0.xx.0 && git push origin master --follow-tags - Build docs:
mix docs - Publish hex release:
mix hex.publish