Scala 可以轻松实现简单的数据采集任务,结合 Akka HTTP(高效HTTP客户端)和 Jsoup(HTML解析库)是常见方案。Scala因为受众比较少,而且随着这两年python的热门语言,更让Scala不为人知,今天我将结合我所学的知识实现一个简单的Scala爬虫代码示例。

Scala实现网页数据采集示例_HTTP

以下就是我整理的一个完整示例,演示如何抓取网页标题和链接:

示例代码

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解析HTML
            val 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")  // 获取绝对URL
              val 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系统

扩展建议

  • 并发采集:结合 SourceFlow 实现多URL并行处理
  • 错误处理:添加重试机制(使用 akka.pattern.retry
  • 数据存储:将结果写入文件(scala.util.Using)或数据库
  • 动态内容:如需执行JavaScript,可集成 SeleniumPlaywright

执行前准备

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)

以上就是全部的内容,总体来说步骤还是很详细的,对于小型爬虫还是非常适合的。如果任何问题都可以这里留言一起讨论。