crawly

elixir-crawlyApache-2.0长期未更新

基于 Elixir 的高层网页爬取与抓取框架,用并发和容错能力帮你快速搭建爬虫、批量提取网页数据。

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

0.15.0发布于 2023-04-11 08:16 UTC1,128star125fork同步于 2026-11-07 07:34 UTC

怎么上手

由 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 说明

README 未说明硬件要求,仅要求 Elixir ~> 1.14,支持 GNU/Linux、Windows、macOS X 和 BSD

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

Elixir 编写的高层网页爬取与结构化数据抽取框架,适合做数据挖掘与归档

基于 Elixir 的高层网页爬取与抓取框架,用并发和容错能力帮你快速搭建爬虫、批量提取网页数据。

核心能力

  • 用 Crawly.Spider 回调定义 base_url、init 和 parse_item
  • 内置 DomainFilter、UniqueRequest、UserAgent 等中间件
  • 用 Pipeline 做字段校验、去重、JSON 编码和写文件
  • 默认在 localhost:4001 提供管理 UI 与 REST API
  • 可配置浏览器渲染抓取 AJAX 异步页面

容易踩的坑

需同时添加 floki 依赖用于解析 HTML;管理 UI 默认占用 localhost:4001,可用 start_http_api?: false 关闭;浏览器渲染需额外配置,README 未给出具体步骤

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本0.15.0
  1. 0.15.00.15.0 Release最新正式版2023-04-11 · 2023-04-11 08:16 UTC

    What's Changed

    1. Created a simple management Web UI. Try it on localhost:4001
    2. 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
    3. 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
    4. Added generators for Crawly spiders and configuration files to reduce boilerplate
    5. Improved UniqueRequest middleware so that it can store hashes instead of complete URLs (special thanks to @serpent213)
    6. Added SameDomainFilter middleware, my favorite, which will probably deprecate the need to rely on the base_url in the future. Again thanks to @serpent213!
  2. 0.13.0Release 0.13.02021-02-05 · 2021-02-05 20:22 UTC
    查看更新说明
    1. Bugfix for start_urls size (now it's possible to have very large start URLs)
    2. Split business logs from other logs. Per spider logging
    3. Send logs to CrawlyUI (optional)
    4. Allow to override more spider options:
      • closespider_itemcount
      • closespider_timeout
      • concurrent_requests_per_domain (number of started workers)
    5. Change on_spider_log_callback (now it also gets the crawl_id)
    6. Parse pipelines
  3. 0.12.02020-11-16 · 2020-11-16 20:01 UTC

    这个版本没有写更新说明。

  4. 0.11.0Release 0.11.02020-10-07 · 2020-10-07 08:26 UTC

    这个版本没有写更新说明。

  5. 0.10.0Release 0.10.02020-05-18 · 2020-05-18 09:27 UTC
    查看更新说明

    The release includes the following improvements:

    1. WriteToFile pipeline now adds timestamps to filenames
    2. WriteToFile pipeline will now create a folder if missing
    3. SendToUI item pipeline will send data to experimental CrawlyUI management dashboard
    4. Other smaller features

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    Crawly

    Module Version Hex Docs Total Download License Last Updated

    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

    1. Elixir ~> 1.14
    2. Works on GNU/Linux, Windows, macOS X, and BSD.

    Quickstart

    1. Create a new project: mix new quickstart --sup

    2. Add Crawly as a dependencies:

      # mix.exs
      defp deps do
          [
            {:crawly, "~> 0.17.2"},
            {:floki, "~> 0.33.0"}
          ]
      end
      
    3. Fetch dependencies: $ mix deps.get

    4. 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
       end
      

      New 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

    5. 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

    6. Start the Crawl:

        iex -S mix run -e "Crawly.Engine.start_spider(BooksToScrape)"
      
    7. 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
    

    Crawly Management UI

    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

    1. Blog post on Erlang Solutions website: https://www.erlang-solutions.com/blog/web-scraping-with-elixir.html
    2. 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
    3. Web scraping with Crawly and Elixir. Browser rendering: https://medium.com/@oltarasenko/web-scraping-with-elixir-and-crawly-browser-rendering-afcaacf954e8
    4. 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
    5. What is web scraping, and why you might want to use it?
    6. Using Elixir and Crawly for price monitoring
    7. Building a Chrome-based fetcher for Crawly

    Example projects

    1. Blog crawler: https://github.com/oltarasenko/crawly-spider-example
    2. E-commerce websites: https://github.com/oltarasenko/products-advisor
    3. Car shops: https://github.com/oltarasenko/crawly-cars
    4. 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:

    1. Update version in mix.exs
    2. Update version in quickstart (README.md, this file)
    3. Commit and create a new tag: git commit && git tag 0.xx.0 && git push origin master --follow-tags
    4. Build docs: mix docs
    5. Publish hex release: mix hex.publish