Saat ini, Web Crawling adalah teknologi terkenal, tetapi masih ada banyak kompleksitas. Perayap web sederhana masih sulit untuk bersaing dengan situs web modern yang dikembangkan oleh berbagai teknologi kompleks seperti pelatihan AJAX, XMLHTTPrequest, WebSockets, soket flash, dll.
Mari kita ambil kebutuhan dasar kita pada proyek HubDoc sebagai contoh, di mana kita merangkak jumlah tagihan, tanggal kedaluwarsa, nomor rekening, dan yang paling penting: PDF tagihan baru -baru ini dari situs web bank, utilitas dan perusahaan kartu kredit. Untuk proyek ini, saya mulai dengan solusi yang sangat sederhana (tidak menggunakan produk komersial mahal yang kami evaluasi untuk saat ini) - proyek crawler sederhana yang saya lakukan dengan Perl di MessageLab/Symantec. Tetapi hasilnya tidak berjalan dengan baik, dan spammer membuat situs web yang jauh lebih sederhana daripada bank dan utilitas.
Jadi bagaimana cara menyelesaikan masalah ini? Kami terutama mulai dengan perpustakaan permintaan yang sangat baik yang dikembangkan menggunakan Mikea. Buat permintaan di browser, dan periksa header permintaan apa yang dikirim di jendela jaringan, dan kemudian salin header permintaan ini ke dalam kode. Proses ini sangat sederhana. Ini hanya untuk melacak semua permintaan dari login ke mengunduh file PDF dan kemudian mensimulasikan semua permintaan dari proses ini. Untuk membuatnya lebih mudah untuk menangani hal -hal serupa dan membuat pengembang web lebih rasional dalam menulis program crawler, saya mengekspor hasil dari HTML ke jQuery (menggunakan perpustakaan cheato ringan), yang membuat pekerjaan serupa menjadi sederhana dan membuatnya lebih mudah untuk menggunakan pemilih CSS untuk memilih elemen dalam satu halaman. Seluruh proses dibungkus menjadi kerangka kerja, yang juga dapat melakukan pekerjaan tambahan, seperti mengambil sertifikat dari database, memuat robot individu, dan berkomunikasi dengan UI melalui socket.io.
Ini berfungsi untuk beberapa situs web, tetapi ini hanya skrip JS, bukan kode Node.js saya yang ditempatkan di situs mereka oleh perusahaan -perusahaan ini. Mereka dapat melapisi masalah sisa untuk mengatasi kompleksitas, membuatnya sangat sulit bagi Anda untuk mencari tahu apa yang harus dilakukan untuk mendapatkan titik informasi login. Untuk beberapa situs saya mencoba mendapatkannya dengan menggabungkannya dengan perpustakaan permintaan () selama beberapa hari, tetapi masih sia -sia.
Setelah hampir macet, saya menemukan Node-Phantomjs, sebuah perpustakaan yang memungkinkan saya untuk mengontrol browser Webkit headless phantomjs dari Node (Catatan Penerjemah: Saya tidak mengharapkan kata benda yang sesuai. Tanpa kepala berarti bahwa halaman render diselesaikan di latar belakang tanpa menampilkan perangkat). Ini sepertinya solusi sederhana, tetapi ada beberapa masalah yang tidak dapat dihindari oleh phantomj:
1.Phantomjs hanya dapat memberi tahu Anda apakah halaman telah dimuat, tetapi Anda tidak dapat menentukan apakah ada pengalihan (pengalihan) yang diimplementasikan melalui tag JavaScript atau meta dalam proses ini. Terutama ketika JavaScript menggunakan setTimeout () untuk menunda panggilan.
2.PhantomJS memberi Anda kait pageloadsarted yang memungkinkan Anda untuk menangani masalah yang disebutkan di atas, tetapi fungsi ini hanya dapat mengurangi nomor ini ketika Anda menentukan jumlah halaman untuk dimuat, dan menyediakan pemrosesan untuk kemungkinan waktu tunggu (karena ini tidak selalu terjadi), sehingga ketika nomor Anda dikurangi menjadi 0, fungsi callback Anda dapat dipanggil. Metode ini dapat berhasil, tetapi selalu membuat orang merasa seperti seorang peretas.
3.Phantomjs membutuhkan proses yang lengkap dan independen untuk setiap halaman untuk merangkak, karena jika ini bukan masalahnya, tidak mungkin untuk memisahkan cookie antara setiap halaman. Jika Anda menggunakan proses phantomjs yang sama, sesi di halaman yang telah masuk akan dikirim ke halaman lain.
4. Tidak dapat menggunakan phantomjs untuk mengunduh sumber daya - Anda hanya dapat menyimpan halaman sebagai PNG atau PDF. Ini bermanfaat, tetapi itu berarti kita perlu menggunakan untuk meminta () untuk mengunduh PDF.
5. Karena alasan di atas, saya harus menemukan cara untuk mendistribusikan cookie dari sesi phantomjs ke Pustaka Permintaan Sesi (). Cukup mendistribusikan document.cookie string, menguraikannya, dan menyuntikkannya ke toples cookie dari permintaan ().
6. Suntikan variabel ke dalam sesi browser tidak mudah. Untuk melakukan ini, saya perlu membuat string untuk membuat fungsi JavaScript.
Salinan kode adalah sebagai berikut:
Robot.prototype.add_page_data = fungsi (halaman, nama, data) {
Page.Evaluate (
"function () {var" + name + "= window." + nama + "=" + json.stringify (data) + "}"
);
}
7. Beberapa situs web selalu diisi dengan kode seperti Console.log (), dan mereka perlu didefinisikan ulang dan output ke lokasi yang kami inginkan. Untuk mencapai ini, saya melakukan ini:
Salinan kode adalah sebagai berikut:
if (! console.log) {
var iframe = document.createElement ("iframe");
document.body.appendChild (iframe);
konsol = window.frames [0] .console;
}
8. Beberapa situs web selalu diisi dengan kode seperti Console.log (), dan mereka perlu didefinisikan ulang dan output ke lokasi yang kami inginkan. Untuk mencapai ini, saya melakukan ini:
Salinan kode adalah sebagai berikut:
if (! console.log) {
var iframe = document.createElement ("iframe");
document.body.appendChild (iframe);
konsol = window.frames [0] .console;
}
9. Tidak mudah untuk memberi tahu browser yang saya klik pada tag A. Untuk mencapai hal -hal ini, saya menambahkan kode berikut:
Salinan kode adalah sebagai berikut:
var clickelement = window.clickeLement = function (id) {
var a = document.geteLementById (id);
var e = document.createEvent ("mouseEvents");
E.InitMouseEvent ("klik", true, true, window, 0, 0, 0, 0, false, false, false, false, 0, null);
a.dispatchevent (e);
};
10. Saya juga perlu membatasi konkurensi maksimum sesi browser untuk memastikan bahwa kami tidak akan meledak server. Meski begitu, batasan ini jauh lebih tinggi dari apa yang dapat ditawarkan solusi komersial mahal. (Catatan Penerjemah: Artinya, konkurensi solusi komersial lebih besar dari solusi ini)
Setelah semua pekerjaan, saya memiliki solusi crawler yang relatif layak untuk permintaan PhantomJS +. Anda harus masuk dengan phantomjs sebelum Anda dapat kembali ke permintaan permintaan (). Ini akan menggunakan cookie yang ditetapkan dalam phantomjs untuk memverifikasi sesi yang masuk. Ini adalah kemenangan besar karena kami dapat menggunakan aliran permintaan () untuk mengunduh file PDF.
Seluruh rencana adalah untuk membuatnya relatif mudah bagi pengembang web untuk memahami cara menggunakan pemilih jQuery dan CSS untuk membuat crawler untuk situs web yang berbeda. Saya belum berhasil membuktikan bahwa ide ini layak, tetapi saya percaya itu akan segera terjadi.