Saya menggunakan CasperJS untuk mengotomatiskan serangkaian klik, formulir yang telah diisi, penguraian data, dll melalui situs web.
Casper tampaknya diatur ke dalam daftar langkah prasetel dalam bentuk then
pernyataan (lihat contohnya di sini: http://casperjs.org/quickstart.html ) tetapi tidak jelas apa yang memicu pernyataan berikutnya untuk benar-benar dijalankan.
Misalnya, apakah then
menunggu semua permintaan yang tertunda selesai? Apakah injectJS
dihitung sebagai permintaan yang menunggu keputusan? Apa yang terjadi jika saya memiliki then
pernyataan bersarang - dirantai di akhir open
pernyataan?
casper.thenOpen('http://example.com/list', function(){
casper.page.injectJs('/libs/jquery.js');
casper.evaluate(function(){
var id = jQuery("span:contains('"+itemName+"')").closest("tr").find("input:first").val();
casper.open("http://example.com/show/"+id); //what if 'then' was added here?
});
});
casper.then(function(){
//parse the 'show' page
});
Saya mencari penjelasan teknis tentang cara kerja aliran di CasperJS. Masalah khusus saya adalah bahwa then
pernyataan terakhir saya (di atas) berjalan sebelum casper.open
pernyataan saya & saya tidak tahu mengapa.
sumber
flow
casperjs, tetapi saya telah menemukan bahwa pada dasarnya Anda tidak dapat merujuk casper dari dalamevaluate
panggilan. (yaitu Anda tidak dapat membuka url baru, log, echo, dll). Jadi dalam kasus saya, evaluasi dipanggil tetapi tidak ada cara untuk berinteraksi dengan dunia luar.evaluate()
adalah untuk kode yang berjalan di "browser", di DOM halaman phantomjs sedang menjelajah. Jadi tidak ada dicasper.open
sana, tetapi mungkin ada jQuery. Jadi teladan Anda tidak masuk akal, tapi saya masih bertanya-tanya apa yangthen()
sebenarnya terjadi.Jawaban:
then()
pada dasarnya menambahkan langkah navigasi baru dalam tumpukan. Langkah adalah fungsi javascript yang dapat melakukan dua hal berbeda:Mari kita ambil skenario navigasi sederhana:
Anda dapat mencetak semua langkah yang dibuat dalam tumpukan seperti ini:
Itu memberi:
Perhatikan
_step()
fungsi yang telah ditambahkan secara otomatis oleh CasperJS untuk memuat url untuk kita; ketika url dimuat, langkah selanjutnya yang tersedia di tumpukan - yangstep3()
- dipanggil.Ketika Anda telah menentukan langkah-langkah navigasi Anda,
run()
jalankan satu per satu secara berurutan:Catatan kaki: item panggilan balik / pendengar adalah implementasi dari pola Janji .
sumber
then()
hanya mendaftarkan serangkaian langkah.run()
dan rangkaian fungsi runner, callback, dan listenernya, semuanya melakukan tugas melaksanakan setiap langkah.Setiap kali langkah selesai, CasperJS akan memeriksa terhadap 3 bendera:
pendingWait
,loadInProgress
, dannavigationRequested
. Jika salah satu dari flag tersebut benar, maka tidak melakukan apa-apa, diam sampai nanti (setInterval
gaya). Jika tidak ada satu pun dari tanda tersebut yang benar, maka langkah selanjutnya akan dijalankan.Pada CasperJS 1.0.0-RC4, terdapat cacat, di mana, dalam keadaan berbasis waktu tertentu, metode "coba lakukan langkah berikutnya" akan dipicu sebelum CasperJS punya waktu untuk menaikkan salah satu dari
loadInProgress
ataunavigationRequested
bendera. Solusinya adalah menaikkan salah satu bendera tersebut sebelum meninggalkan langkah apa pun di mana bendera tersebut diharapkan akan dinaikkan (misal: menaikkan bendera sebelum atau setelah meminta acasper.click()
), mungkin seperti ini:(Catatan: Ini hanya ilustrasi, lebih mirip psuedocode daripada bentuk CasperJS yang tepat ...)
Untuk membungkus solusi itu menjadi satu baris kode, saya perkenalkan
blockStep()
dalam permintaan tarik github ini , memperluasclick()
danclickLabel()
sebagai sarana untuk membantu menjamin bahwa kami mendapatkan perilaku yang diharapkan saat menggunakanthen()
. Lihat permintaan untuk info lebih lanjut, pola penggunaan, dan file pengujian minimum.sumber
blockStep
, IMHOMenurut Dokumentasi CasperJS :
then()
Tanda tangan:
then(Function then)
Di balik layar, kode sumber untuk
Casper.prototype.then
ditampilkan di bawah ini:Penjelasan:
Dengan kata lain,
then()
menjadwalkan langkah berikutnya dalam proses navigasi.Ketika
then()
dipanggil, itu melewati fungsi sebagai parameter yang akan disebut sebagai langkah.Ia memeriksa apakah sebuah instance telah dimulai, dan jika belum, ini akan menampilkan kesalahan berikut:
Selanjutnya, ia memeriksa apakah
page
objeknyanull
.Jika kondisinya benar, Casper membuat
page
objek baru .Setelah itu,
then()
validasistep
parameter untuk memeriksa apakah itu bukan fungsi.Jika parameter bukan fungsi, ini akan menampilkan kesalahan berikut:
Kemudian, fungsi tersebut memeriksa apakah Casper sedang berjalan.
Jika Casper tidak berjalan,
then()
menambahkan langkah ke akhir antrian.Jika tidak, jika Casper sedang berjalan, Casper akan memasukkan sub-langkah yang lebih dalam dari langkah sebelumnya.
Terakhir,
then()
fungsi tersebut diakhiri dengan memancarkanstep.added
peristiwa, dan mengembalikan objek Casper.sumber