From 905c85813a24f02050421df8a7b1bf7ffbf4d987 Mon Sep 17 00:00:00 2001 From: Jacek Kowalski <Jacek@jacekk.info> Date: Sat, 01 Nov 2014 23:52:41 +0000 Subject: [PATCH] [core] Zablokowanie przetwarzania XML External Entities --- data/lotto/pobierz.php | 280 +++++++++++++++++++++++++++++++------------------------ 1 files changed, 159 insertions(+), 121 deletions(-) diff --git a/data/lotto/pobierz.php b/data/lotto/pobierz.php index 2260d8b..73e7aeb 100644 --- a/data/lotto/pobierz.php +++ b/data/lotto/pobierz.php @@ -2,25 +2,41 @@ echo STAR.'Pobieranie danych...'; class lotto { + // Zawartość strony http://lotto.pl/wyniki-gier + // jako obiekt DOMDocument protected $strona = NULL; + // Powiązany DOMXPath + protected $xpath = NULL; + // Specjalne zachowania dla gier + const NONE = 0; + const PLUS = 1; + const LOTTOPLUS = 2; + const EKSTRA = 3; + + // Lista gier. protected $gry = array( - 'lotto' => array(6, FALSE, 'dl'), - 'mini-lotto' => array(5, FALSE, 'el'), - 'kaskada' => array(12, FALSE, 'ka'), - 'multi-multi' => array(20, TRUE, 'mm'), - 'joker' => array(5, FALSE, 'jk') + // nazwa + 'lotto', 'mini-lotto', + 'kaskada', 'multi-multi', + 'joker', 'ekstra-pensja' ); + // Spróbuj pobrać stronę http://lotto.pl/wyniki-gier + // do zmiennej $this->strona z użyciem pliku cache. function __construct() { $cache = 'lotto_cache.txt'; + // Sprawdź, czy da się skorzystać z pliku cache. if( ( !file_exists($cache) AND !is_writable(dirname($cache)) ) OR ( file_exists($cache) AND !(is_writable($cache)) ) ) { + // Nie, nie da się. $cache = ''; } else { + // Tak, da się. + // Sprawdź, czy dane są aktualne. if(@filemtime($cache)<strtotime('yesterday 22:45') && time()<=strtotime('14:30')) { $recent = FALSE; } @@ -34,156 +50,178 @@ } } + $strona = ''; + $this->strona = new DOMDocument(); + if($cache == '' OR !$recent) { - $this->strona = @file_get_contents('http://lotto.pl/wyniki-gier'); - if(!$this->strona) { + // Dane są nieaktualne, więc pobieramy je ponownie + $strona = @file_get_contents('http://lotto.pl/wyniki-gier'); + if(!$strona) { throw new Exception('Nie udało się pobrać wyników.'); } + // Można zapisać do cache'a... if($cache != '') { - file_put_contents($cache, $this->strona); + // ...więc zapamiętujemy arkusz. + file_put_contents($cache, $strona); } + + @$this->strona->loadHtml($strona); } else { - $this->strona = file_get_contents($cache); - } - } - - protected function szukaj_poczatku($tresc, $poczatek = 0) { - return strpos($this->strona, $tresc, $poczatek); - } - - protected function szukaj_konca($tresc, $poczatek = 0) { - $pozycja = strpos($this->strona, $tresc, $poczatek); - - if($pozycja !== FALSE) { - $pozycja += strlen($tresc); + // Dane w cache są aktualne, więc załaduj je. + @$this->strona->loadHtmlFile($cache); } - return $pozycja; + $this->xpath = new DOMXPath($this->strona); } + // Znajduje odpowiedni element w pliku HTML lub zwraca błąd. + protected function wytnij($zapytanie, $gdzie = NULL, $blad = 'Brak danych') { + $rezultat = $this->xpath->query($zapytanie, $gdzie); + if(!$rezultat OR $rezultat->length <= 0) { + throw new Exception($blad); + } + return $rezultat; + } + + // Zwraca wynik gry (domyślnie lotto). function wynik($gra = 'lotto') { $wyniki = $this->wyniki($gra, 1); + if(!isset($wyniki[0])) { + throw new Exception('Brak wyników dla gry.'); + } return $wyniki[0]; } - function wyniki($gra = 'lotto', $liczba = 100) { - if(!isset($this->gry[$gra])) { + // Zwraca $liczba ostatnich wyników gry (domyślnie lotto), + // jednak nie więcej niż 5 (tyle jest na stronie Totalizatora). + function wyniki($gra = 'lotto', $zwroc = 1000) { + if(!in_array($gra, $this->gry)) { throw new Exception('Podana gra liczbowa nie jest obsługiwana.'); } - $wyniki = array(); - $poczatek = $this->szukaj_konca('<div class="start-wyniki_'.$gra.'">'); - if($poczatek === FALSE) { - throw new Exception('Nie znaleziono wyników dla gry '.$gra.' na stronie.'); + $rezultaty = array(); + + $dane = $this->wytnij('//div[@class="start-wyniki_'.$gra.'"]', NULL, + 'Nie znaleziono na stronie wyników dla gry '.$gra); + $dane = $dane->item(0); + + + $daty = $this->wytnij('div[contains(concat(" ", @class, " "), " wyniki_data ")]', $dane, + 'Nie znaleziono informacji o losowanu gry '.$gra); + $wyniki = $this->wytnij('div[contains(concat(" ", @class, " "), " glowna_wyniki_'.$gra.' ")]', $dane, + 'Nie znaleziono wyników losowania gry '.$gra); + + $plusy = NULL; + try { + $plusy = $this->wytnij('div[@class="wynik_'.$gra.'_plus"]', $dane); + } catch(Exception $e) {} + + $lottoplusy = NULL; + try { + $lottoplusy = $this->wytnij('//div[@class="glowna_wyniki_'.$gra.'plus"]', $dane); + } catch(Exception $e) {} + + for($l = 0; $l < $daty->length && $l < $wyniki->length && $l < $zwroc; $l++) { + $rezultat = array(); + + // Znajdź $l-tą datę losowania i jego wynik + $data = $daty->item($l); + $wynik = $wyniki->item($l); + + try { + // Znajdź datę i godzinę + $data = $this->wytnij('strong', $data, 'Nie znaleziono '.$l.' daty losowania gry '.$gra); + $rezultat['data'] = trim($data->item(0)->textContent); + if($data->length > 1) { + $rezultat['godzina'] = trim($data->item(1)->textContent); + } + + // Znajdź poszczególne liczby w wyniku + $liczby = $this->wytnij('div[@class="wynik_'.$gra.'"]', $wynik, + 'Nie znaleziono liczb w '.$l.' losowaniu gry '.$gra); + $rezultat['liczby'] = array(); + foreach($liczby as $liczba) { + $rezultat['liczby'][] = trim($liczba->textContent); + } + } catch(Exception $e) { + break; + } + + try { + // Szukamy plusa + if($plusy && $plusy->length > $l) { + $rezultat['plus'] = trim($plusy->item($l)->textContent); + } + } catch(Exception $e) {} + + try { + // Szukamy ekstra liczby + $ekstra = $this->wytnij('div[@class="wynik_'.strtr($gra, '-', '_').'"]', $wynik, + 'Nie znaleziono ekstra w '.$l.' losowaniu gry '.$gra); + $rezultat['ekstra'] = trim($ekstra->item(0)->textContent); + } catch(Exception $e) {} + + try { + // Szukamy lottoplusa + if($lottoplusy && $lottoplusy->length > $l) { + $liczby = $this->wytnij('div[@class="wynik_'.$gra.'plus"]', $lottoplusy->item($l), + 'Nie znaleziono liczb w '.$l.' losowaniu gry '.$gra.'plus'); + $rezultat['plus'] = array(); + foreach($liczby as $liczba) { + $rezultat['plus'][] = trim($liczba->textContent); + } + } + } catch(Exception $e) {} + + $rezultaty[] = $rezultat; } - for($l = 0; $l < $liczba; $l++) { - $poczatek = $this->szukaj_konca('<div class="wyniki_data">', $poczatek); - if($poczatek === FALSE) { - break; + return $rezultaty; + } + + protected $skroty = array( + 'lotto' => 'dl', 'mini-lotto' => 'el', + 'kaskada' => 'ka', 'multi-multi' => 'mm', + 'joker' => 'jk', 'ekstra-pensja' => 'ep' + ); + + function pobierz_jeden($skrot, $wynik) { + $last_data = @file_get_contents('./last_'.$skrot.'.txt'); + if($last_data != $wynik['data']) { + foreach($wynik['liczby'] as $i => $liczba) { + $wynik[$i+1] = $liczba; } - - $wynik = array(); - - $poczatek = $this->szukaj_konca('<strong>', $poczatek); - if($poczatek === FALSE) { - break; - } - $koniec = $this->szukaj_poczatku('</strong>', $poczatek); - $wynik['data'] = substr($this->strona, $poczatek, $koniec-$poczatek); - if($poczatek === FALSE) { - break; - } - $poczatek = $this->szukaj_konca('<strong>', $poczatek); - $koniec = $this->szukaj_poczatku('</strong>', $poczatek); - $wynik['godzina'] = substr($this->strona, $poczatek, $koniec-$poczatek); - - $poczatek = $this->szukaj_konca('<div class="glowna_wyniki_'.$gra.'">', $poczatek); - if($poczatek === FALSE) { - break; - } - - $wynik['liczby'] = array(); - for($i = 0; $i < $this->gry[$gra][0]; $i++) { - $poczatek = $this->szukaj_konca('<div class="wynik_'.$gra.'">', $poczatek); - $koniec = $this->szukaj_poczatku('</div>', $poczatek); - $wynik['liczby'][] = substr($this->strona, $poczatek, $koniec-$poczatek); - } - - if($this->gry[$gra][1]) { - $poczatek = $this->szukaj_konca('<div class="wynik_'.$gra.'_plus">', $poczatek); - $koniec = $this->szukaj_poczatku('</div>', $poczatek); - $wynik['plus'] = substr($this->strona, $poczatek, $koniec-$poczatek); - } - - $wyniki[] = $wynik; + file_put_contents('./last_'.$skrot.'.txt', $wynik['data']); + file_put_contents('./'.$skrot.'.txt', serialize($wynik)); + file_put_contents('./archiwum/'.$skrot.'_'.date('j.m.Y', strtotime($wynik['data'])).'.txt', serialize($wynik)); + echo OK; + } else { + echo NOT; } - - return $wyniki; } function pobierz() { - foreach($this->gry as $gra => $data) { + foreach($this->gry as $gra) { echo STAR.'Wyniki gry '.$gra.'...'; if($gra == 'multi-multi') { + echo "\n"; $wyniki = $this->wyniki($gra, 2); - $wynik = $wyniki[0]; - $skrot = $data[2].substr($wynik['godzina'], 0, 2); - $last_data = @file_get_contents('./last_'.$skrot.'.txt'); - if($last_data != $wynik['data']) { - $output = array(); - $output['data'] = $wynik['data']; - for($i = 0; $i < $data[0]; $i++) { - $output[$i+1] = $wynik['liczby'][$i]; + foreach($wyniki as $wynik) { + $godzina = substr($wynik['godzina'], 0, 2); + echo ' '.STAR.'godzina '.$godzina.'...'; + if($godzina == '21') { + $godzina = '22'; } - if($data[1]) { - $output['plus'] = $wynik['plus']; - } - file_put_contents('./last_'.$skrot.'.txt', $output['data']); - file_put_contents('./'.$skrot.'.txt', serialize($output)); - file_put_contents('./archiwum/'.$skrot.'_'.date('j.m.Y', strtotime($output['data'])).'.txt', serialize($output)); + $skrot = $this->skroty[$gra].$godzina; + + $this->pobierz_jeden($skrot, $wynik); } - - $wynik = $wyniki[1]; - $skrot = $data[2].substr($wynik['godzina'], 0, 2); - $last_data = @file_get_contents('./last_'.$skrot.'.txt'); - if($last_data != $wynik['data']) { - $output = array(); - $output['data'] = $wynik['data']; - for($i = 0; $i < $data[0]; $i++) { - $output[$i+1] = $wynik['liczby'][$i]; - } - if($data[1]) { - $output['plus'] = $wynik['plus']; - } - file_put_contents('./last_'.$skrot.'.txt', $output['data']); - file_put_contents('./'.$skrot.'.txt', serialize($output)); - file_put_contents('./archiwum/'.$skrot.'_'.date('j.m.Y', strtotime($output['data'])).'.txt', serialize($output)); - } + } else { + $this->pobierz_jeden($this->skroty[$gra], $this->wynik($gra)); } - else - { - $wynik = $this->wynik($gra); - $skrot = $data[2]; - $last_data = @file_get_contents('./last_'.$skrot.'.txt'); - if($last_data != $wynik['data']) { - $output = array(); - $output['data'] = $wynik['data']; - for($i = 0; $i < $data[0]; $i++) { - $output[$i+1] = $wynik['liczby'][$i]; - } - if($data[1]) { - $output['plus'] = $wynik['plus']; - } - file_put_contents('./last_'.$skrot.'.txt', $output['data']); - file_put_contents('./'.$skrot.'.txt', serialize($output)); - file_put_contents('./archiwum/'.$skrot.'_'.date('j.m.Y', strtotime($output['data'])).'.txt', serialize($output)); - } - } - echo OK; } } } -- Gitblit v1.9.1