Elixir 网络抓取指南

2026 年的 Elixir 网页抓取:完整指南

在本指南中,我将指导您使用 Elixir 用于网页抓取。我们会讲解基础内容——环境搭建、必备工具和最佳实践。我还会介绍如何从分页页面和 JavaScript 渲染页面抓取数据。来看看为什么 Elixir 正在成为网页抓取的首选之一!

为什么选择 Elixir 进行网络抓取?

Elixir 的优势在于其可扩展性和并发性。基于 Erlang 虚拟机(BEAM)Elixir 可以处理数百万个轻量级进程,每个进程的开销最小。这使得 Elixir 非常适合处理需要并行处理多个请求的任务,例如对内容分页的网站进行搜索。Elixir 的语法和工具生态系统使其易于使用,即使是初学函数式编程的开发人员也能轻松上手。

考虑将 Elixir 用于网络刮擦的主要原因包括

  1. 并发性和可扩展性 Elixir 可以并发处理多个请求,而不会降低速度或内存效率,因此非常适合搜索多个页面或网站。
  2. 可靠性: BEAM 的 "让它崩溃 "理念实现了优美的故障处理,这意味着如果进程崩溃,你的刮板可以自我恢复。
  3. 容错: Elixir 内置的监督树和弹性架构意味着应用程序可以从意外问题中恢复,而不会中断整个刮擦操作。

Elixir 的最佳自动化替代方案

如果您对刮擦不感兴趣,只想获得数据,请查看以下内容 数据集网站:

  1. Bright Data - 可定制和预建的跨行业数据集。
  2. Statista - 用于商业和研究的大量统计数据和报告。
  3. Datarade - 来自不同供应商的优质数据产品市场。
  4. AWS Data Exchange - 与 AWS 服务集成的第三方数据集。
  5. Zyte — 面向业务需求定制的网页抓取以及数据集。
  6. 数据与儿子 - 买卖各种数据集的开放市场。
  7. Coresignal - 劳动力分析,提供大量与工作相关的数据。
  8. Oxylabs - 专业的公司数据和网络搜索服务。
  9. 彭博企业数据目录 - 供企业使用的财务数据。
  10. Kaggle - 用于数据科学的免费公共数据集和工具。

有些是免费的,有些不是,有些提供免费样品。请根据自己的需要进行选择。我与其中任何一家都没有任何关系。

设置 Elixir 网络抓取环境

要开始在 Elixir 中进行网页抓取,你需要先设置一个 Elixir 项目,并添加两个主要库: Crawly 和 Floki.

  1. Crawly 是一个功能强大的抓取框架,它模仿了 Scrapy 的结构和功能,Scrapy 是 Python 最流行的网络抓取库之一。它提供了基本的抓取组件,包括蜘蛛、管道和中间件。
  2. Floki 是一款适用于 Elixir 的直接 HTML 解析器。它允许你使用 CSS 选择器从 HTML 文档中定位和检索特定元素。

步骤 1:设置 Elixir 项目

首先,安装 Elixir(如果你使用的是 Windows,还要安装 Erlang),然后创建一个新的 Elixir 项目:

mix new elixir_scraper - sup

该命令将初始化一个名为 elixir_scraper 的新监督项目。

步骤 2:添加依赖关系

在 mix.exs 文件中,将 Crawly 和 Floki 添加为依赖项:

defp deps do
[
{:crawly, "~> 0.16.0"},
{:floki, "~> 0.33.0"}
]
end
然后,安装 libraries:
mix deps.get

现在,您的 Elixir 项目已准备就绪,可以进行网络爬取了。

用 Crawly 构建简单的 Elixir 蜘蛛

Crawly spider 本质上是一个 Elixir 模块,它定义了如何从目标网站检索和解析数据。在本例中,我们将创建一个蜘蛛,从模拟电子商务网站 ScrapingCourse.com 抓取数据。

步骤 1:创建蜘蛛

使用以下命令生成一只爬行蜘蛛:

mix crawly.gen.spider - filepath ./lib/scrapingcourse_spider.ex - spidername ScrapingcourseSpider

这会在 lib 目录中创建一个名为 scrapingcourse_spider.ex 的文件。以下是初始代码的样子:

defmodule ScrapingcourseSpider do
use Crawly.Spider
@impl Crawly.Spider
def base_url(), do: "https://www.scrapingcourse.com/ecommerce/"
@impl Crawly.Spider
def init() do
[start_urls:["https://www.scrapingcourse.com/ecommerce/"]]
end
@impl Crawly.Spider
def parse_item(response) do
{:ok, document} = Floki.parse_document(response.body)
product_items =
document
|> Floki.find("li.product")
|> Enum.map(fn x ->)
%{
url:Floki.find(x, "a.woocommerce-LoopProduct-link)|> Floki.attribute("href")|> Floki.text()、
name: Floki.find(x, "h2.woocommerce-loop-product__title") |> Floki.text(),
image: Floki.find(x, "img.attachment-woocommerce_thumbnail")|> Floki.attribute("src") |> Floki.text(),
price: Floki.find(x, "span.price")|> Floki.text()
}
end)
%Crawly.ParsedItem{items: product_items}
end
end

这段代码定义了一个 ScrapingcourseSpider 模块,它:

  • 目标是 ScrapingCourse.com 网站。
  • 使用 CSS 选择器提取产品名称、价格、图片和 URL 等数据。

步骤 2:运行蜘蛛

要执行蜘蛛,请运行以下命令:

iex -S mix run -e "Crawly.Engine.start_spider(ScrapingcourseSpider)"

您的刮擦工具应记录提取的每个项目,为目标网站的数据结构提供有价值的见解。

将抓取的数据导出为 CSV

要把抓取的数据存入 CSV 文件,请将管道配置为包含 Crawly 的 CSVEncoder:

import Config
config :crawly,
middlewares: [],
pipelines: [
{Crawly.Pipelines.CSVEncoder、 fields: [:url, :name, :image, :价格]},
{Crawly.Pipelines.WriteToFile、 extension: "csv", folder: "output"}
]

再次运行蜘蛛程序,Crawly 就会在输出文件夹中输出包含所需数据字段的 CSV 文件。

处理分页页面

许多网站将数据分布在多个页面上。要处理分页问题,请检查目标网站的导航元素,并配置您的蜘蛛来跟踪其他页面。

例如,抓取分页的产品列表:

识别 CSS 选择器 用于分页链接(如 a.page-numbers)。

使用 Floki 提取每个页面的 URL 并将其添加到 Crawly 的 next_requests 数组中。

def parse_item(response) do
{:ok, document} = Floki.parse_document(response.body)
product_items = # parse products…
next_requests =
document
|> Floki.find("a.page-numbers")
|> Floki.attribute("href")
|> Enum.map(&Crawly.Utils.request_from_url/1)
%Crawly.ParsedItem{items: product_items, requests: next_requests}
end

这样设置后,Crawly 就能跟踪每个分页链接,确保刮取所有产品。

处理 JavaScript 渲染的内容

Elixir 和许多语言一样,无法在 HTTP 响应中原生执行 JavaScript。不过,你可以集成 Splash Splash(一个无头浏览器)来处理由 JavaScript 渲染的页面。Splash 在服务端渲染内容,为 Elixir 提供完整的 HTML 文档,包括由 JavaScript 生成的元素。

步骤 1:设置 Splash

Splash 可以作为 Docker 容器运行。拉取并运行 Splash 镜像:

docker pull scrapinghub/splash docker run -it -p 8050:8050 - rm scrapinghub/splash

步骤 2:配置 Crawly 以使用 Splash

在 config.exs 文件中,配置 Crawly 通过 Splash 抓取页面:

import Config
config :crawly,
fetcher: {Crawly.Fetchers.Splash, [base_url: "http://localhost:8050/render.html", wait: 3]}

此配置确保 Crawly 通过 Splash 获取数据,从而能够处理 JavaScript 渲染的内容。现在,当你的爬虫发起请求时,Splash 会处理任何 JavaScript,并将渲染后的 HTML 发送给 Elixir。

使用代理和用户代理避免阻塞

许多网站都采取了反僵尸措施,可以阻止来自单一 IP 的重复请求。你可以通过轮换用户代理和使用代理服务器来减少这些阻止。

轮换用户代理: 添加 Crawly.Middlewares.UserAgent 中间件以旋转用户代理:

config :crawly,
middlewares: [
{Crawly.Middlewares.UserAgent, user_agents: [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36",
]}
]

使用代理服务器 使用代理伪装你的 IP,提升爬虫对封禁的抗性。

config :crawly,
middlewares: [
{Crawly.Middlewares.RequestOptions, [proxy: {"http://proxyaddress.com", 8000}]}
]

高级 Elixir 网络抓取技术

有了 Elixir,您就可以将刮擦技术更进一步,通过额外的配置和先进的技术提高性能。

并行请求: Crawly 允许并发请求,以加快数据收集速度。在 config.exs 中将 concurrent_requests_per_domain 设置为更高值。

config :crawly、
concurrent_requests_per_domain:4

错误处理: Crawly 的错误处理功能允许在刮擦遇到问题时进行优美的恢复,确保以最少的中断时间提取最多的数据。

结论

Elixir 是网页抓取的一个强力选择,主要因为它可以并发处理任务,并在高负载下保持稳定。Crawly 和 Floki 这类库让上手变得很容易,为从基础配置到更复杂任务都提供了强大的工具,例如处理分页、抓取由 JavaScript 渲染的页面,以及规避拦截。

网络抓取正朝着更加分布式、耐用的设置方向发展,而 Elixir 的功能风格和强大的处理能力非常适合。如果你正在探索更大规模的数据提取,Elixir 是一个可靠的选择,它能满足现代的刮擦需求。

类似文章