Posted at

Scala2.12で最新バージョンのHtmlUnitDriverを使用してクローラーを作成してみる。

More than 1 year has passed since last update.

セプテーニさんのScalaもくもく会に参加させて頂いた際に、Scalaの勉強用に簡易クローラーを作成してみました。その作業ログになります。


HTMLパーサー

とりあえずXPathを使用できるHTMLパーサーが必要だなということで調べてみたところ、HtmlUnitDriverが使い勝手が良さそう&情報も多そうだったのでこれを使ってみます。

HtmlUnitDriverを使ってHTMLスクレイピング in Scala - Qiita

WebCrawler in Scala - Web就活日記


HtmlUnitDriverのバージョン

上記の、rkanekoさんとyutakikuchiさんの記事ではwebdriver-htmlunitというjarファイルが使用されていたのですが、これがどうもかなり古い(2009年で更新が止まっている)ようなので、ちょっと調べてみたところHtmlUnitDriverには下記3種類のjarファイルが存在しているようです。

groupId
artifactId
Latest Version
Updated

org.seleniumhq.webdriver
webdriver-htmlunit
0.9.7376
08-Oct-2009

org.seleniumhq.selenium
selenium-htmlunit-driver
2.52.0
12-Feb-2016

org.seleniumhq.selenium
htmlunit-driver
2.23.2
26-Oct-2016

更新日付が最も新しいのはorg.seleniumhq.selenium.htmlunit-driverのようなので、これを使ってみます。


サンプルコード


build.sbt

name := "crawler_sample_scala"

version := "1.0"

scalaVersion := "2.12.0"

libraryDependencies ++= Seq(
"org.seleniumhq.selenium" % "htmlunit-driver" % "2.23.2",
"org.seleniumhq.selenium" % "selenium-support" % "3.0.1",
"net.sourceforge.htmlunit" % "htmlunit" % "2.23"
)



Crawler.scala

package com.polysoft

import scala.collection.JavaConverters._
import org.openqa.selenium.htmlunit.HtmlUnitDriver
import org.openqa.selenium.{ WebElement, By }

object Crawler {
def main(args: Array[String]) = {
val url = "https://sep-ori-mokumoku-day.connpass.com/event/44613/"
crawl(url)
}

private def crawl(url: String): Unit = {
val driver = new HtmlUnitDriver()
driver.get(url)
println(s"title: ${driver.getTitle}")

val content = driver
.findElement(By.xpath("//div[contains(@class, 'event_detail_area')]"))
.getText
println(s"content: ${content}")

driver.findElements(By.xpath("//div[contains(@class, 'event_p_area')]/div"))
.asScala
.foreach{ we: WebElement =>
val member = we.findElement(By.xpath("p[@class='name']/a")).getText
println(s"member: ${member}")
}
}
}


実行すると、Scalaもくもく会のconpassのページをクローリングして、ページのタイトル、コンテンツ、および参加者の方のハンドルネーム一覧を表示します。


補足

sbtは外部ライブラリのpom.xmlに記載されている依存性を自動的に解決してくれない(?)ようで、HtmlUnitDriverが依存しているnet.sourceforge.htmlunit.htmlunitを持ってきてくれないため、build.sbtlibraryDependenciesに直接追記しました。

あまりよろしくない手法だと思うので、どなたか正しい方法をご存知の方がいらっしゃいましたら情報頂けますと幸いですm(__)m