我正在使用scala-scraper库进行网页抓取。我想创建一个List[JSoupBrowser]
,其中包含具有唯一用户代理的JsoupBrowsers
列表。目前,我有以下代码,
import net.ruippeixotog.scalascraper.browser.{JsoupBrowser => JSB}
class Scraper() {
def userAgents : List[String] =
List (
"Mozilla/5.0 (Linux; Android 7.0; Pixel C Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.98 Safari/537.36"
)
def browsers : List[JSB] = userAgents.foreach(agent => JSB(agent)) // throws err
// def browsers: List[JSB] = userAgents.foreach(agent => JSB()) // no err
}
然而,这是抛出错误
Cannot resolve reference JSoupBrowser with such signature
查看scala-scraper JSoupBrowser source 透露,类声明是
class JsoupBrowser(val userAgent: String = "jsoup/1.8", val proxy: java.net.Proxy = null) extends Browser
我是Scala的新手,所以这可能只是对构造函数的误解。
当为可选参数userAgent
提供具有正确类型的参数并且默认构造函数正常工作时,为什么第一个抛出错误?
答案 0 :(得分:1)
假设JSB
是JsoupBrowser
的导入别名:
import net.ruippeixotog.scalascraper.browser.{JsoupBrowser => JSB}
JSB()
是合法的,因为它是对JsoupBrowser
的随播对象中apply
方法的调用。从链接的源代码中可以看出,此apply
方法只调用new JsoupBrowser()
。基本上,它是使用默认参数创建JsoupBrowser
实例的便捷方法。
如您所知,如果要覆盖默认的userAgent
参数,则必须使用new
关键字来实例化JsoupBrowser
。但是,你猜测,这完全是因为JsoupBrowser
是一个类,这是不正确的。您必须使用new
的原因是因为apply
的随播对象中没有JsoupBrowser
的任何重载版本允许您覆盖默认参数。这方面的一个例子是:
object JsoupBrowser {
...
def apply(agent: String): Browser = new JsoupBrowser(userAgent = agent)
...
}
由于上述版本的apply
不可用,因此您无法致电JSB(agent)
,必须使用new JSB(agent)
。
另外,创建List[JSB]
的更简单方法是:
def browsers: List[JSB] = userAgents.map(new JSB(_))