Python เป็นภาษาที่มีประโยชน์ อย่างไรก็ตาม อาจผิดพลาดได้เนื่องจากภาษาสคริปต์ขาดการประเมินประเภทที่เข้มงวดและการดำเนินการบางอย่างที่มีราคาแพง จากประสบการณ์ส่วนตัวของฉัน ฉันมักจะประสบปัญหากับข้อผิดพลาดที่ไม่สามารถทำซ้ำได้ใน Python ในโปรแกรมที่เป้าหมายการวิเคราะห์มีขนาดใหญ่และจำเป็นต้องมีการขนานกัน ฉันลองใช้ Kotlin แบบไม่ได้ตั้งใจและพบว่ามันค่อนข้างใช้งานง่าย ดังนั้นฉันจึงลองย้าย Scraper ที่ใช้งานใน Python3
(ยังไงก็ตามผมไม่เคยแตะ Java เลยจริงๆ)
นี่เป็นมือใหม่ Kotlin แต่เธรด Python และเธรด Kotlin ดูเหมือนจะทำงานแตกต่างออกไป
แม้ว่าเธรดของ Kotlin จะไม่แยกกระบวนการ แต่อัตราการใช้งาน CPU เกิน 100% ดังนั้นจึงดูเหมือนว่าเธรดที่มีประสิทธิภาพกำลังดำเนินการโดยใช้ CPU หลายตัว (หรืออีกนัยหนึ่งคือ หลังจากหารด้วย Multiprocess แล้ว ดูเหมือนว่าจะไม่จำเป็นต้องเรียกใช้ Thread ข้างใต้)
นี่คือวิธีการติดตั้งบน Ubuntu
$ curl -s https://get.sdkman.io | bash
$ sdk install kotlin
ดูเหมือนว่าหน่วยความจำ JVM จะถูกบันทึกในตัวแปรสภาพแวดล้อม JAVA_OPT และหากคุณใช้งานตามปกติ หน่วยความจำจะพังเนื่องจากไม่มีหน่วยความจำ ดังนั้นจึงเป็นการดีกว่าที่จะแก้ไขด้วยวิธีที่ทันสมัย ฉันมีการตั้งค่าเช่นนี้
JAVA_OPTS= " -Xmx3000M -Xms3000M "
ฉันไม่เก่ง Java และฉันกำลังคิดที่จะทำตามแผนอาชีพที่จะหลีกเลี่ยง Java ให้ได้มากที่สุด แต่ฉันรู้สึกว่าการเรียนรู้เครื่องมือต่างๆ ด้วยตนเองคงเป็นเรื่องยาก โดยเฉพาะ Eclipse และ IDE เนื่องจากมีหลายอย่าง ของสิ่งต่างๆ
การใช้ Kotlin กับ IDE น่าจะสะดวกกว่า แต่ฉันคิดว่า CUI ก็ใช้ได้ตราบใดที่ไม่มีปัญหาในการคอมไพล์และรันด้วย CUI
มีหลายวิธีในการคอมไพล์ แต่เราพบว่าการคอมไพล์เป็นไฟล์ jar รวมถึงรันไทม์นั้นมีประโยชน์กว่าด้วย
$ kotlinc foo.kt -include-runtime -d foo.jar
ตอนนี้คุณสามารถรวบรวม
คุณสามารถรวมไฟล์หลายไฟล์ไว้ในขวดเดียวได้ (คุณสามารถอ้างถึงฟังก์ชั่นของ bar.kt และคลาสใน foo.kt)
$ kotlinc foo.kt bar.kt -include-runtime -d foo.jar
สามารถใช้งานได้โดยการเพิ่มไฟล์ jar ที่สามารถคอมไพล์ได้โดยใช้ Maven ของ Java ฯลฯ ลงใน classpath (สมมติว่าคุณใช้ไฟล์ alice.jar และ bob.jar)
สิ่งนี้มีประโยชน์มากเพราะช่วยให้เราสามารถนำทรัพย์สิน Java จำนวนมากกลับมาใช้ใหม่ได้
$ kotlinc foo.kt bar.kt -cp alice.jar:bob.jar -include-runtime foo.jar
ตัวอย่างเช่น เมื่อรัน kotlin jar โดยใช้ไฟล์ jar ภายนอก คำสั่งจะเป็นเช่นนี้
$ kotlin -cp alice.jar:bob.jar:foo.jar FooKt
ดูเหมือนว่าชื่อ FooKt จะใช้เพื่อระบุไฟล์ foo.kt ที่มีฟังก์ชันหลัก
เมื่อมีการโหลดข้อมูลแบบอะซิงโครนัสโดยใช้ JavaScript หากคุณเพียงดึงข้อมูลและวิเคราะห์ด้วย jsoup เป็นต้น คุณจะไม่สามารถรับเนื้อหาได้ คุณต้องเรียกใช้ JavaScript เพื่อสร้างสถานะที่คล้ายกับที่มนุษย์จะเห็น เรียกใช้ phamtomjs ผ่านซีลีเนียมเพื่อให้ JavaScript ทำงานได้ ตัวอย่างเช่น การค้นหารูปภาพของ Microsoft Bing แสดงผลด้วย Ajax และไม่สามารถทำงานในสภาพแวดล้อมที่ JavaScript ไม่ทำงาน (นี่เป็นเพียงการทดลอง ดังนั้นเมื่อทำการคัดลอกรูปภาพจริง ๆ โปรดดำเนินการผ่าน 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()
ตัวแปร html จะมี html ที่แสดงผลหลังจากที่ JavaScript ทำงาน เมื่อใส่สิ่งนี้ลงใน jsoup คุณจะพบ src URL ของรูปภาพต่างๆ ตาม URL ของรูปภาพที่คุณพบ ให้ใช้คำสั่ง wget เพื่อเก็บไว้ในโฟลเดอร์ภายใต้ไดเร็กทอรีใดก็ได้
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 จากไซต์นี้และวางไว้ใน PATH
ดูเหมือนจะมีหลายวิธีในการเขียนสิ่งนี้ แต่นี่เป็นการนำไปปฏิบัติที่ง่ายที่สุด
ตรรกะทั้งหมดที่จะคัดลอกไว้ใน {} จะกลายเป็นอินสแตนซ์ของเธรด และคุณสามารถเริ่มหรือรวมเธรดนั้นเพื่อรันพร้อมกันได้
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
}
ดูเหมือนว่าโมดูลการทำให้เป็นอนุกรมที่เรียกว่า Jackson สามารถใช้ได้ในระยะเวลาที่จำกัด
ดูเหมือนว่าไลบรารี Java เพียงอย่างเดียวใช้งานไม่ได้ และคุณต้องโหลดโมดูลสำหรับ Kotlin แยกต่างหาก
โดยจำกัด ฉันลองซีเรียลไลซ์และดีซีเรียลไลซ์ MutableMap<String, DataClass> แล้วมันก็ใช้งานไม่ได้
MutableMap<String, String> ทำงานได้ดี ดังนั้นฉันไม่แน่ใจว่าโครงสร้างที่ซ้อนกันไม่ดีหรือไม่รองรับ Data Class
ตัวอย่างการทำให้เป็นอนุกรม
val mapper = ObjectMapper ().registerKotlinModule()
val serialzied = mapper.writeValueAsString(url_details)
ตัวอย่างการดีซีเรียลไลซ์
val mapper = ObjectMapper ().registerKotlinModule()
val url_details = mapper.readValue< MutableMap < String , String >>(json)
ก่อนอื่นให้คอมไพล์โคลน
$ git clone https://github.com/GINK03/kotlin-phantomjs-selenium-jsoup-parser.git
จนถึงขณะนี้ มีการนำการขูดสองประเภทไปใช้: เพียงคัดลอกไปที่ความลึก 100 โดยใช้การค้นหาแบบกว้างก่อนโดยไม่ต้องประเมิน JavaScript
(เนื่องจากฉันใช้มันเพื่อขูดไซต์ของตัวเอง ฉันจึงไม่ได้กำหนดขีดจำกัดใดๆ เป็นพิเศษ แต่ค่าเริ่มต้นคือการเข้าถึงแบบขนาน 50 ครั้งขึ้นไป ดังนั้นโปรดปรับเปลี่ยนตามนั้น)
$ sh run.scraper.sh widthSearch ${yourOwnSite}
ใช้ Microsoft Bing เพื่อค้นหาบนหน้าจอค้นหารูปภาพ นี่เป็นโค้ดทดลองเพื่อดูว่าสามารถรับเนื้อหาที่วาดด้วย Ajax โดยไม่ใช้ API ได้หรือไม่ ดังนั้นฉันไม่คิดว่าควรมีการเข้าถึงในปริมาณมากและทำให้เกิดปัญหา
โปรดดูไฟล์ kancolle.txt บน github สำหรับรายการค้นหา
sh run.scraper.sh image ${検索クエリリスト} ${出力ディレクトリ}