Cara Parsing HTML Dengan PHP Menggunakan DiDOM




Sesekali, developers perlu men scrape halaman web untuk mendapatkan beberapa informasi dari situs web.

Misalnya, kalian mengerjakan proyek pribadi di mana kalian harus mendapatkan informasi geografis tentang ibu kota berbagai negara dari Wikipedia. Memasukkan ini secara manual akan memakan banyak waktu. Namun, kalian bisa melakukannya dengan sangat cepat dengan menggores halaman Wikipedia dengan bantuan PHP. 

Kalian juga bisa mengurai HTML secara otomatis untuk mendapatkan informasi tertentu daripada melalui seluruh markup secara manual.

Dalam tutorial ini, kita akan belajar tentang parser HTML yang cepat dan mudah digunakan yang disebut DiDOM. Kita akan mulai dengan proses instalasi dan kemudian belajar cara mengekstrak informasi dari berbagai elemen di halaman web menggunakan berbagai jenis penyeleksi seperti tag, class, dll.

Instalasi dan Penggunaan

Kalian bisa dengan mudah menginstal DiDOM di direktori proyek kalian dengan menjalankan perintah berikut:

1:  composer require imangazaliev/didom  

Setelah kalian menjalankan perintah di atas, kalian akan dapat memuat HTML dari string, file lokal, atau halaman web. Berikut ini contohnya:

1:  require_once('vendor/autoload.php');  
2:  use DiDom\Document;  
3:  $document = new Document($bogor_html_string);  
4:  $document = new Document('bogor.html', true);  
5:  $url = 'https://id.wikipedia.org/wiki/Kota_Bogor';  
6:  $document = new Document($url, true);  

Saat kalian memutuskan untuk mengurai HTML dari dokumen, itu sudah bisa dimuat dan disimpan dalam variabel. Dalam kasus seperti itu, kalian cukup meneruskan variabel itu ke Document() dan DiDOM akan menyiapkan string untuk parsing.

Jika HTML harus dimuat dari file atau URL, kalian bisa meneruskannya sebagai parameter pertama ke Document() dan menyetel parameter kedua ke true.


Kalian juga bisa membuat objek Document baru dengan menggunakan new Document() tanpa parameter apa pun. Dalam kasus ini, kalian bisa memanggil metode loadHtml() untuk memuat HTML dari string dan loadHtmlFile() untuk memuat HTML dari file atau halaman web.

Menemukan Elemen HTML

Hal pertama yang harus kalian lakukan sebelum mendapatkan HTML atau teks dari suatu elemen adalah menemukan elemen itu sendiri. Cara termudah untuk melakukannya adalah dengan menggunakan metode find() dan meneruskan pemilih CSS untuk elemen yang kalian maksudkan sebagai parameter pertama.

Kalian juga bisa meneruskan XPath untuk sebuah elemen sebagai parameter pertama dari metode find(). Namun, ini mengharuskan kalian untuk meneruskan Query :: TYPE_XPATH sebagai parameter kedua.

Jika kalian hanya ingin menggunakan nilai XPath untuk menemukan elemen HTML, kalian cukup menggunakan metode xpath() alih-alih meneruskan Query :: TYPE_XPATH sebagai parameter kedua ke find() setiap saat.

Jika DiDOM dapat menemukan elemen yang cocok dengan pemilih CSS yang diteruskan atau ekspresi XPATH, ini akan mengembalikan array instance DiDom\Element. Jika tidak ada elemen yang ditemukan, itu akan mengembalikan array kosong.

Karena metode ini mengembalikan array, kalian bisa langsung mengakses elemen pencocokan ke-n dengan menggunakan find()[n-1].

Sebuah contoh

Dalam contoh berikut, kita akan mendapatkan HTML bagian dalam dari semua tajuk tingkat pertama dan kedua di artikel Wikipedia tentang Kota Bogor.

1:  require_once('vendor/autoload.php');  
2:  use DiDom\Document;  
3:  $document = new Document('https://id.wikipedia.org/wiki/Kota_Bogor', true);  
4:  $main_heading = $document->find('h1.firstHeading')[0];  
5:  echo $main_heading->html();  
6:  $sub_headings = $document->find('h2');  
7:  foreach($sub_headings as $sub_heading) {  
8:    if($sub_heading->text() !== 'See also') {  
9:      echo $sub_heading->html();  
10:    } else {  
11:      break;  
12:    }  
13:  }  

Kita mulai dengan membuat objek Dokumen baru dengan meneruskan URL artikel Wikipedia tentang Kota Bogor. 

Setelah itu, kita mendapatkan elemen heading utama menggunakan metode find() dan menyimpannya di dalam variabel bernama $main_heading. Kita sekarang akan dapat memanggil metode berbeda pada elemen ini seperti text(), innerHtml(), html(), dll.

Untuk heading utama, kita cukup memanggil metode html() yang mengembalikan HTML dari seluruh elemen heading. Demikian pula, kita bisa mendapatkan HTML di dalam elemen tertentu dengan menggunakan metode innerHtml(). Terkadang, kalian akan lebih tertarik dengan konten teks biasa dari suatu elemen daripada HTML-nya. Dalam kasus seperti itu, kalian cukup menggunakan metode text() dan selesai dengannya.

Judul tingkat dua (Headings level two) membagi halaman Wikipedia kita menjadi beberapa bagian yang terdefinisi dengan baik. Namun, kalian mungkin ingin menyingkirkan beberapa subpos seperti "Lihat juga", "Catatan", dll.

Salah satu cara untuk melakukannya adalah dengan mengulang semua judul tingkat dua dan memeriksa nilai yang dikembalikan oleh metode text(). Kita keluar dari loop jika teks judul yang dikembalikan adalah "Lihat juga".

Kalian bisa langsung menuju ke heading tingkat dua atau empat dengan menggunakan $document-> find('h2')[3] dan $document-> find('h2')[5].

Melintasi DOM ke Atas dan Bawah

Setelah kalian memiliki akses ke elemen tertentu, library memungkinkan kalian untuk melintasi ke atas dan ke bawah pohon DOM untuk mengakses elemen lain dengan mudah.

Kalian bisa pergi ke parent (induk) elemen HTML menggunakan metode parent(). Demikian pula, kalian bisa mendapatkan sibling berikutnya atau sebelumnya dari sebuah elemen menggunakan metode nextSibling() dan priorSibling().

Ada banyak metode yang tersedia untuk mendapatkan akses ke turunan dari elemen DOM juga. Misalnya, kalian bisa mendapatkan elemen child tertentu menggunakan metode child(n). Demikian pula, kalian bisa mendapatkan akses ke child pertama atau terakhir dari elemen tertentu menggunakan metode firstChild() dan lastChild(). Kalian bisa mengulang semua child dari elemen DOM tertentu menggunakan metode children().

Setelah kalian masuk ke elemen tertentu, kalian akan dapat mengakses HTML-nya dll. Menggunakan metode html(), innerHtml(), dan text().

Dalam contoh berikut, kita mulai dengan elemen heading level dua dan terus memeriksa apakah elemen sibling berikutnya berisi beberapa teks. Segera setelah kita menemukan elemen sibling dengan beberapa teks, kita menampilkannya ke browser.

1:  require_once('vendor/autoload.php');  
2:  use DiDom\Document;  
3:  $document = new Document('https://id.wikipedia.org/wiki/Kota_Bogor', true);  
4:  $sub_headings = $document->find('h2');  
5:  for($i = 1; $i < count($sub_headings); $i++) {  
6:    if($sub_headings[$i]->text() !== 'See also') {  
7:      $next_sibling = $sub_headings[$i]->nextSibling();  
8:      while(!$next_elem->html()) {  
9:        $next_sibling = $next_sibling->nextSibling();  
10:      }  
11:      echo $next_elem->html()."<br>";  
12:    } else {  
13:      break;  
14:    }  
15:  }  

Kalian bisa menggunakan teknik serupa untuk mengulang melalui semua elemen sibling dan hanya mengeluarkan teks jika mengandung string tertentu atau jika elemen sibling adalah tag paragraf, dll. Setelah kalian mengetahui dasar-dasarnya, bahwa menemukan informasi yang tepat itu mudah.

Memanipulasi Atribut Elemen

Kemampuan untuk mendapatkan atau menetapkan nilai atribut untuk elemen yang berbeda terbukti sangat berguna dalam situasi tertentu. Misalnya, kita bisa mendapatkan nilai atribut src untuk semua tag img di artikel Wikipedia kita dengan menggunakan $image_elem->attr('src'). Dengan cara yang sama, kalian bisa mendapatkan nilai atribut href untuk semua tag dalam dokumen.

Ada tiga cara untuk mendapatkan nilai atribut yang diberikan untuk elemen HTML. kalian dapat menggunakan metode getAttribute('attrName') dan meneruskan nama atribut yang kalian minati sebagai parameter. 

kalian juga bisa menggunakan metode attr('attrName'), yang bekerja seperti getAttribute(). Terakhir, library juga memungkinkan kalian untuk langsung mendapatkan nilai atribut menggunakan $elem->attrName. Ini berarti kalian bisa mendapatkan nilai atribut src untuk elemen gambar secara langsung dengan menggunakan $imageElem->src.

1:  require_once('vendor/autoload.php');  
2:  use DiDom\Document;  
3:  $document = new Document('https://id.wikipedia.org/wiki/Kota_Bogor', true);  
4:  $images = $document->find('img');  
5:  foreach($images as $image) {  
6:    echo $image->src."<br>";  
7:  }  

Setelah kalian memiliki akses ke atribut src, kalian bisa menulis kode untuk mengunduh semua file gambar secara otomatis. Dengan cara ini, kalian akan dapat menghemat banyak waktu.

Kalian juga dapat menyetel nilai atribut tertentu menggunakan tiga teknik berbeda. Pertama, kalian dapat menggunakan metode setAttribute('attrName', 'attrValue') untuk menyetel nilai atribut. kalian juga bisa menggunakan metode attr('attrName', 'attrValue') untuk menyetel nilai atribut. Terakhir, kalian bisa menyetel nilai atribut untuk elemen tertentu menggunakan $Elem->attrName = 'attrValue'.

Menambah, Menghapus dan Mengganti Elemen

Kalian juga dapat membuat perubahan pada dokumen HTML yang dimuat menggunakan metode berbeda yang disediakan oleh library. Misalnya, kalian bisa menambah, mengganti atau menghapus elemen dari pohon DOM menggunakan metode appendChild(), replace(), dan remove().

Library juga memungkinkan kalian untuk membuat elemen HTML kalian sendiri untuk menambahkannya ke dokumen HTML asli. Kalian bisa membuat objek Elemen baru dengan menggunakan new Element('tagName', 'tagContent').

Ingatlah bahwa kalian akan mendapatkan Kesalahan Tidak Tertangkap (Uncaught Error) : Class 'Elemen' tidak ditemukan (Class 'Element' not found) kesalahan jika program kalian tidak berisi baris, gunakan DiDom \ Element sebelum membuat instance objek elemen.

Setelah kalian memiliki elemen, kalian bisa menambahkannya ke elemen lain di DOM menggunakan metode appendChild() atau kalian bisa menggunakan metode replace() untuk menggunakan elemen yang baru dibuat sebagai pengganti beberapa elemen HTML lama dalam dokumen. Contoh berikut akan membantu memperjelas konsep ini lebih lanjut.

1:  require_once('vendor/autoload.php');  
2:  use DiDom\Document;  
3:  use DiDom\Element;  
4:  $document = new Document('https://id.wikipedia.org/wiki/Kota_Bogor', true);  
5:  // This will result in error.  
6:  echo $document->find('h2.test-heading')[0]->html()."\n";  
7:  $test_heading = new Element('h2', 'This is test heading.');  
8:  $test_heading->class = 'test-heading';  
9:  $document->find('h1')[0]->replace($test_heading);  
10:  echo $document->find('h2.test-heading')[0]->html()."\n";  

Awalnya, tidak ada elemen h2 di dokumen kita dengan class test-heading. Oleh karena itu, kita akan terus mendapatkan kesalahan jika kita mencoba mengakses elemen seperti itu.

Setelah memverifikasi bahwa tidak ada elemen seperti itu, kita membuat elemen h2 baru dan mengubah nilai atribut class nya menjadi test-heading.

Setelah itu, kita mengganti elemen h1 pertama dalam dokumen dengan elemen h2 yang baru kita buat. Menggunakan metode find() pada dokumen kita lagi untuk menemukan heading h2 dengan class test-heading akan mengembalikan elemen sekarang.

Kesimpulan

Tutorial ini membahas dasar-dasar parser PHP DiDOM HTML. Kita mulai dengan penginstalan dan kemudian belajar cara memuat HTML dari string, file, atau URL. Setelah itu, kami membahas cara menemukan elemen tertentu berdasarkan pemilih CSS atau XPath-nya. 

Kita juga belajar bagaimana mendapatkan sibling, parent, atau child dari suatu elemen. Bagian lainnya membahas bagaimana kita dapat memanipulasi atribut elemen tertentu atau menambah, menghapus, dan mengganti elemen dalam dokumen HTML.

Jika ada sesuatu yang kalian ingin saya klarifikasi di tutorial ini, silakan beri tahu saya di kolom komentar yah. See You Next Time :)