Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Pobieranie konkretnej informacji z tabeli na innej stronie.
Forum PHP.pl > Forum > PHP
omi
Witam!

Pobieram całą stronę: https://secure.tibia.com/community/?subtopic=killstatistics (np.server Amera ) do pliku tekstowego za pomocą curl, a chcałbym z tej tabeli co tam jest zapisać tylko np. dwie pozycje "Abyssador" i "An Observer Eye" z kolumny Race, a z kolumny Last Day - Killed by Players.

Bym prosił o jakiś przykładowy kod jak to wyselekcjonować żeby nie zapisywało wszystkiego ze strony tylko te konkretne dwie rzeczy. Pozdrawiam.
SmokAnalog
Masz szczęście, bo w przypadku tej strony do treści po wysłaniu formularza z nazwą świata możesz też się dostać z metody GET: https://secure.tibia.com/community/?subtopi...amp;world=Amera

Dla Ciebie oznacza to tyle, że nie musisz się bawić w cURL czy inne biblioteki do wykonywania żądań HTTP. Wystarczy zwykłe:

  1. $html = file_get_contents('https://secure.tibia.com/community/?subtopic=killstatistics&world=Amera');


Jak już masz w zmiennej kod HTML, to najlepiej analizować go parserem DOM, np. wbudowanym PHP DOM. To już wymaga trochę wprawy.
omi
Dzięki za odpowiedź. Mam taki kod znalazłem z forum. Zapisuję on już nie całą stronę tylko niektóre elementy tabeli. A co by tu zmienić w tym kodzie żeby zapisać tylko np. dwie pozycje "Abyssador" i "An Observer Eye" z kolumny Race, a z kolumny Last Day - Killed by Players znajdującą się tam liczbę? Tak w ogóle to bym chciał to co wybiorę z tabeli zapisać do bazy danych w przyszłości, nie jestem do końca pewny czy dobrze kombinuje teraz czy to się tak da zapisać do bazy danych?


  1. <?php
  2. $s = file_get_contents('https://secure.tibia.com/community/?subtopic=killstatistics&world=Amera');
  3. preg_match_all( '#<td>(.*?)</td>#is', $s, $m, PREG_PATTERN_ORDER );
  4.  
  5. $string = implode("\n", $m[1]);
  6.  
  7. file_put_contents('asd.txt',$string);
  8. ?>
viking
http://simplehtmldom.sourceforge.net/manual.htm

  1. <?php
  2.  
  3. include 'simple_html_dom.php';
  4.  
  5. $html = new simple_html_dom();
  6. $a = $html->load_file('https://secure.tibia.com/community/?subtopic=killstatistics&world=Amera');
  7. $table = $html->find('div#ContentHelper table', 4);
  8.  
  9. foreach ($table->find('tr td') as $td) {
  10. echo $td->plaintext;
  11. }


Kombinuj dalej.
trueblue
  1. $html = file_get_contents('https://secure.tibia.com/community/?subtopic=killstatistics&world=Amera');
  2.  
  3. $dom = new DOMDocument;
  4. libxml_use_internal_errors(true);
  5. $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
  6. libxml_clear_errors();
  7. $dom->encoding = 'UTF-8';
  8.  
  9. $xpath = new DOMXPath($dom);
  10. $tds = $xpath->query('//table//td[contains(text(),"Abyssador") or contains(text(),"An Observer Eye")]/ancestor::tr/td[3]');
  11.  
  12. foreach($tds as $td){
  13. echo $td->nodeValue;
  14. }


Więcej info na: http://kawalekkodu.pl/post/the-tag-is-out-...domxpath-s01e01
omi
Dziękuję za odpowiedź. To zaczyna nabierać jakiś kształtów.
SmokAnalog
A odpowiadając na Twoją wątpliwość preg_match i preg_match_all też mogą być używane do wyłuskiwania danych z HTML-a, prawdziwe parsery DOM to jednak lepszy sposób. O ile wyrażenia regularne sprawdzą się w bardzo prostych przypadkach, tak już na przykład wybieranie komórki tabeli w czwartej kolumnie może okazać się mało intuicyjnym zadaniem dla wyrażenia regularnego, jeśli komórka nie została oznaczona jakimiś specyficznymi atrybutami. Co gorsza, nawet jeśli Twój wzorzec zostanie dopasowany, teoretycznie może on pasować do czegoś innego, bo akurat jakiś inny element też spełnia wymagania. Lepiej nauczyć się pracować z parserami DOM, bo od tego są.
omi
Jeszcze mam jeden dylemat bo przeszukiwałem internet i nic takiego nie mogę znaleźć. Wiem że trzeba dodać do tego kodu:

  1. $html = file_get_contents('https://secure.tibia.com/community/?subtopic=killstatistics&world=Amera');
  2.  
  3. $dom = new DOMDocument;
  4. libxml_use_internal_errors(true);
  5. $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
  6. libxml_clear_errors();
  7. $dom->encoding = 'UTF-8';
  8.  
  9. $xpath = new DOMXPath($dom);
  10. $tds = $xpath->query('//table//td[contains(text(),"Abyssador") or contains(text(),"An Observer Eye")]/ancestor::tr/td[3]');
  11.  
  12. foreach($tds as $td){
  13. echo $td->nodeValue;
  14. }


dane do połączenia z bazą :

$url = 'adres bazy danych np: localhost';
$identyfikator = 'login';
$haslo = 'hasło';
$baza_danych="nazwa_bazy_danych";
$tabela="nazwa_tabeli"

i nie wiem co dalej zmienić w kodzie żeby wynik nie był wyświetlany w przeglądarce tylko został zapisany do bazy danych w jednym wierszu w dwóch kolumnach, wynik 0 w jednej kolumnie wynik 1 w drugiej kolumnie tabeli.
Przy okazji jak będę robił kolejny zapis do bazy danych żeby dało się skasować poprzedni zapis.
Pozdrawiam

SmokAnalog
Coś słabo szukasz: http://php.net/manual/en/mysqli.prepare.php i użyj tego do wykonania zapytań INSERT i DELETE.
omi
Dzięki za odpowiedź. Popróbuję coś wykombinować tylko mówię od razu że nie skończyłem informatyki na politechnice i mogę nie ogarniać niektórych wątków i nie ogarniam. Coś spróbuję posklejać. To taki projekt hobbistyczny.

INSERT to powinien wyglądać mniej więcej tak ?:

  1. INSERT INTO $tabela VALUES ('0', '1');


I wtedy te pobrane dane można zapisać w jednym wierszu w dwóch kolumnach. Tak tu to widzę z przykładów.
Czyli potrzebuje w kodzie mieć coś takiego jw. czy nie bardzo?


A więc na razie mam taki kod:

  1. $mysqli = new mysqli("localhost", "my_user", "my_password", "nazwa bazy danych");
  2.  
  3. /* check connection */
  4. if (mysqli_connect_errno()) {
  5. printf("Connect failed: %s\n", mysqli_connect_error());
  6. exit();
  7. }
  8.  
  9. $tabela = "Nazwa tabeli";
  10.  
  11.  
  12. $html = file_get_contents('https://secure.tibia.com/community/?subtopic=killstatistics&world=Amera');
  13.  
  14. $dom = new DOMDocument;
  15. libxml_use_internal_errors(true);
  16. $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
  17. libxml_clear_errors();
  18. $dom->encoding = 'UTF-8';
  19.  
  20. $xpath = new DOMXPath($dom);
  21. $tds = $xpath->query('//table//td[contains(text(),"Abyssador") or contains(text(),"An Observer Eye")]/ancestor::tr/td[3]');
  22.  
  23. foreach($tds as $td){
  24. echo $td->nodeValue;
  25. }


I teraz nie wiem jak zmodyfikować ten kod i wstawić do niego INSERT i DELETE.
Pozdrawiam

Po chwili zastanowienia stwierdziłem ze ten kod wyżej nie zda mi egzaminu trzeba to zrobić tak jak pisał SmokAnalog za pomocą preg_match i preg_match_all. Czyli w bazie danych powinny być dwa wiersze w tym przypadku w których będą się znajdować dwa słowa "Abyssador" i "An Observer Eye" i przypisane w drugiej kolumnie do tych słów wartości.
SmokAnalog
To czy użyć PHP DOM czy preg_match_all to tylko kwestia wyłuskania tych danych i lepiej to zrobić z PHP DOM. Co do tego jak zrobić zapytanie, przejrzyj ten link, który Ci wysłałem. Tam masz przykłady.
omi
Czy by mógł mi ktoś dokończyć ten kod i dodać do niego INSERT żebym mógł zobaczyć jak to się zapiszę w bazie danych. bo na razie ten kod wyświetla mi wynik w przeglądarce. Bym prosił. Pozdrawiam.



  1. $mysqli = new mysqli("localhost", "my_user", "my_password", "nazwa bazy danych");
  2.  
  3. /* check connection */
  4. if (mysqli_connect_errno()) {
  5. printf("Connect failed: %s\n", mysqli_connect_error());
  6. exit();
  7. }
  8.  
  9. $tabela = "Nazwa tabeli";
  10.  
  11.  
  12. $html = file_get_contents('https://secure.tibia.com/community/?subtopic=killstatistics&world=Amera');
  13.  
  14. $dom = new DOMDocument;
  15. libxml_use_internal_errors(true);
  16. $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
  17. libxml_clear_errors();
  18. $dom->encoding = 'UTF-8';
  19.  
  20. $xpath = new DOMXPath($dom);
  21. $tds = $xpath->query('//table//td[contains(text(),"Abyssador") or contains(text(),"An Observer Eye")]/ancestor::tr/td[3]');
  22.  
  23. foreach($tds as $td){
  24. echo $td->nodeValue;
  25. }
viking
Wygląda jakbyś całkowicie czekał na gotowca. Podstaw zapytanie insert zamiast echo i tyle.
omi
Dzięki za odpowiedz.

Jak na razie dzięki należy się Wam flaszka Piccolo.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.