Bot yazacaklar için yol haritası 3 [Anlatım] ÖRNEK BOT YAPIMI'nın Devamı

19 May 2020
238
84
1. bölüm
2. bölüm
3. bölüm (şuan buradasınız)


Merhaba,

Bir önceki konuda yapacağımız bot için önce sorgulama yapabileceğimiz ve json olarak çıktı alabileceğimiz bir api oluşturmuştuk ve kitaplarla alakalı bilgilere bu süreçte erişim sağlamıştık. Peki nedir bu JSON? json bütün program dilleri için geçerli olan bir metin biçimidir ve bu metinler üzerinden farklı uygulamalarla veri alışverişinde bulunabilirsiniz. kısa bir örnek vermek gerekirse.

PHP:
$JSON_METNI = '{"durum":false,"hata":"sayfa bulunamadı"}';
$obje = json_decode($JSON_METNI);
echo $obje->durum == false ? $obje->hata : "hata yoksa çalışacak kısım";
/*
veya
*/
$array = json_decode($JSON_METNI, true);
echo $array["durum"] == false ? $array["hata"] : "hata yoksa çalışacak kısım";
kategori php olduğu için php üzerinden örneklendirdim. herhangi bir dil ile de bunu yapabilirdik. kısa koşul yazmayı da bu konunun başında belirtmiştim.

json hakkında fikir sahibi olduysanız eğer, botumuza geri dönebiliriz. ne demiştik, uzak sunucudaki kitapları bulacağız ve daha sonrasında bu kitapları okuyacağız, okutacağız. bu sefer kullanacağımız sınıf yapısı bir öncekine göre birazcık daha karmaşık, dolayısıyla tam bir kronolojisi yok, elimden geldiğince detaylandırarak anlamanız için çabalayacağım. ne demiştik önceki konuda, işe başlamadan önce mutlaka uzun uzadıya düşünmek gerekir. Bende bu istekleri bir komut olarak yazmayı uygun gördüm, elimde kendi kullanımım için yazdığım bir araç olduğu için, dedim ki onun eklentisiymiş gibi kullanırım. hadi başlayalım.

PHP:
    public function PdfHunterID(){
        return str_replace(array('PdfHunter -p 0 ', 'PdfHunter -p 1 '), '', $this->Inputs(0)->PdfHunter);
    }

öncelikle bunun ne olduğuna değinmek istiyorum $this->Inputs(0)->PdfHunter bu aslında farklı bir class da gelen postlar için yaptırdığım bir kontrol. siz bunu $_POST["id"] olarak düşünebilirsiniz. kafanız karışmasın yani. burada gönderdiğimiz değerden id değerini alıyoruz, anlatılacak karmaşık bir tarafımı yok.


PHP:
    public function BaglantiyiBul(){
        $ara = $this->PdfHunterID();
        $dosya = "addon/Onbellek/searchurl/".$ara.date('d-m-Y-H-i').".txt";
        if(file_exists($dosya)){
            $sonuc = file_get_contents($dosya);
        }else{
            $url = "https://www.pdfdrive2.com/kan-e$ara.html";
            $curl = curl_init($url);
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_HEADER, true);
            $resp = curl_exec($curl);
            curl_close($curl);
            preg_match('@Location:(.*?)X-Frame-Options:@si', $resp, $sonuc);
            $url = "https://www.pdfdrive2.com".trim($sonuc[1]);
            file_put_contents($dosya, $url);
            $sonuc = file_get_contents($dosya);
        }
        return !empty($sonuc) ? trim($sonuc) : die('www.pdfdrive2.com header(Location: ***) bilgisini değiştirmiş olabilir. Lütfen farklı bir id dene.');
    }
önceki konuda yaptığımız analiz çalışmasını hatırlamışsınızdır. hatırlamayanlar konunun ilgili bölümünü tekrar okusun. önceki konuda buna benzer bir metot'u detaylı olarak sizlere anlatmış ve neden böyle bir dosya kontrolü yapmamız gerektiğinden bahsetmiştim. bu yüzden bu kısmı da es geçiyorum. burada göze çarpan tek unsur var fark ettiniz mi bilmiyorum.
Kod:
CURLOPT_HEADER
nedir bu? bu arkadaş sunucu yanıtlarını okumamızı sağlayan curl içi bir özellik. $url değişkeninde fark ettiyseniz /kan-e{id} şeklinde bir bağlantı isteği gönderdim. peki neden kan yazdım? normalde o sitede böyle bir url yok, ancak biz oraya bir string ve bir interval değer bildirdik. string değerin hatalı olması durumunda parametredeki interval değere başvuracak ve bizi bir 404 sayfasına yönlendirmektense doğru sayfaya yönlendirecek. yani gitmek istediğimiz sayfayı bulmak için isteyerek yanlış sayfaya yöneliyoruz. bunu size gösterek anlatmakta fayda var.
c7xuxav.jpg

tarayıcıda isteyerek olmayan bir url'e doğru interval değerler ile istekte bulundum. daha sonrasında beni ben farkında bile olmadan doğru sayfaya yönlendirdi. işte biz buradaki hata için verilen istisnai durumdan faydalanarak, gerçek sayfayı bulduk ve hemen bir dosya içerisine yazdık ki, ilerleyen işlemlerde tekrar curl ile bu istek çalıştırılmasın ve dosyadan okuyalım. kısacası bizim için bu adresi kaydediyor. sonuç;
Kod:
https://www.pdfdrive2.com/satranç-stefan-zweig-e117517380.html


PHP:
    public function SonBaglanti(){
        $ara = $this->PdfHunterID();
        $dosya = "addon/Onbellek/searchurl2/".$ara.date('d-m-Y-H-i').".txt";
        if(file_exists($dosya)){
            $sonuc = file_get_contents($dosya);
        }else{
            $url = $this->BaglantiyiBul();
            $curl = curl_init($url);
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            $resp = curl_exec($curl);
            curl_close($curl);
            $altpattern = str_replace(array('https://www.pdfdrive2.com', 'e'.$ara), array('', 'd'.$ara), $url);
            $mainpattern = '@<button type="button" id="previewButtonMain" class="btn btn-warning btn-responsive" data-id="'.$ara.'" data-preview="(.*?)" data-download-page="'.$altpattern.'" @si';
            preg_match($mainpattern, $resp, $sonuc);
            $url = "https://www.pdfdrive2.com".trim($sonuc[1]);
            file_put_contents($dosya, $url);
            $sonuc = file_get_contents($dosya);
        }
        return !empty($sonuc) ? trim($sonuc) : die('Lütfen farklı bir id dene.');
    }
evet burada işler benim için biraz karışmıştı yaparken, çünkü indirme bağlantıları için geçerli bir oturum değeri istiyordu site. önceki konudaki analiz olayının ne kadar kritik olduğunu bir kez daha bu noktada anlamışsınızdır umarım. şimdi önceki curl isteğimizde biz belirtilen id için doğru kitap sayfasını bulmuştuk, şimdi kitabı indirmek için çeşitli yollara başvuracağız. burada bu işlemi yaparken indirme bağlantısını değil de, önizleme kısmını kullanacağım. normal bir kullanıcı için "indirme" butonu mantıklı görünebilir, ama arkaplanda gerçekleşen olaylarda daha çok yönlendirme söz konusu olduğu için, bot kullanıcı daha az yönlendirmesi olan "önizleme" butonuna tıklayacak. böylece bir aşama daha kat etmiş olacağız.
18by24a.jpg

Kod:
https://www.pdfdrive2.com/ebook/preview?id=117517380&session=a934fa8f050d12b5dcea6960dd7f0350
dosyamıza bu url'i de kaydetmiş olduk


PHP:
    public function KitabiBul(){
        $ara = $this->PdfHunterID();
        $dosya = "addon/Onbellek/ids/$ara.txt";
         if(file_exists($dosya)){
             $sonuc = file_get_contents($dosya);
         }else{
             $url = $this->SonBaglanti();
             $curl = curl_init($url);
             curl_setopt($curl, CURLOPT_URL, $url);
             curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
             curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
             curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
             curl_setopt($curl, CURLOPT_HEADER, true);
             $resp = curl_exec($curl);
             curl_close($curl);
             preg_match('@Location:(.*?)X-Frame-Options:@si', $resp, $sonuc);
             $pdf = str_replace('https://docs.google.com/gview?url=', '', $sonuc[1]);
             $url = str_replace(" ", "+", urldecode(ltrim($pdf)));
             file_put_contents($dosya, $url);
             $sonuc = file_get_contents($dosya);
         }
         return !empty($sonuc) ? trim($sonuc) : die($ara.' için sonuç bulunamadı veya tanımlanamayan bir url sebebi ile istek gerçekleştirilemedi.');
    }

önceki metotda aldığımız url bilgisi ile, bu metot da o url için bir istekte bulunuyoruz. artık bu çalışmada ki curl yapısına aşina odluğunuz için bu metot için çokta detaylandırma yapmayacağım. adrese bağlanınca, bizi farklı bir adrese yönlendiriyor. bu bilgiyi almak için yine CURLOPT_HEADER opsiyonundan yararlanıyoruz ve sunucu yanıtını okuyoruz.
j4rr1fn.jpg

hadi ama!.. metot yazarak anlattım, metot da bulunan kodları açıklayarak anlattım, görselle de anlattım, beni eşofmanlı şevket hocaya bağlatmayın : ) bu sayede google üzerinden, uzak sunucudaki dosyanın ön izlemesini gerçekleştirdik ve bu url değerinide önbelleğimize aldık arkadaşlar. bu nasıl yaptık? google'ın url parametresinin değerini alarak url'i decode işleminden geçirdik.
Kod:
https://preview.pdcdn.xyz/dl2.php?id=117517380&h=a934fa8f050d12b5dcea6960dd7f0350&u=cache&ext=pdf&n=Satranç+-+stefan+zweig&embedded=true&1036
elimizde sonunda, uzak, uzak, uzak sunucudaki dosyanın oturum parametreleri ile birlikte bir adresi oldu. oturum parametreleri önemli, bu parametreler kısa süre için geçerli ve bunlar olmadan dosyaya erişemeyiz. illa bir oturum parametresi session anahtarını taşımak zorunda değil ayrıca.

PHP:
    public function ReturnKitap(){
        $ara = $this->PdfHunterID();
        $dosya = "addon/Onbellek/return/$ara.pdf";
        if(file_exists($dosya)){
            $sonuc = $dosya;
        }else{
            $url = $this->KitabiBul();
            $curl = curl_init($url);
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            $resp = curl_exec($curl);
            $resp = empty($resp) ? die($this->KitabiBul().' adresinde dosya silindiği için kitap okunamaz.') : $resp;
            curl_close($curl);
            $olustur = fopen($dosya, 'w');
            fwrite($olustur,$resp);
            fclose($olustur);
            file_exists($dosya) ? $sonuc = $dosya : die('PDF oluşturulamadı') ;
        }
        return $sonuc;
    }
artık son kez curl kullanıyoruz arkadaşlar. dosyaya eriştik ve pdf olarak dosyayı sunumuza kaydettik.

PHP:
    public function ReturnTxt(){
        $ara = $this->PdfHunterID();
        $dosya = "addon/Onbellek/returntxt/$ara.txt";
        if($this->ReturnKitap()){
            if(file_exists($dosya)){
                $sonuc = file_get_contents($dosya);
            }else{
                $pdfdoc = "addon/Onbellek/return/$ara.pdf";
                include "addon/autoload.php";
                $parser = new \Smalot\PdfParser\Parser();
                $pdf    = $parser->parseFile($pdfdoc);
                $text = str_replace(array('"', "'", "\\"), '', $pdf->getText());
                file_put_contents($dosya, $text);
                $sonuc = file_get_contents($dosya);
            }
        }else{
            $this->ReturnKitap();
        }
        return isset($sonuc) ? $sonuc = htmlspecialchars(str_replace("\n", "\t", $sonuc), ENT_QUOTES) :
        die('Olasılığı gözükmeyen ve hiç beklenmeyen bir hata, bu mavi ekranın siyah ekran vermesi gibi saçma bir hata. Tekrar dene ve eğer bu hata ile karşılaşırsan farklı bir kitap dene');
    }
bir önceki konuda "kodlama" başlığı altında eklentilerimizi listelemiştim. burada PdfParser eklentisi ile kaydettiğimiz pdf kitabi txt değerine dönüştürüyorum. tabi bu çalışmayı kopyalayıp aynını yaparsanız, pdf parser kısmında benim aldığım sonuçları alamazsınız. pdfparser'ı revize ederek kendimce gereken düzenlemeler yaptım çünkü. neyse txt olarak kaydettik, artık bu dosya hem pdf kitap olarak elimizde mevcut hem de txt olarak, ayrıca ileride başka biri bu kitabı ardığında curl ile falan işimiz olmayacak direk sistemin önbelleğinden bunu kişiye sunabileceğiz.


PHP:
    public function PdfHunter($value){
        $komut = explode (' ', $value);
        if(count($komut) >= 3){
            if(parent::KullaniciTakibi(1, '', $value, 1) == 1){
                $yanitla = $komut[1] == "-s" ?
                $this->XScript(0, $value).$this->XScript(3,str_replace('PdfHunter -s ', '', $value)) :
                ($komut[1] == "-p" && $komut[2] == 0 ?
                (str_word_count(str_replace('PdfHunter -p 0 ', '', $value)) == 0 ?
                $this->XScript(0, $value).$this->XScript(4, $this->ReturnKitap()) : //str_replace('PdfHunter -p 0 ', '', $value) :
                $this->PdfHata($value)) :
                ($komut[1] == "-p" && $komut[2] == 1 ?
                (str_word_count(str_replace('PdfHunter -p 1 ', '', $value)) == 0 ?
                $this->XScript(0, $value).$this->XScript(5, $this->ReturnTxt()) :
                $this->PdfHata($value) ) :
                $this->PdfHata($value) ));
            }
        }else{
            $yanitla = $this->PdfHata($value);
        }
        echo $yanitla;
    }

bu ise sınıfımızın son metotu. yapılan istek doğrultusunda yanıt verecek şekilde yazdığımız için, XScript sınıfına falan değinmem gerekecek, gerek yok. siz kendiniz istediğiniz gibi uyarlayın. ben burada

Kod:
# Arama yapmak ve sonuçları listelemek için: PdfHunter -s {DEĞER} @str
# İstenilen kitabı pdf olaran görüntülemek için: PdfHunter -p 0 {DEĞER} @int
# İstenilen kitabı sistemin kendisi seslendirmesi için: PdfHunter -p 1 {DEĞER} @int
şeklinde kendime bir post isteğinde bulundum ve bun istekleri explode ederek işledim, 1 ise sunu yap 0 ise sunu yap gibi.

evet sonuca gelin birlikte bakalım, ne yapmışız?




6yuDQ.gif
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.