Scala实现网页数据采集示例
Scala 可以轻松实现简单的数据采集任务,结合 Akka HTTP(高效HTTP客户端)和 Jsoup(HTML解析库)是常见方案。Scala因为受众比较少,而且随着这两年python的热门语言,更让Scala不为人知,今天我将结合我所学的知识实现一个简单的Scala爬虫代码示例。
以下就是我整理的一个完整示例,演示如何抓取网页标题和链接:
示例代码
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.stream.scaladsl._
import org.jsoup.Jsoup
import scala.concurrent._
import scala.util.{Success, Failure}object WebScraper {// sbt依赖配置(build.sbt):// libraryDependencies ++= Seq(// "com.typesafe.akka" %% "akka-http" % "10.5.0",// "com.typesafe.akka" %% "akka-stream" % "2.8.0",// "org.jsoup" % "jsoup" % "1.16.1"// )def main(args: Array[String]): Unit = {// 目标网站(示例:Scala官网)val targetUrl = "https://www.scala-lang.org/"// 创建Actor系统(Akka基础组件)implicit val system: ActorSystem = ActorSystem("WebScraper")import system.dispatcher // 线程池// 1. 发送HTTP GET请求val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = targetUrl))// 2. 处理响应:提取HTML -> 解析数据responseFuture.flatMap { response =>response.status match {case StatusCodes.OK =>// 将响应体转为字符串val htmlString = response.entity.toStrict(5.seconds).map(_.data.utf8String)htmlString.map { html =>// 3. 使用Jsoup解析HTMLval doc = Jsoup.parse(html)// 提取页面标题val title = doc.title()println(s"网页标题: $title\n")// 提取所有链接 (示例:打印前5个)val links = doc.select("a[href]")println(s"发现 ${links.size()} 个链接,示例:")links.stream().limit(5).forEach { link =>val href = link.attr("abs:href") // 获取绝对URLval text = link.text().trim.take(30) // 截取部分文本println(s"- [$text] -> $href")}}case _ =>Future.failed(new RuntimeException(s"请求失败: ${response.status}"))}}.onComplete {// 4. 处理最终结果case Success(_) =>println("\n数据采集完成!")system.terminate() // 关闭Actor系统case Failure(ex) =>println(s"发生错误: ${ex.getMessage}")system.terminate()}}
}
关键步骤解析
1、发送HTTP请求
- 使用
akka.http.scaladsl.Http().singleRequest()
发送GET请求 - 支持异步非阻塞IO,适合高并发采集
2、处理响应
- 检查HTTP状态码(仅处理200 OK)
- 将响应实体转换为字符串(
data.utf8String
)
3、解析HTML
- Jsoup 提供类似jQuery的DOM操作:
doc.title()
获取页面标题doc.select("a[href]")
选择所有带链接的<a>
标签attr("abs:href")
获取绝对URL(避免相对路径问题)
4、资源清理
- 完成后调用
system.terminate()
关闭Actor系统
扩展建议
- 并发采集:结合
Source
和Flow
实现多URL并行处理 - 错误处理:添加重试机制(使用
akka.pattern.retry
) - 数据存储:将结果写入文件(
scala.util.Using
)或数据库 - 动态内容:如需执行JavaScript,可集成 Selenium 或 Playwright
执行前准备
1、在 build.sbt
中添加依赖:
libraryDependencies ++= Seq("com.typesafe.akka" %% "akka-http" % "10.5.0","com.typesafe.akka" %% "akka-stream" % "2.8.0", // Akka 2.6+ 兼容"org.jsoup" % "jsoup" % "1.16.1"
)
2、运行程序(支持 Scala 2.13/3.x)
以上就是全部的内容,总体来说步骤还是很详细的,对于小型爬虫还是非常适合的。如果任何问题都可以这里留言一起讨论。