Python и JavaScript доминируют во всей индустрии скрапбукинга. Если вам нужна производительность или переносимость, Scala предлагает сильную альтернативу. Scala дает нам компилируемую, переносимую и сильно типизированную основу для работы.
Сегодня мы рассмотрим, как скреативить с помощью Scala и jsoup. Хотя о нем пишут не так часто, как о веб-скрапинге на Python, Scala обеспечивает прочный фундамент и достойные инструменты для скрапинга.
Почему именно Scala?
Существует довольно много причин, по которым вы можете выбрать Scala вместо Python или JavaScript.
- Производительность: Scala компилируется в JVM (Java Virtual Machine). Компиляторы переводят наш код в исполняемый на машине байткод. Это делает его изначально более быстрым, чем Python.
- Статическая типизация: Проверка типов обеспечивает дополнительный уровень безопасности. Многие распространенные ошибки отлавливаются еще до запуска программы.
- Переносимость: Scala компилируется в байткод JVM (Java Virtual Machine). Байткод JVM может выполняться везде, где установлена Java.
- Полная совместимость с Java: Вы можете использовать зависимости Java в коде Scala. Это значительно расширяет доступную вам экосистему.
Начало работы
Прежде чем приступить к работе, необходимо убедиться, что у вас установлена Scala. Ниже мы приводим инструкции для Ubuntu, macOS и Windows.
Полную документацию по установке можно посмотреть здесь.
Ubuntu
curl -fL https://github.com/coursier/coursier/releases/latest/download/cs-x86_64-pc-linux.gz | gzip -d > cs && chmod +x cs && ./cs setup
macOS
brew install coursier && coursier setup
Windows
Загрузите программу установки Scala для Windows.
Создание скребка
Создайте новую папку проекта и перейдите в нее по cd
.
mkdir quote-scraper
cd quote-scraper
Инициализируйте новый проект Scala. Эта команда преобразует нашу новую папку в проект Scala и создает файл build.sbt
для хранения наших зависимостей.
sbt new scala/scala3.g8
Теперь откройте файл build.sbt
. Вам нужно будет добавить jsoup в качестве зависимости. Ваш полный файл сборки должен выглядеть следующим образом.
val scala3Version = "3.6.3"
lazy val root = project
.in(file("."))
.settings(
name := "quote-scraper",
version := "0.1.0-SNAPSHOT",
scalaVersion := scala3Version,
libraryDependencies += "org.scalameta" %% "munit" % "1.0.0" % Test,
libraryDependencies += "org.jsoup" % "jsoup" % "1.18.3"
)
Затем скопируйте и вставьте приведенный ниже код в файл Main.scala
.
import org.jsoup.Jsoup
import scala.jdk.CollectionConverters._
@main def QuotesScraper(): Unit =
val url = "http://quotes.toscrape.com"
try
val document = Jsoup.connect(url).get()
//find all objects on the page with the quote class
val quotes = document.select(".quote")
for quote <- quotes.asScala do
//find the first object with the class "text" and return its text
val text = quote.select(".text").text()
//find the first object with the class "author" and return its text
val author = quote.select(".author").text()
println(s"Quote: $text")
println(s"Author: $author")
println("-" * 50)
catch case e: Exception => println(s"Error: ${e.getMessage}")
Запуск скребка
Чтобы запустить наш скребок, выполните следующую команду из корня проекта.
sbt run
Вы должны увидеть результат, аналогичный приведенному ниже.
Quote: “The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”
Author: Albert Einstein
--------------------------------------------------
Quote: “It is our choices, Harry, that show what we truly are, far more than our abilities.”
Author: J.K. Rowling
--------------------------------------------------
Quote: “There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.”
Author: Albert Einstein
--------------------------------------------------
Quote: “The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.”
Author: Jane Austen
--------------------------------------------------
Quote: “Imperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.”
Author: Marilyn Monroe
--------------------------------------------------
Quote: “Try not to become a man of success. Rather become a man of value.”
Author: Albert Einstein
--------------------------------------------------
Quote: “It is better to be hated for what you are than to be loved for what you are not.”
Author: André Gide
--------------------------------------------------
Quote: “I have not failed. I've just found 10,000 ways that won't work.”
Author: Thomas A. Edison
--------------------------------------------------
Quote: “A woman is like a tea bag; you never know how strong it is until it's in hot water.”
Author: Eleanor Roosevelt
--------------------------------------------------
Quote: “A day without sunshine is like, you know, night.”
Author: Steve Martin
--------------------------------------------------
[success] Total time: 6 s, completed Feb 18, 2025, 8:58:04 PM
Выбор с помощью jsoup
Чтобы найти элементы страницы с помощью jsoup, мы используем метод select()
. select()
возвращает список всех элементов, соответствующих нашему селектору. Давайте посмотрим, как это работает в нашем проекте Quote Scraper.
В этой строке мы используем document.select(".quote")
, чтобы вернуть все элементы страницы с классом
quote
.
val quotes = document.select(".quote")
Мы также можем написать эти селекторы с большей структурой: element[attribute='some value']
. Это позволит нам применять более сильные фильтры при поиске объектов на странице.
Строка ниже все равно вернет те же объекты страницы, но она гораздо выразительнее.
val quotes = document.select("div[class='quote']")
Давайте рассмотрим еще несколько примеров использования select()
в нашем коде. Поскольку в каждой цитате есть только один текстовый
элемент и один автор
, select()
возвращает только один текстовый объект и одного автора. Если бы наш элемент цитаты содержал несколько текстов или авторов, то select() вернул бы все тексты и авторов для каждой цитаты.
//find objects with the class "text" and return their text
val text = quote.select(".text").text()
//find objects with the class "author" and return their text
val author = quote.select(".author").text()
Извлечение с помощью jsoup
Для извлечения данных с помощью jsoup мы можем использовать следующие методы:
text()
: Извлечение текста из списка элементов страницы. Когда вы извлекаете цены с веб-сайта, они отображаются на странице в виде текста.attr()
: Извлечение определенного атрибута из одного элемента страницы. Это части данных, расположенные внутри HTML-тегов. Этот метод обычно используется для извлечения ссылок с веб-сайта.
text()
Мы видели примеры этого на примере нашего начального скрепера. text()
возвращает текст всех элементов, к которым мы обращаемся. Если в приведенном ниже примере нужно найти двух авторов, text()
извлечет оба их текста и объединит их в одну строку.
//find objects with the class "text" and return their text
val text = quote.select(".text").text()
//find objects with the class "author" and return their text
val author = quote.select(".author").text()
attr()
Метод attr()
ведет себя иначе, чем text()
. Этот метод извлекает один атрибут из одного элемента страницы.
//find link elements with the class "tag" and extract the "href" from the first one
val firstTagLink = quote.select("a[class='tag']").attr("href")
После добавления этой строки наш вывод выглядит следующим образом.
Quote: “The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”
Author: Albert Einstein
First Tag Link: /tag/change/page/1/
--------------------------------------------------
Quote: “It is our choices, Harry, that show what we truly are, far more than our abilities.”
Author: J.K. Rowling
First Tag Link: /tag/abilities/page/1/
--------------------------------------------------
Quote: “There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.”
Author: Albert Einstein
First Tag Link: /tag/inspirational/page/1/
--------------------------------------------------
Quote: “The person, be it gentleman or lady, who has not pleasure in a good novel, must be intolerably stupid.”
Author: Jane Austen
First Tag Link: /tag/aliteracy/page/1/
--------------------------------------------------
Quote: “Imperfection is beauty, madness is genius and it's better to be absolutely ridiculous than absolutely boring.”
Author: Marilyn Monroe
First Tag Link: /tag/be-yourself/page/1/
--------------------------------------------------
Quote: “Try not to become a man of success. Rather become a man of value.”
Author: Albert Einstein
First Tag Link: /tag/adulthood/page/1/
--------------------------------------------------
Quote: “It is better to be hated for what you are than to be loved for what you are not.”
Author: André Gide
First Tag Link: /tag/life/page/1/
--------------------------------------------------
Quote: “I have not failed. I've just found 10,000 ways that won't work.”
Author: Thomas A. Edison
First Tag Link: /tag/edison/page/1/
--------------------------------------------------
Quote: “A woman is like a tea bag; you never know how strong it is until it's in hot water.”
Author: Eleanor Roosevelt
First Tag Link: /tag/misattributed-eleanor-roosevelt/page/1/
--------------------------------------------------
Quote: “A day without sunshine is like, you know, night.”
Author: Steve Martin
First Tag Link: /tag/humor/page/1/
--------------------------------------------------
[success] Total time: 3 s, completed Feb 18, 2025, 10:29:30 PM
Альтернативные инструменты для веб-скрепинга
- Браузер для скрапинга: Удаленный браузер, полностью интегрированный с прокси, который можно использовать из Playwright и Selenium.
- API-интерфейсы для веб-скраперов: Автоматизируйте процесс скрапинга, вызвав один из наших API. Когда вы вызываете API-скребок, мы скребем сайт и отправляем данные обратно вам.
- Скребок без кода: Сообщите нам, какой сайт вы хотите скрапировать и какие данные вам нужны. Остальное мы сделаем сами.
- Наборы данных: Наши базы данных, пожалуй, самые простые из всех методов извлечения информации. Мы сканируем сотни сайтов и постоянно обновляем наши базы данных. Наборы данных дают вам чистый набор данных, готовый к анализу.
Заключение
Веб-скраппинг довольно интуитивно понятен в Scala. Вы узнали, как выбирать элементы страницы и извлекать из них данные с помощью jsoup. Если скраппинг – не ваш конек, вы всегда можете воспользоваться одним из наших автоматизированных инструментов, чтобы направить процесс в нужное русло, или полностью отказаться от него, используя наши готовые наборы данных.
Зарегистрируйтесь и начните бесплатную пробную версию уже сегодня!
Кредитная карта не требуется