Python ist eine nützliche Sprache. Dies kann jedoch schief gehen, da die Skriptsprache keine strenge Typbewertung durchführt und einige kostspielige Vorgänge erfordert. Aufgrund meiner persönlichen Erfahrung habe ich oft Probleme mit nicht reproduzierbaren Fehlern in Python in Programmen, bei denen das Analyseziel groß wird und Parallelität erforderlich ist. Ich habe Kotlin beiläufig ausprobiert und fand es recht einfach zu verwenden, also habe ich versucht, den in Python3 implementierten Scraper zu portieren.
(Übrigens habe ich Java nie wirklich berührt)
Dies ist ein Kotlin-Neuling, aber Python-Threads und Kotlin-Threads scheinen sich unterschiedlich zu verhalten.
Obwohl Kotlins Thread den Prozess nicht aufteilt, übersteigt die CPU-Auslastungsrate 100 %, sodass es den Anschein hat, dass effizientes Threading mit mehreren CPUs durchgeführt wird. (Mit anderen Worten, nach der Aufteilung mit Multiprocess scheint es nicht nötig zu sein, Thread darunter auszuführen.)
So installieren Sie es unter Ubuntu.
$ curl -s https://get.sdkman.io | bash
$ sdk install kotlin
Es scheint, dass der JVM-Speicher in der Umgebungsvariablen JAVA_OPT aufgezeichnet ist. Wenn Sie ihn normal verwenden, stürzt er aufgrund von Speichermangel ab. Daher ist es besser, das Problem auf moderne Weise zu beheben. Ich habe solche Einstellungen.
JAVA_OPTS= " -Xmx3000M -Xms3000M "
Ich bin nicht gut in Java und habe darüber nachgedacht, einen Karriereplan zu verfolgen, der Java so weit wie möglich meidet, aber ich habe das Gefühl, dass es schwierig sein würde, die Tools selbst zu erlernen, hauptsächlich Eclipse und IDE, weil es viele davon gab der Dinge.
Es wäre praktisch, Kotlin mit einer IDE zu verwenden, aber ich denke, CUI ist in Ordnung, solange es keine Probleme beim Kompilieren und Ausführen mit CUI gibt.
Es gibt viele Möglichkeiten zum Kompilieren, aber wir fanden es praktischer, es in eine JAR-Datei zu kompilieren, einschließlich der Laufzeit.
$ kotlinc foo.kt -include-runtime -d foo.jar
Jetzt können Sie kompilieren.
Sie können mehrere Dateien in einem Glas zusammenfassen. (Sie können auf die Funktionen und Klassen von bar.kt in foo.kt verweisen.)
$ kotlinc foo.kt bar.kt -include-runtime -d foo.jar
Es kann verwendet werden, indem dem Klassenpfad eine JAR-Datei hinzugefügt wird, die mit Javas Maven usw. kompiliert werden kann. (Angenommen, Sie verwenden die Dateien alice.jar und bob.jar)
Dies ist sehr hilfreich, da wir so viele Java-Assets wiederverwenden können.
$ kotlinc foo.kt bar.kt -cp alice.jar:bob.jar -include-runtime foo.jar
Wenn Sie beispielsweise ein Kotlin-JAR mit einer externen JAR-Datei ausführen, sieht der Befehl wie folgt aus.
$ kotlin -cp alice.jar:bob.jar:foo.jar FooKt
Dieser Name FooKt scheint verwendet zu werden, um die Datei foo.kt anzugeben, die die Hauptfunktion enthält.
Wenn Daten asynchron mit JavaScript geladen werden und Sie sie einfach abrufen und mit jsoup usw. analysieren, können Sie den Inhalt nicht abrufen. Sie müssen JavaScript ausführen, um einen Zustand zu erstellen, der dem ähnelt, was ein Mensch sehen würde. Führen Sie phamtomjs über Selenium aus, damit JavaScript funktioniert. Beispielsweise wird die Bildsuche von Microsoft Bing mit Ajax gerendert und kann nicht in einer Umgebung funktionieren, in der JavaScript nicht funktioniert. (Dies dient experimentellen Zwecken. Wenn Sie Bilder also tatsächlich scrapen, tun Sie dies bitte über die API.)
val driver = PhantomJSDriver ()
driver.manage().window().setSize( Dimension ( 4096 , 2160 ))
driver.get( " https://www.bing.com/images/search?q= ${encoded} " )
//すべての画像が描画されるのを待つ
Thread .sleep( 3001 )
val html = driver.getPageSource()
Die HTML-Variable enthält den gerenderten HTML-Code, nachdem JavaScript ausgeführt wurde. Indem Sie dies in jsoup eingeben, können Sie die Quell-URL verschiedener Bilder finden. Verwenden Sie den Befehl wget, um sie anhand der URL des gefundenen Bildes in einem Ordner in einem beliebigen Verzeichnis zu speichern.
val doc = Jsoup .parse(html.toString(), " UTF-8 " )
println (doc.title())
doc.select( " img " ).filter { x ->
x.attr( " class " ) == " mimg "
}.map { x ->
val data_bm = x.attr( " data-bm " )
val src = x.attr( " src " )
Runtime .getRuntime().exec( " wget ${src} -O imgs/ ${name} / ${data_bm} .png " )
}
PhantomJS muss von dieser Site heruntergeladen und im PATH platziert werden.
Es scheint mehrere Möglichkeiten zu geben, dies zu schreiben, aber dies ist die einfachste Implementierung.
Die gesamte in {} eingeschlossene Logik, die gescrapt werden soll, wird zu einer Thread-Instanz, und Sie können diesen Thread starten oder ihm beitreten, um ihn parallel auszuführen.
val threads = url_details.keys.map { url ->
val th = Thread {
if (url_details[url] !! == "まだ" ) {
_parser (url).map { next ->
urls.add(next)
}
println ( "終わりに更新 : $url " )
url_details[url] = "終わり"
// save urls
_save_conf ( mapper.writeValueAsString(url_details) )
}
}
th
}
Es scheint, dass ein Serialisierungsmodul namens Jackson für eine begrenzte Zeit verwendet werden kann.
Es scheint, dass die Java-Bibliothek allein nicht funktioniert und Sie das Modul für Kotlin separat laden müssen.
Mit Einschränkungen habe ich versucht, MutableMap<String, DataClass> zu serialisieren und zu deserialisieren, aber es hat nicht funktioniert.
MutableMap<String, String> funktioniert einwandfrei, daher bin ich mir nicht sicher, ob die verschachtelte Struktur fehlerhaft ist oder die Datenklasse nicht unterstützt.
Serialisierungsbeispiel
val mapper = ObjectMapper ().registerKotlinModule()
val serialzied = mapper.writeValueAsString(url_details)
Beispiel für eine Deserialisierung
val mapper = ObjectMapper ().registerKotlinModule()
val url_details = mapper.readValue< MutableMap < String , String >>(json)
Zuerst Git-Klon
$ git clone https://github.com/GINK03/kotlin-phantomjs-selenium-jsoup-parser.git
Bisher wurden zwei Arten des Scrapings implementiert: einfaches Scraping bis zu einer Tiefe von 100 mithilfe der Breitensuche ohne Auswertung von JavaScript.
(Da ich es zum Scrapen meiner eigenen Website verwendet habe, habe ich keine besonderen Grenzwerte festgelegt, aber der Standardwert ist 50 oder mehr parallele Zugriffe, also passen Sie ihn bitte entsprechend an.)
$ sh run.scraper.sh widthSearch ${yourOwnSite}
Verwenden Sie Microsoft Bing, um auf dem Bildsuchbildschirm zu suchen. Dies ist ein experimenteller Code, um zu sehen, ob es möglich ist, Inhalte mit Ajax zu zeichnen, ohne die API zu verwenden. Daher denke ich nicht, dass der Zugriff in großen Mengen erfolgen und Probleme verursachen sollte.
Die Suchliste finden Sie in der Datei kancolle.txt auf Github.
sh run.scraper.sh image ${検索クエリリスト} ${出力ディレクトリ}