如何使用 Elixir 开始网络抓取的终极指南
Suciu Dan,2022 年 10 月 18 日
导言
网络搜刮是从论坛、社交媒体网站、新闻网站、电子商务平台等公开网站中提取数据的过程。本文将介绍如何在 Elixir 中创建 Web scraper,让您先睹为快。
如果您还不清楚网络搜刮的定义,那么让我们把从网站上保存图片视为手动网络搜刮。如果要手工保存网站上的所有图片,根据网站的复杂程度,可能需要几个小时甚至几天的时间。
您可以通过构建网络搜刮器来自动完成这一过程。
也许你想知道网络刮刀有哪些用途。以下是常见的几种情况:
新闻追踪
您可以从最喜欢的财经新闻网站上获取最新消息,运行情绪分析算法,并在市场开始和变动前几分钟就知道该投资什么。
社交媒体洞察
您可以从社交媒体页面上抓取评论,分析用户在谈论什么以及他们对产品或服务的感受。
价格监控
如果你热衷于收集游戏机和视频游戏,但又不想花大价钱购买最新的 PS5,你可以制作一个网络搜索器,检索 eBay 上的列表,并在廉价游戏机上市时向你发送通知。
机器学习培训
如果你想创建一个能识别任何图片中猫的品种的移动应用程序,你需要大量的训练数据;与其手动保存成百上千张猫的图片来训练模型,你可以使用网络搜刮工具来自动完成。
我们将使用 Elixir 构建网络刮擦程序,Elixir 是一种基于 Erlang 的编程语言,由 Ruby on Rails 团队核心成员何塞-瓦利姆(José Valim)创建。该编程语言借鉴了 Ruby 语法的简洁性,并将其与 Erlang 构建低延迟、分布式和容错系统的能力相结合。
要求
在编写第一行代码之前,请确保您的计算机上安装了 Elixir。下载适用于您操作系统的安装程序,并按照安装页面的说明进行操作。
在安装过程中,你会发现 Erlang 编程语言也是必需的。请记住,Elixir 在 Erlang 虚拟机中运行,因此两者都需要。
开始
在本文中,您将学习如何在 Elixir 中创建一个网络搜刮器,从 eBay 搜刮产品的 PS5 列表,并将提取的数据(名称、url、价格)存储到本地。
检查目标
是时候检查 eBay 页面上的搜索结果并收集一些选择器了。
访问 ebay.com,在 "搜索 "输入框中输入 PS5 并点击 "搜索 "按钮。加载搜索结果页面后,打开浏览器中的检查工具(右键单击页面上的任意位置并选择检查)。
您需要收集以下选择器:
- 产品清单 项目
- 产品网址
- 产品名称
- 产品价格
使用选择元素工具,搜索产品项目列表 (ul) 和产品项目 (li):

利用这两个元素,就可以提取出爬虫提取数据所需的类:
- .srp-results .s-item 产品列表元素 (ul) 的子元素
- .s-item__title span 产品标题
- .s-item__link 产品链接
- .s-item__price 产品价格
创建项目
让我们使用 mix 命令创建一个 Elixir 项目:
mix new elixir_spider --sup
--sup标志会生成一个包含监督树的 OTP 应用程序骨架,这是管理多个并发进程(如爬虫)的应用程序所需的功能。
创建临时文件夹
将当前目录更改为项目根目录:
cd elixir_spider
创建临时目录:
mkdir temp
我们使用该目录来存储搜刮到的项目。
添加依赖项
创建项目后,需要添加两个依赖项:
打开 mix.exs 文件,在 deps 块中添加依赖项:
defp deps do
[
{:crawly, "~> 0.14.0"},
{:floki, "~> 0.33.1"}
]
end
运行此命令获取依赖项:
mix deps.get
创建配置
创建 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: ["Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0"]}
],
pipelines: [
{Crawly.Pipelines.Validate, fields: [:url, :title, :price]},
{Crawly.Pipelines.DuplicatesFilter, item_id: :title},
Crawly.Pipelines.JSONEncoder,
{Crawly.Pipelines.WriteToFile, extension: "jl", folder: "./temp"}
]
一般选项
让我们对每处房产进行一番了解:
- closeespider_timeout:整数,蜘蛛保持打开状态的最长秒数
- concurrent_requests_per_domain(每个域的并发请求数):每个刮擦域的最大请求数
- closespider_itemcount:项目流水线传递的最大项目数
用户代理
通过设置用户代理,你可以模仿真实的浏览器来提高搜索结果。网站对刮擦者并不满意,会试图阻止任何看起来不真实的用户代理。你可以使用这样的工具来获取你的浏览器用户代理。
WebScrapingAPI会在每次请求时轮换用户代理和 IP 地址,并实施无数的规避措施来防止此类情况的发生。您的请求不会被阻止,而重试机制的实施会给您带来亚马逊式的结果。
管道
管道是自上而下处理的命令,可以对处理过的项目进行操作。我们使用以下管道:
- 验证字段(标题、价格、url):检查项目是否设置了刮擦字段
- 重复过滤器:按标题检查重复项目
- JSON 编码器:将结构编码为 JSON 对象
- 写入文件:将项目写入 ./temp 文件夹
创建蜘蛛
网络爬虫(或称蜘蛛)是一种机器人,它通过 CSS 选择器,使用用户定义的字段浏览网站并提取数据。爬虫可以提取页面上的所有链接,并使用特定链接(如分页链接)抓取更多数据。
现在是设置爬虫基础的时候了:在 lib/elixir_spider 文件夹中创建 ebay_scraper.ex 文件,并粘贴以下代码:
# lib/elixir_spider/ebay.ex
defmodule EbayScraper do
use Crawly.Spider
@impl Crawly.Spider
def base_url(), do:""
@impl Crawly.Spider
def init() do
end
@impl Crawly.Spider
def parse_item(response) do
end
end
这只是文件的骨架,不会运行或返回任何结果。让我们先谈谈每个函数,然后再逐一填写。
base_url()函数只调用一次,它会返回爬虫将抓取的目标网站的基本 URL;它还用于过滤外部链接,防止爬虫跟踪这些链接。我们并不想抓取整个互联网,因此,我们需要一个 "base_url "函数。
@impl Crawly.Spider
def base_url(), do:"https://www.ebay.com/"
init()函数会被调用一次,用于初始化爬虫的默认状态;在这种情况下,该函数会返回开始抓取的 start_url。
用这个功能替换您的空白功能:
@impl Crawly.Spider
def init() do
[start_urls:["https://www.ebay.com/sch/i.html?_nkw=ps5"]]
end
所有神奇的数据提取都发生在parse_item()函数中。我们会为每个获取的 URL 调用该函数。在这个函数中,我们使用 Floki HTML 解析器来提取我们需要的字段:标题、URL 和价格。
函数将如下所示:
@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(".srp-results .s-item")
|> Enum.map(fn x ->
%{
title: Floki.find(x, ".s-item__title span") |> Floki.text(),
price: Floki.find(x, ".s-item__price") |> Floki.text(),
url: Floki.find(x, ".s-item__link") |> Floki.attribute("href") |> Floki.text(),
}
end)
%{items: items}
end
您可能已经注意到,我们正在使用 "入门--检查目标 "部分中的类,从 DOM 元素中提取我们需要的数据。
运行蜘蛛
现在是测试代码并确保其正常运行的时候了。在项目根目录下运行以下命令:
iex -S mix run -e "Crawly.Engine.start_spider(EbayScraper)"
如果使用 PowerShell,请确保将 iex 替换为 iex.bat,否则会因 -S 参数不存在而出错。在 PowerShell 中使用此命令:
iex.bat -S mix run -e "Crawly.Engine.start_spider(EbayScraper)"
检查结果
打开 ./temp 文件夹,检查 .jl 文件。你会看到一个文本文件,其中包含一个 JSON 对象列表,每行一个。每个对象都包含我们需要的 eBay 产品列表信息:标题、价格和 URL。
下面是产品对象的外观:
{"url":"https://www.ebay.com/itm/204096893295?epid=19040936896&hash=item2f851f716f:g:3G8AAOSwNslhoSZW&amdata=enc%3AAQAHAAAA0Nq2ODU0vEdnTBtnKgiVKIcOMvqJDPem%2BrNHrG4nsY9c3Ny1bzsybI0zClPHX1w4URLWSfXWX%2FeKXpdgpOe%2BF8IO%2FCh77%2FycTnMxDQNr5JfvTQZTF4%2Fu450uJ3RC7c%2B9ze0JHQ%2BWrbWP4yvDJnsTTWmjSONi2Cw71QMP6BnpfHBkn2mNzJ7j3Y1%2FSTIqcZ%2F8akkVNhUT0SQN7%2FBD38ue9kiUNDw9YDTUI1PhY14VbXB6ZMWZkN4hCt6gCDCl5mM7ZRpfYiDaVjaWVCbxUIm3rIg%3D%7Ctkp%3ABFBMwpvFwvRg","title":"PS5 Sony PlayStation 5 Console Disc Version! US VERSION!","price":"$669.99"}
改进蜘蛛
我们从第一个产品列表页面提取了所有产品,但这还不够。现在应该实施分页,让爬虫提取所有可用的产品。
让我们更改parse_item()函数,并添加一个新代码块,创建一个包含下一个分页链接的请求结构。将此代码添加到 items 代码之后:
# 提取下一页链接并将其转换为请求
requests =
document
|> Floki.find(".s-pagination a.pagination__next")
|> Floki.attribute("href")
|> Crawly.Utils.build_absolute_urls(response.request_url)
|> Crawly.Utils.requests_from_urls()
更新parse_item()函数的返回语句,使其也包含下一个请求。结构将如下所示
%{
:requests => requests,
:items => items
}
再次运行爬虫,但这次要准备一杯咖啡。搜索 PS5 列表的所有页面需要几分钟时间。
爬虫完成任务后,检查 ./temp 文件夹中的搜索结果。您已成功在 eBay 上搜索到 PS5 游戏机,并获得了一份包含其价格的清单。您可以扩展此爬虫,搜索其他产品。
结论
在这篇文章中,你将了解到什么是网络爬虫、这些爬虫有哪些用例、如何使用已有库在几分钟内使用 Elixir 设置一个爬虫,以及如何运行和提取实际数据。
如果你觉得工作量很大,我想告诉你一个不太好的消息:我们只是做了表面文章。长时间运行这个刮板,会引发你想不到的问题。
eBay 会检测到您的活动并将其标记为可疑活动;爬虫会开始获取验证码补丁;您必须扩展爬虫功能以解决验证码问题
eBay 的检测系统可能会标记你的 IP 地址并阻止你访问网站;你必须使用代理池并在每次请求时轮换 IP 地址。
是不是已经头晕目眩了?让我们再讨论一个问题:用户代理。你需要建立一个包含用户代理的大型数据库,并在每次请求时轮换该值。检测系统会根据 IP 地址和用户代理拦截搜索器。
如果你想把更多精力放在业务方面,把时间投入到数据提取而不是解决检测问题上,那么使用刮板作为服务是更好的选择。像WebScrapingAPI这样的解决方案可以解决上述所有问题,还能解决更多问题。
新闻和更新
订阅我们的时事通讯,了解最新的网络搜索指南和新闻。
We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

相关文章

探索 Scrapy 和 Selenium 在网络刮擦方面的深入比较。从大规模数据采集到处理动态内容,了解两者的优缺点和独特功能。了解如何根据项目需求和规模选择最佳框架。


学习如何使用 Scrapy 和 Splash 抓取 JavaScript 渲染的动态网站。从安装到编写 spider、处理分页和管理 Splash 响应,本综合指南为初学者和专家提供了循序渐进的指导。


