Menguasai Web Scraping dengan Xpath
Temukan langkah-langkah melakukan web scrapping yang efektif dengan Xpath Selector di sini.
Seorang Quality Assurance (QA) Engineer umumnya sudah pernah menggunakan CSS Selector untuk melakukan web scraping. Web scraping, web harvesting, atau disebut juga web data extraction merupakan kegiatan mengambil data tertentu secara semi-terstruktur dari sebuah halaman situs web. CSS Selector paling umum digunakan karena lebih singkat dan lebih popular. Meski demikian, ada selector lain yang meskipun tampak kompleks ternyata lebih powerful, yaitu XPath Selector. Artikel ini akan membahas tentang apa saja yang bisa kita lakukan untuk mengoptimalkan penggunaan XPath Selector.
Apa Itu XPath?
XML Path Language (Xpath) adalah sebuah ekspresi yang digunakan untuk menemukan node atau node-sets yang ada pada dokumen XML. Ekspresi XPath menggunakan notasi path, seperti pada URL, untuk menavigasi melalui struktur hirarki pada dokumen XML yang dapat secara fleksibel menunjuk pada elemen HTML yang spesifik.
Meskipun kurang popular, XPath memiliki banyak manfaat yang akan berguna bagi para QA. Dalam automation testing project misalnya, QA Engineer umumnya lebih memilih menggunakan id, name, dan class sebagai locator. Namun, terkadang kita tidak bisa menemukan atribut tersebut dalam DOM atau elemen tersebut berubah secara dinamis pada DOM. Pada situasi ini, kita dapat menggunakan XPath karena XPath dapat mereferensi berdasarkan relasi elemen dan juga dapat menemukan teks dalam elemen HTML.
Tipe-tipe XPath
Ada tiga tipe XPath:
1. Absolute XPath
Tipe ini selalu dimulai dari root node halaman HTML. Penggunaan Absolute XPath memang lebih cepat dibandingkan Relative XPath, namun tidak direkomendasikan karena alasan-alasan berikut:
- Memiliki ekspresi yang lebih panjang, sehingga lebih sulit untuk dibaca.
- Tidak fleksibel dan cenderung tidak bisa digunakan ketika terdapat perubahan struktur pada halaman web.
Meski demikian, XPath absolut dapat digunakan ketika XPath relatif tidak berjalan.
Syntax: Selalu dimulai dengan
/html
Contoh:
/html/body/div/div[2]/form/div[1]/input
2. Relative XPath
Tipe ini digunakan untuk menemukan elemen yang sehubungan dengan elemen lain yang diketahui. Gunakanlah relasi yang paling dekat sehingga ekspresi XPath tidak terlalu panjang.
Syntax: Dimulai dengan dua forward slash ‘//’.
Contoh:
//input[@type='password']
//div[@class='login__logo']/img
//label[@for='password']/..
3. Exact XPath
Tipe ini menemukan elemen menggunakan tag-name, attribute, value atau inner text dari elemen tersebut. Ini lebih sederhana dan tahan terhadap perubahan struktural halaman web.
Contoh: //a[text()=’Lupa Kata Sandi?’]
Penggunaan XPath
Ada tujuh node pada XPath, yaitu element, attribute, text, namespace, processing-instruction, comment, dan root. Dokumen XML adalah pohon yang terdiri dari node-node. Elemen teratas dari pohon tersebut adalah elemen root.
XPath Syntax
Berikut adalah daftar sintaksis elemen dasar yang akan sering dipakai untuk menyusun ekspresi XPath:
XPath Predicates
Predikat XPath dapat menyaring elemen-elemen yang ditemukan oleh ekpresi yang dibuat. Predikat ditulis dalam tanda kurung kotak ([predicate]). Berikut adalah contoh predikat:
Contoh Penggunaan XPath
Ada beberapa hal yang perlu dipertimbangkan ketika kita memilih XPath. Locator yang baik umumnya memiliki sifat unik, deskriptif, tahan terhadap perubahan struktural, dan singkat. Kali ini saya akan menggunakan halaman Log In di laman StarXperience sebagai contoh dalam penggunaan XPath untuk menemukan elemen.
Menemukan elemen dengan attribute yang diketahui
Syntax : //*[@attributeName='value']
Mari temukan bidang “username”:
XPath : //*[@id='id_username']
Menemukan elemen dengan multiple candidates
Xpath :
- Menemukan elemen kedua dalam form :
//form/*[2]
- Menemukan elemen terakhir dalam form :
//form/*[last()]
Menemukan elemen dengan tag-name dan attribute
Syntax : //tagName[@attributeName='value']
Mari temukan tombol “Submit”:
XPath : //input[@id='btn-login']
Menemukan elemen dengan teks statis yang terlihat (exact match)
Syntax : //tagName[text()='exact text']
Mari temukan label bidang “Password”:
XPath : //label[text()='Kata Sandi:']
Perlu diperhatikan bahwa teks yang ingin ditemukan bersifat case sensitive.
Menemukan elemen dengan sebagian teks statis (partial match)
Syntax :
//tagName[contains(text(),'substring')]
//tagName[contains(.,'substring')]
Mari temukan link “Daftar penyedia layanan”:
XPath : //a[contains(text(),'penyedia')]
Menemukan elemen ketika prefix inner text bersifat statis
Syntax : //tagName[starts-with(text(),'Prefix of inner text')]
Mari temukan link “Daftar Penyedia layanan” lagi:
XPath : //a[starts-with(text(),'Daftar')]
Menemukan elemen dengan multiple attribute
Syntax :
//tagName[@attribute1='value1'][@attribute2='value2']...[@attributeN='valueN']
//tagName[@attribute1='value1' and @attributeN='valueN']
Mari temukan bidang “Password”:
XPath : //input[@type='password'][@name='password']
Menemukan beberapa elemen dengan menggabungkan beberapa ekspresi XPath
Jika Anda menggunakan Selenium dan menggunakan metode findElement, hanya elemen pertama yang akan terpilih. Sebaliknya, jika Anda menggunakan metode findElements, maka semua elemen yang ditemukan akan terpilih.
Mari pilih elemen tombol “toggle show”/”hide teks” pada bidang “Password”.
Syntax : XPath1|XPath2|...|XPathN
XPath : //div[contains(@class,'mdi-eye-off')]|//div[contains(@class,'mdi-eye')]
Menemukan elemen dengan relasi dari elemen lain
Jika elemen target tidak memiliki sesuatu yang unik, kita harus menemukan elemen lain dengan relasi terdekat dengan XPath yang unik. Kita dapat menjadikan elemen tersebut sebagai elemen patokan atau landmark menuju target elemen. Kita akan analogikan relasi antar node ini dengan pohon keluarga.
Syntax : //<<knownXpath>>/relation::<elementName>
Untuk contoh penggunaan relasi, mari kita gunakan contoh halaman Pendaftaran pada web StarXperience.
1. Ancestor
Mari kita temukan elemen keseluruhan “Form Content” yang ada di langkah 1 Pendaftaran tanpa mengikutkan tombol “Selanjutnya”, dengan menggunakan elemen “Nama Badan Usaha” sebagai patokan:
Syntax :
//<<knownXpath>>/ancestor::<elementName>
XPath :
//input[@id='companyName']//ancestor::div[@class='form__content']
2. Parent
Parent adalah elemen yang berada tepat satu level di atas elemen landmark. Mari kita coba temukan elemen “Form Content” dengan elemen tulisan “Informasi Badan Usaha” sebagai patokan.
Syntax :
//<knownXpath>/parent::elementName
//<knownXpath>/..
XPath :
//div[text()='Informasi Badan Usaha']/..
3. Descendants
Mari temukan elemen email yang ada pada langkah 1 Pendaftaran dengan kontainer keseluruhan elemen di step 1 sebagai patokan karena memiliki id.
Syntax :
//<<knownXpath>>/descendant::<elementName>
XPath :
//div[@id='step1']/descendant::input[@type='email']
4. Child
Mari temukan elemen button selanjutnya yang ada di langkah 1 Pendaftaran. Kontainer keseluruhan elemen di langkah 1 sebagai patokan karena memiliki id.
Syntax :
//<knownXpath>/child::<elementName>
//<knownXpath>/<elementName>
XPath :
//div[@id='step1']/div/button
5. Following
Following:: dapat digunakan untuk menemukan elemen-elemen di manapun yang berada setelah elemen patokan secara urutan dokumen. Mari temukan elemen button “Selanjutnya” pertama dengan menjadikan bidang “Alamat Usaha” sebagai patokan.
Syntax :
//<<knownXpath>>/following::<elementName>
XPath :
//textarea[@id='address']/following::button[1]
6. Preceding
Preceding:: digunakan untuk menemukan elemen yang berada sebelum elemen patokan secara urutan dokumen.
Syntax :
//<<knownXpath>>/preceding::<elementName>
XPath :
//textarea[@id='address']/preceding::input[@name='email']
7. Following-Sibling
Following-sibling dapat digunakan untuk menemukan elemen pada level yang sama yang berada setelah elemen patokan pada dokumen HTML. Mari temukan elemen panduan nomor +62 pada bidang “No. Telepon Tempat Usaha”.
Syntax :
//<<knownXpath>>/following-sibling::<elementName>
XPath :
//label[text()='No. Telepon Tempat Usaha']/following-sibling::div[@class='icon']
8. Preceding-Sibling
Preceding-sibling dapat digunakan untuk menemukan elemen pada level yang sama yang berada sebelum elemen patokan pada dokumen HTML. Mari temukan elemen panduan nomor +62 pada bidang “No. Penanggung Jawab”.
Syntax :
//<<knownXpath>>/preceding-sibling::<elementName>
XPath :
//input[@id='picPhoneNumber']/preceding-sibling::div[@class='icon']
Kesimpulan
Meskipun memiliki fungsi yang sama dengan CSS Selector, XPath adalah alat yang serbaguna dan powerful. XPath memang terlihat lebih sulit dikuasai. Hal yang membuat menantang bukanl pada pembuatan ekspresi XPath itu sendiri, melainkan menemukan path yang tepat untuk menemukan elemen target dan pada saat yang sama bersifat fleksibel sehingga tahan terhadap perubahan pada DOM tree.