Python é uma linguagem útil. No entanto, pode dar errado devido à falta de avaliação rigorosa do tipo na linguagem de script e a algumas operações caras. Com base na minha experiência pessoal, muitas vezes tenho sido incomodado por erros irreproduzíveis em Python em programas onde o alvo da análise se torna grande e o paralelismo é necessário. Experimentei casualmente o Kotlin e descobri que era muito fácil de usar, então tentei portar o Scraper que foi implementado em Python3.
(A propósito, eu nunca toquei em Java)
Este é um novato em Kotlin, mas os threads Python e Kotlin parecem se comportar de maneira diferente.
Embora o Thread do Kotlin não divida o processo, a taxa de uso da CPU excede 100%, então parece que o threading eficiente está sendo executado usando várias CPUs. (Em outras palavras, após dividir com Multiprocess, parece não haver necessidade de executar Thread sob ele)
É assim que se instala no Ubuntu.
$ curl -s https://get.sdkman.io | bash
$ sdk install kotlin
Parece que a memória JVM está gravada na variável de ambiente JAVA_OPT, e se você usar normalmente, ela irá travar por falta de memória, então seria melhor consertar de forma moderna. Eu tenho as configurações assim.
JAVA_OPTS= " -Xmx3000M -Xms3000M "
Não sou bom em Java e estava pensando em seguir um plano de carreira que evitasse Java o máximo possível, mas sinto que seria difícil aprender as ferramentas em si, principalmente Eclipse e IDE Porque eram muitas. das coisas.
Seria conveniente usar Kotlin com um IDE, mas acho que CUI é adequado, desde que não haja problemas ao compilar e executar com CUI.
Existem muitas maneiras de compilar, mas achamos mais útil compilá-lo em um arquivo jar, incluindo o tempo de execução.
$ kotlinc foo.kt -include-runtime -d foo.jar
Agora você pode compilar.
Você pode combinar vários arquivos em um jar. (Você pode consultar as funções e classes de bar.kt em foo.kt)
$ kotlinc foo.kt bar.kt -include-runtime -d foo.jar
Ele pode ser usado adicionando um arquivo jar que pode ser compilado usando Maven do Java etc. (Suponha que você use os arquivos alice.jar e bob.jar)
Isso é muito útil porque nos permite reutilizar muitos ativos Java.
$ kotlinc foo.kt bar.kt -cp alice.jar:bob.jar -include-runtime foo.jar
Por exemplo, ao executar um jar kotlin usando um arquivo jar externo, o comando será assim.
$ kotlin -cp alice.jar:bob.jar:foo.jar FooKt
Este nome FooKt parece ser usado para especificar o arquivo foo.kt que contém a função principal.
Quando há carregamento assíncrono de dados usando JavaScript, se você simplesmente recuperá-los e analisá-los com jsoup etc., não será capaz de obter o conteúdo.Você precisa executar o JavaScript para criar um estado semelhante ao que um ser humano veria. execute phamtomjs via Selenium para fazer o JavaScript funcionar. Por exemplo, a pesquisa de imagens do Microsoft Bing é renderizada com Ajax e não pode funcionar em um ambiente onde o JavaScript não funciona. (Isso é para fins experimentais, portanto, ao copiar imagens, faça-o por meio da 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()
A variável html conterá o html renderizado após a execução do JavaScript. Ao colocar isso no jsoup, você pode encontrar o URL src de várias imagens. Com base no URL da imagem encontrada, use o comando wget para armazená-lo em uma pasta em qualquer diretório.
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 " )
}
O PhantomJS precisa ser baixado deste site e colocado no PATH.
Parece haver várias maneiras de escrever isso, mas esta é a implementação mais fácil.
Toda a lógica a ser extraída entre {} se torna uma instância de thread, e você pode iniciar ou ingressar nesse thread para executá-lo em paralelo.
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
}
Parece que um módulo de serialização chamado jackson pode ser usado por um tempo limitado.
Parece que a biblioteca Java sozinha não funciona e você precisa carregar o módulo para Kotlin separadamente.
De forma limitada, tentei serializar e desserializar MutableMap<String, DataClass> e não funcionou.
MutableMap<String, String> funciona bem, então não tenho certeza se a estrutura aninhada é ruim ou se não suporta classe de dados.
Exemplo de serialização
val mapper = ObjectMapper ().registerKotlinModule()
val serialzied = mapper.writeValueAsString(url_details)
Exemplo de desserialização
val mapper = ObjectMapper ().registerKotlinModule()
val url_details = mapper.readValue< MutableMap < String , String >>(json)
Primeiro, faça o clone do git
$ git clone https://github.com/GINK03/kotlin-phantomjs-selenium-jsoup-parser.git
Até agora, dois tipos de raspagem foram implementados: simplesmente raspar até uma profundidade de 100 usando pesquisa em largura sem avaliar JavaScript.
(Como eu o estava usando para copiar meu próprio site, não defini nenhum limite específico, mas o padrão é 50 ou mais acessos paralelos, portanto, ajuste de acordo.)
$ sh run.scraper.sh widthSearch ${yourOwnSite}
Use o Microsoft Bing para pesquisar na tela de pesquisa de imagens. Este é um código experimental para ver se é possível desenhar conteúdo com Ajax sem usar a API, então não acho que deva ser acessado em grandes quantidades e causar problemas.
Consulte o arquivo kancolle.txt no github para obter a lista de pesquisa.
sh run.scraper.sh image ${検索クエリリスト} ${出力ディレクトリ}