PHP ile Crawling İşlemi

Share Button

PHP ile Data Crawling

Eğer sizde benim gibi crawler yazmayı seviyorsanız, PHP nin DOMXPath objesi bu işi gerçekten oldukca kolaylaştırıyor. Ben daha önceki kendi denemelerimde metin işleme yoluyla aradığım veriye ulaşmayı tercih ediyordum. Ancak bu yöntem zaman açısından oldukca maliyetli oluyordu. Bunun yerine xPath sorgusundan yararlanarak veri çekmek gerçekten çok kolay.

Örnek olarak bigpara.com sitesindeki Dolar kurunun alış fiyatını crawle edelim. İlk olarak crawler kodumuzu yazalım.

mycrawler.php:

$url = ''; # Bu degiskenin icinde crawle edecegimiz sitenin url bilgisi yeralacak.
$xpath = ''; # Bu degiskenin icinde crawle edecegimiz verinin xpath adresi yeralacak.
$htmlContent = file_get_contents($url);
if(!$htmlContent) {
  throw new Exception('Failed to connection.');
}
libxml_use_internal_errors(true);   
$domObj = new DOMDocument();
$domObj->loadHTML($htmlContent);
$xPathObj = new DOMXPath($domObj);
$value = $xPathObj->query($xpath)->item(0)->firstChild->nodeValue;
print $value . PHP_EOL;

Şimdi de crawle edeceğimiz verinin xpath adresini alalım. Bu işlem için google chrome tarayıcısından yararlanacağız. XPath adresini tespit etmek için:

* Sayfayı google chrome ile açtıktan sonra verinin bulunduğu alanda fare ile sağ tıklayarak Inspect Element seçeneğine tıklayın.

* Tarayıcının alt kısmında açılan bölümdeki html kodları arasında okumak istediğiniz metni bulun ve üzerine sağ tıklayarak Copy as xPath seçeneğine tıklayın.

Şimdi de edindiğimiz xpath ve url bilgisini kodumuzun içine yerleştirelim.

$url = 'http://www.bigpara.com/dolar/?bprtme=1463181297&sTo=301'; # Bu degiskenin icinde crawle edecegimiz sitenin url bilgisi yeralacak.
$xpath = '//*[@id="content"]/div[2]/div[1]/div[3]/div[2]/strong'; # Bu degiskenin icinde crawle edecegimiz verinin xpath adresi yeralacak.
...

Artık kodumuzu çalıştırmaya hazırız. Hemen bir terminal açalım ve php betiğimizi çalıştıralım.
shell:

$ php mycrawler.php

Sonuç:

1,985
Share Button

About İbrahim Gündüz

1983 yılında İstanbul’da doğdu. İlkokul yıllarında cobol ve basic le olan tanışması, yazılıma olan ilgisini arttırdı 2005 yılında. Uludağ Üniversitesi Teknik Bilimler Meslek Yüksek Okulu Elektronik bölümünden mezun olan Gündüz, çeşitli alanlarda faaliyet gösteren kurumlarda yazılım geliştirici olarak görev almıştır. Mesleki ilgi alanları, ölçeklenebilir sistemler, uygulama entegrasyonları ve ödeme sistemleridir. Halen Markafoni back end geliştirici olarak çalışmaktadır.

11 Comments

  • Berk Aslan
    Eylül 3, 2013 - 10:32 am | Permalink

    Merhaba, öncelikle bu güzel yöntemi bizimle paylaştığınız için teşekkürler.
    $xPathObj = DOMXPath($domObj) satırında DOMXPatch fonksiyonunu bulamadığına dair bir hata veriyor.

    • Berk Aslan
      Eylül 3, 2013 - 10:33 am | Permalink

      $xPathObj = new DOMXPath($domObj); dediğimizde düzeliyor. new anahtarı unutulmuş.

  • Eylül 3, 2013 - 1:38 pm | Permalink

    Çok teşekkürler. Python’dan alışkanlık. new anahtarını eklemeyii atlamışım.

  • Eylül 9, 2013 - 8:17 am | Permalink

    Yegane dostum : PHPQuery https://code.google.com/p/phpquery/

  • Burak Ateş
    Mayıs 20, 2014 - 9:28 am | Permalink

    Merhaba,

    Öncelikle paylaşımın için çok teşekkür.

    Bu kodu belirli bir ürün değil de input ile girilen ürünü arayacak hale nasıl getirebiliriz?

    Yardımcı olursan sevinirim.

    • Mayıs 20, 2014 - 5:23 pm | Permalink

      Selamlar,
      Tarıyıcıyı taklit ederek, sitenin arama sırasında karşıya gönderdiği verileri curl ile gönderir ve sonucu örnekteki gibi parse edebilirsin.

  • Metin
    Mayıs 24, 2014 - 7:09 pm | Permalink

    Merhaba,

    Peki ürünün fiyatı dışında siteden resminide çekmek istesek nasıl bir kod yazmamız gerekir, onu halledemedim de…

    • Mayıs 25, 2014 - 6:37 pm | Permalink

      Aslında orada asıl anlatılmak istenen, PHP ile DOM objelerine ve niteliklerine nasıl ulaşılabileceğiydi. Parse etmek istediğiniz sayfadaki imajlarda aslında birer DOM objesi. Imaja ait xpath üzerinden ilgili imajın yol bilgisine (src niteliğine ait değer) ulaşırsınız ve bu yoldaki resmi file_get_contents veya curl ile okuyup bir dosyaya yazabilirsiniz. Aynı şekilde imajlara xpath dışında DomDocument in diğer metodlarıyla da (getElementsByTagName gibi) ulaşarak crawle etmeye çalıştığınız sitedeki birden fazla imajı da okuyabilirsiniz.

      • Metin
        Mayıs 26, 2014 - 1:36 pm | Permalink

        İbrahim Bey, tam anlayamadım. Şimdi image dosyasınının xpathini aldım ve xpathres olarak kaydettim diyelim. resmin linkini çekeceğim kodu yada resmi ekranda göstereceğim kodu yazabilirseniz gerçekten çok sevinirim.
        Saygılar,

  • Berat
    Mayıs 27, 2014 - 12:56 pm | Permalink

    Merhaba,

    Metin arkadaşımız ile aynı istekte bulunacaktım. örnek kod ile yardımcı olabilir misiniz? resmin xpathını aldığımızı düşünün linkini nasıl elde edip <img src=… içerisinde yazdırabiliriz?

  • Mayıs 27, 2014 - 6:56 pm | Permalink

    Sitedeki örnekte belirtilen bigpara.com sitesinin tepesindeki logoyu crawle edeceğimizi varsayalım.

    1. Logoyu görüntüleyen img objesinin xpath bilgisini tarayıcı marifetiyle tespit edelim.
    //*[@id=”header”]/div[2]/a/img

    2. Sayfa içeriğini file_get_contents veya CURL ile yükleyelim ve DOMDocument nesnesi ile sayfayı parse edelim.

    $url = 'http://www.bigpara.com/index.html';
    $xpath = '//*[@id="header"]/div[2]/a/img';
    $htmlContent = file_get_contents($url);
    if(!$htmlContent) {
        throw new Exception('Failed to connection.');
    }
    libxml_use_internal_errors(true);
    $domObj = new DOMDocument();
    $domObj->loadHTML($htmlContent);
    

    3. DOMXPath ile imajı xpath i üzerinden dökümandan sorgulayalım ve src attribute unda yazan değere ulaşaım.

    $xPathObj = new DOMXPath($domObj);
    $imageSource = $xPathObj->query($xpath)->item(0)->attributes->getNamedItem('src')->textContent;
    

    4. img objesinin src niteliğinden örnekde olduğu gibi “/Content/images/bigpara-logo.jpg” şeklinde yalnızca resmin yolu dönüyorsa sitenin url ini path bilgisinin başına ekleyip file_get_content ile imajı ilgili urlden okuyun.

    $parsedUrl = pathinfo($url);
    $imageUrl = sprintf("%s%s", $parsedUrl['dirname'], $imageSource);
    $imageData = file_get_contents($imageUrl);
    

    5. Okuduğunuz resim verisini bir dosya ismi verip diske yazalım.

    $ext = array_reverse(explode(".", $imageUrl))[0];
    $fileName = sprintf('myfile.%s', $ext);
    file_put_contents($fileName, $imageData);
    
  • Bir Cevap Yazın

    E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir