Pengikisan Web Modern dengan Python dan Selenium

Diterbitkan: 2022-03-11

Pengikisan web telah digunakan untuk mengekstrak data dari situs web hampir sejak World Wide Web lahir. Pada hari-hari awal, pengikisan terutama dilakukan pada halaman statis – yang memiliki elemen, tag, dan data yang diketahui.

Baru-baru ini, bagaimanapun, teknologi canggih dalam pengembangan web telah membuat tugas sedikit lebih sulit. Dalam artikel ini, kita akan mengeksplorasi bagaimana kita bisa melakukan scraping data jika teknologi baru dan faktor lain mencegah scraping standar.

Pengikisan Data Tradisional

Karena sebagian besar situs web menghasilkan halaman yang dimaksudkan untuk keterbacaan manusia daripada membaca otomatis, pengikisan web terutama terdiri dari mencerna data mark-up halaman web secara terprogram (pikirkan klik kanan, Lihat Sumber), kemudian mendeteksi pola statis dalam data itu yang akan memungkinkan program untuk "membaca" berbagai informasi dan menyimpannya ke file atau database.

Pengikisan Data

Jika data laporan ditemukan, seringkali, data dapat diakses dengan meneruskan variabel bentuk atau parameter dengan URL. Sebagai contoh:

 https://www.myreportdata.com?month=12&year=2004&clientid=24823

Python telah menjadi salah satu bahasa pengikisan web paling populer sebagian karena berbagai perpustakaan web yang telah dibuat untuk itu. Salah satu perpustakaan populer, Beautiful Soup, dirancang untuk menarik data dari file HTML dan XML dengan memungkinkan pencarian, navigasi, dan modifikasi tag (yaitu, pohon parse).

Pengikisan berbasis browser

Baru-baru ini, saya memiliki proyek pengikisan yang tampaknya cukup mudah dan saya sepenuhnya siap untuk menggunakan pengikisan tradisional untuk menanganinya. Tetapi ketika saya masuk lebih jauh, saya menemukan hambatan yang tidak dapat diatasi dengan metode tradisional.

Tiga masalah utama mencegah saya dari metode pengikisan standar saya:

  1. Sertifikat. Ada sertifikat yang harus diinstal untuk mengakses bagian situs web tempat data berada. Saat mengakses halaman awal, sebuah prompt muncul meminta saya untuk memilih sertifikat yang tepat dari yang terinstal di komputer saya, dan klik OK.
  2. iframe. Situs ini menggunakan iframe, yang mengacaukan pengikisan normal saya. Ya, saya dapat mencoba menemukan semua URL iframe, lalu membuat peta situs, tetapi sepertinya itu bisa menjadi berat.
  3. JavaScript. Data diakses setelah mengisi formulir dengan parameter (misalnya, ID pelanggan, rentang tanggal, dll.). Biasanya, saya akan melewati formulir dan hanya meneruskan variabel formulir (melalui URL atau sebagai variabel formulir tersembunyi) ke halaman hasil dan melihat hasilnya. Tetapi dalam kasus ini, formulir berisi JavaScript, yang tidak mengizinkan saya untuk mengakses variabel formulir secara normal.

Jadi, saya memutuskan untuk meninggalkan metode tradisional saya dan mencari alat yang memungkinkan untuk pengikisan berbasis browser. Ini akan bekerja secara berbeda dari biasanya – alih-alih langsung membuka halaman, mengunduh pohon parse, dan mengeluarkan elemen data, saya malah “bertindak seperti manusia” dan menggunakan browser untuk membuka halaman yang saya butuhkan, lalu mengikis data - dengan demikian, melewati kebutuhan untuk menangani hambatan yang disebutkan.

Selenium

Secara umum, Selenium dikenal sebagai kerangka kerja pengujian sumber terbuka untuk aplikasi web – memungkinkan spesialis QA untuk melakukan pengujian otomatis, menjalankan pemutaran, dan menerapkan fungsionalitas kendali jarak jauh (memungkinkan banyak instance browser untuk pengujian beban dan beberapa jenis browser). Dalam kasus saya, ini sepertinya bisa berguna.

Bahasa masuk saya untuk web scraping adalah Python, karena memiliki perpustakaan yang terintegrasi dengan baik yang umumnya dapat menangani semua fungsi yang diperlukan. Dan tentu saja, perpustakaan Selenium ada untuk Python. Ini akan memungkinkan saya untuk membuat "browser" – Chrome, Firefox, IE, dll. – kemudian berpura-pura saya menggunakan browser sendiri untuk mendapatkan akses ke data yang saya cari. Dan jika saya tidak ingin browser benar-benar muncul, saya dapat membuat browser dalam mode "tanpa kepala", membuatnya tidak terlihat oleh pengguna mana pun.

Pengaturan Proyek

Untuk mulai bereksperimen, saya perlu menyiapkan proyek saya dan mendapatkan semua yang saya butuhkan. Saya menggunakan mesin Windows 10 dan memastikan saya memiliki versi Python yang relatif diperbarui (itu v. 3.7.3). Saya membuat skrip Python kosong, lalu memuat pustaka yang saya pikir mungkin diperlukan, menggunakan PIP (penginstal paket untuk Python) jika saya belum memuat pustaka. Ini adalah perpustakaan utama yang saya mulai:

  1. Permintaan (untuk membuat permintaan HTTP)
  2. URLLib3 (penanganan URL)
  3. Sup Cantik (kalau-kalau Selenium tidak bisa menangani semuanya)
  4. Selenium (untuk navigasi berbasis browser)

Saya juga menambahkan beberapa parameter panggilan ke skrip (menggunakan perpustakaan argparse) sehingga saya bisa bermain-main dengan berbagai kumpulan data, memanggil skrip dari baris perintah dengan opsi yang berbeda. Itu termasuk ID Pelanggan, dari bulan/tahun, dan ke bulan/tahun.

Masalah 1 – Sertifikat

Pilihan pertama yang harus saya buat adalah browser mana yang akan saya beri tahu Selenium untuk digunakan. Karena saya biasanya menggunakan Chrome, dan itu dibangun di atas proyek Chromium open-source (juga digunakan oleh browser Edge, Opera, dan Amazon Silk), saya pikir saya akan mencobanya terlebih dahulu.

Saya dapat memulai Chrome di skrip dengan menambahkan komponen perpustakaan yang saya butuhkan, lalu mengeluarkan beberapa perintah sederhana:

 # Load selenium components from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait, Select from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException # Establish chrome driver and go to report site URL url = "https://reportdata.mytestsite.com/transactionSearch.jsp" driver = webdriver.Chrome() driver.get(url)

Karena saya tidak meluncurkan browser dalam mode tanpa kepala, browser benar-benar muncul dan saya dapat melihat apa yang dilakukannya. Itu segera meminta saya untuk memilih sertifikat (yang telah saya instal sebelumnya).

Masalah pertama yang harus ditangani adalah sertifikat. Bagaimana memilih yang tepat dan menerimanya untuk masuk ke situs web? Dalam pengujian skrip pertama saya, saya mendapatkan Prompt ini:

Pengikisan Data

Ini tidak baik. Saya tidak ingin mengklik tombol OK secara manual setiap kali saya menjalankan skrip saya.

Ternyata, saya dapat menemukan solusi untuk ini - tanpa pemrograman. Sementara saya berharap Chrome memiliki kemampuan untuk memberikan nama sertifikat saat startup, fitur itu tidak ada. Namun, Chrome memang memiliki kemampuan untuk memilih sertifikat secara otomatis jika ada entri tertentu di registri Windows Anda. Anda dapat mengaturnya untuk memilih sertifikat pertama yang dilihatnya, atau lebih spesifik. Karena saya hanya memuat satu sertifikat, saya menggunakan format generik.

Pengikisan Data

Jadi, dengan set itu, ketika saya memberi tahu Selenium untuk meluncurkan Chrome dan prompt sertifikat muncul, Chrome akan "Pilih Otomatis" sertifikat dan melanjutkan.

Masalah 2 – Iframe

Oke, jadi sekarang saya berada di situs dan formulir muncul, meminta saya untuk mengetikkan ID pelanggan dan rentang tanggal laporan.

Pengikisan Data

Dengan memeriksa formulir di alat pengembang (F12), saya perhatikan bahwa formulir itu disajikan dalam iframe. Jadi, sebelum saya bisa mulai mengisi formulir, saya perlu "beralih" ke iframe yang tepat di mana formulir itu ada. Untuk melakukan ini, saya menggunakan fitur switch-to Selenium, seperti:

 # Switch to iframe where form is frame_ref = driver.find_elements_by_tag_name("iframe")[0] iframe = driver.switch_to.frame(frame_ref)

Bagus, jadi sekarang di bingkai yang tepat, saya dapat menentukan komponen, mengisi bidang ID pelanggan, dan memilih tarik-turun tanggal:

 # Find the Customer ID field and populate it element = driver.find_element_by_name("custId") element.send_keys(custId) # send a test id # Find and select the date drop-downs select = Select(driver.find_element_by_name("fromMonth")) select.select_by_visible_text(from_month) select = Select(driver.find_element_by_name("fromYear")) select.select_by_visible_text(from_year) select = Select(driver.find_element_by_name("toMonth")) select.select_by_visible_text(to_month) select = Select(driver.find_element_by_name("toYear")) select.select_by_visible_text(to_year)

Masalah 3 – JavaScript

Satu-satunya yang tersisa di formulir adalah "mengklik" tombol Temukan, sehingga pencarian akan dimulai. Ini sedikit rumit karena tombol Temukan tampaknya dikendalikan oleh JavaScript dan bukan tombol tipe "Kirim" yang normal. Memeriksanya di alat pengembang, saya menemukan gambar tombol dan bisa mendapatkan XPath-nya, dengan mengklik kanan.

Pengikisan Data

Kemudian, berbekal informasi ini, saya menemukan elemen di halaman, lalu mengkliknya.

 # Find the 'Find' button, then click it driver.find_element_by_xpath("/html/body/table/tbody/tr[2]/td[1]/table[3]/tbody/tr[2]/td[2]/input").click()

Dan voila, formulir telah dikirimkan dan data muncul! Sekarang, saya bisa mengikis semua data di halaman hasil dan menyimpannya sesuai kebutuhan. Atau bisa?

Mendapatkan Data

Pertama, saya harus menangani kasus di mana pencarian tidak menemukan apa pun. Itu cukup mudah. Itu akan menampilkan pesan pada formulir pencarian tanpa meninggalkannya, seperti "Tidak ada catatan yang ditemukan." Saya hanya mencari string itu dan berhenti di sana jika saya menemukannya.

Tetapi jika hasilnya memang datang, data disajikan dalam div dengan tanda plus (+) untuk membuka transaksi dan menampilkan semua detailnya. Transaksi yang dibuka menunjukkan tanda minus (-) yang bila diklik akan menutup div. Mengklik tanda plus akan memanggil URL untuk membuka div dan menutup div yang terbuka.

Pengikisan Data

Oleh karena itu, perlu untuk menemukan tanda plus di halaman, mengumpulkan URL di sebelah masing-masing, lalu mengulang setiap untuk mendapatkan semua data untuk setiap transaksi.

 # Loop through transactions and count links = driver.find_elements_by_tag_name('a') link_urls = [link.get_attribute('href') for link in links] thisCount = 0 isFirst = 1 for url in link_urls: if (url.find("GetXas.do?processId") >= 0): # URL to link to transactions if isFirst == 1: # already expanded + isFirst = 0 else: driver.get(url) # collapsed +, so expand # Find closest element to URL element with correct class to get tran type tran_type=driver.find_element_by_xpath("//*[contains(@href,'/retail/transaction/results/GetXas.do?processId=-1')]/following::td[@class='txt_75b_lmnw_T1R10B1']").text # Get transaction status status = driver.find_element_by_class_name('txt_70b_lmnw_t1r10b1').text # Add to count if transaction found if (tran_type in ['Move In','Move Out','Switch']) and (status == "Complete"): thisCount += 1

Pada kode di atas, field yang saya ambil adalah jenis transaksi dan statusnya, kemudian ditambahkan ke hitungan untuk menentukan berapa banyak transaksi yang sesuai dengan aturan yang ditentukan. Namun, saya dapat mengambil bidang lain dalam detail transaksi, seperti tanggal dan waktu, subtipe, dll.

Untuk proyek ini, hitungan dikembalikan ke aplikasi pemanggil. Namun, itu dan data tergores lainnya dapat disimpan dalam file datar atau database juga.

Kemungkinan Hambatan dan Solusi Tambahan

Banyak kendala lain yang mungkin muncul saat menggores situs web modern dengan browser Anda sendiri, tetapi sebagian besar dapat diselesaikan. Berikut adalah beberapa:

  • Mencoba menemukan sesuatu sebelum itu muncul

    Saat menjelajah sendiri, seberapa sering Anda menemukan bahwa Anda menunggu halaman muncul, terkadang selama beberapa detik? Nah, hal yang sama dapat terjadi saat menavigasi secara terprogram. Anda mencari kelas atau elemen lain – dan itu tidak ada!

    Untungnya, Selenium memiliki kemampuan untuk menunggu hingga elemen tertentu terlihat, dan dapat habis jika elemen tidak muncul, seperti:

 element = WebDriverWait(driver, 10). until(EC.presence_of_element_located((By.ID, "theFirstLabel")))


  • Melewati Captcha

    Beberapa situs menggunakan Captcha atau sejenisnya untuk mencegah robot yang tidak diinginkan (yang mungkin mereka anggap Anda). Ini dapat meredam gesekan web dan memperlambatnya.

Untuk petunjuk sederhana (seperti "berapa 2 + 3?"), Ini umumnya dapat dibaca dan dipahami dengan mudah. Namun, untuk hambatan yang lebih maju, ada perpustakaan yang dapat membantu mencoba memecahkannya. Beberapa contohnya adalah 2Captcha, Death by Captcha, dan Bypass Captcha.

  • Perubahan struktural situs web

    Situs web dimaksudkan untuk berubah – dan mereka sering melakukannya. Itu sebabnya saat menulis skrip scraping, yang terbaik adalah mengingat hal ini. Anda perlu memikirkan metode mana yang akan Anda gunakan untuk menemukan data, dan mana yang tidak digunakan. Pertimbangkan teknik pencocokan sebagian, daripada mencoba mencocokkan seluruh frasa. Misalnya, situs web mungkin mengubah pesan dari “Tidak ada catatan yang ditemukan” menjadi “Tidak ada catatan yang ditemukan” – tetapi jika kecocokan Anda ada di “Tidak ada catatan”, Anda seharusnya baik-baik saja. Juga, pertimbangkan apakah akan cocok dengan XPATH, ID, nama, teks tautan, tag atau nama kelas, atau pemilih CSS – dan yang paling kecil kemungkinannya untuk berubah.

Ringkasan: Python dan Selenium

Ini adalah demonstrasi singkat untuk menunjukkan bahwa hampir semua situs web dapat dihapus, tidak peduli teknologi apa yang digunakan dan kerumitan apa yang terlibat. Pada dasarnya, jika Anda dapat menelusuri situs itu sendiri, biasanya situs tersebut dapat dikikis.

Sekarang, sebagai peringatan, itu tidak berarti bahwa setiap situs web harus dihapus. Beberapa memiliki batasan yang sah, dan ada banyak kasus pengadilan yang memutuskan legalitas pengikisan situs tertentu. Di sisi lain, beberapa situs menyambut dan mendorong data untuk diambil dari situs web mereka dan dalam beberapa kasus menyediakan API untuk mempermudah segalanya.

Bagaimanapun, yang terbaik adalah memeriksa syarat dan ketentuan sebelum memulai proyek apa pun. Tetapi jika Anda terus maju, yakinlah bahwa Anda dapat menyelesaikan pekerjaan.

Sumber Daya yang Direkomendasikan untuk Pengikisan Web Kompleks:

  • Pengikisan Web Python Tingkat Lanjut: Praktik & Solusi Terbaik
  • Pengikisan do-it-yourself yang dapat diskalakan: Cara membuat dan menjalankan pencakar dalam skala besar