我正在尝试用Kotlin制作一个网络应用程序。由于我将要抓取的网站是JS生成的,我一直在尝试使Selenium工作,但我一直被这个错误所困扰。
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:353)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.IllegalStateException: The driver executable does not exist: /home/nexus/Downloads/chromedriver
我已经使用'chmod 777'和驱动程序一起使用了AIR版本。
这是我的抓取功能的代码
package com.example.nexus.scraper
import android.os.AsyncTask
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
class Scrap(): AsyncTask<Void, Void, Void>() {
override fun doInBackground(vararg params: Void?): Void? {
System.setProperty("webdriver.chrome.driver","/home/nexus/Downloads/chromedriver")
var driver: WebDriver = ChromeDriver()
driver.get("www.google.com")
return null
}
}
这是我的build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.example.nexus.scraper"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '2.41.0'
implementation 'com.android.support:support-annotations:27.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
谢谢!
您必须在gradle.build中应用chromedriver目录:
'--webdriver.chrome.driver=/home/nexus/Downloads/chromedriver'
错误是由使用Selenium而不是Selendrium引起的
我强烈建议使用webdriver manager而不是自己设置浏览器二进制文件。
要实例化一个新的chromedriver我会在我的代码中放置这样的函数:
fun chrome(): WebDriver {
WebDriverManager.chromedriver().setup()
return ChromeDriver(chromeOptions())
}
现在你可以使用这个将返回你的chrome驱动程序的函数,如下所示:
val driver = chrome()
driver.get("www.google.com")
webdriver manager将根据您当前的操作系统自动设置驱动程序二进制文件。对于更复杂的示例,可以在不同的浏览器或驱动程序设置和完整的selenium设置之间动态切换,请查看here
因为你想刮一个网站我猜你的选择应该是chrome headless模式,因为它在浏览器启动时间等方面更有效率。
一般来说,我建议使用skrape{it}而不是selenium来完成这项工作(只要你不必点击某处)。它是一个用kotlin编写的库,专门设计用于抓取网站并支持抓取javascript渲染的网站。例如,你可以做这样的事情,你就完成了(不需要硒开销):
val githubName = skrape {
url = "https://github.com/skrapeit"
mode = Mode.DOM
extract {
element(".h-card .p-nickname").text()
}
}
这也适用于更复杂的数据,例如:
data class MyScrapedData(
val userName: String,
val repositoryNames: List<String>
)
fun main() {
val githubUserData = skrape {
url = "https://github.com/skrapeit"
mode = Mode.DOM
extract {
MyScrapedData(
userName = element(".h-card .p-nickname").text(),
repositoryNames = elements("span.repo").map { it.text() }
)
}
}
println("${githubUserData.userName}'s repos are ${githubUserData.repositoryNames}")
}
有关如何使用skrape {it}刮取javascript呈现网站的完整示例,请查看相应的docs section