Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Pobieranie title z linka
Forum PHP.pl > Forum > Przedszkole
Majkelo23
Potrzebuję funkcji, która wyciągnie mi title danej strony, jeśli z kolei się nie uda to zwróci po prostu false.
Próbowałem najprostszym sposobem - file_get_contents() - za cholerę nie chce działać. Są wyjątki, np. nk.pl przeczyta, ale onet.pl / interia.pl / wp.pl nie potrafi odczytać, zwraca mi false. Czym to jest spowodowane ?

Kod wygląda tak:

  1. function get_url_title($url)
  2. {
  3. $path = file_get_contents($url);
  4. if ( preg_match('/<title>(.*?)<\/title>/', $path, $array) )
  5. {
  6. return $array[1];
  7. }
  8. else
  9. {
  10. return false;
  11. }
  12. }
ethann
Mam parę uwag odnośnie regexpa.
w preg_match() jako ograniczniki wzoru zastosuj np. @ (znak małpy), unikniesz backslashowania często występujących znaków. Znak zapytania nie jest potrzebny, sama gwiazdka oznacza, że chcesz w tym miejscu dowolną ilość elementów (łącznie z jego brakiem).
  1. preg_match('@<title>(.*)</title>@', $path, $array)


ad kodu u mnie wyrzuca warning w przypadku nk.
Cytat
Warning: file_get_contents(http://nk.pl/) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden in D:\Programms\wamp\skrypty\getUrlTitle.php on line 5.

Najprawdopodobniej jest parę rzeczy sprawdzanych (chodzi o nagłówki HTTP, np. przeglądarka). Jeśli chcesz z tego serwisu wydobyć adres skorzystaj np. z curl'a i wyślij fałszywe nagłówki.


#edit
U mnie w przypadku WP/Interii/Onet, śmiga bez problemu.

ew. sprawdź czy nie masz ustawionego w php.ini:
allow_url_fopen = Off
ale to raczej odpada bo by Ci nic nie zewnętrznego nie czytało.
Majkelo23
  1. <?php
  2.  
  3. function get_url_title($url)
  4. {
  5. $path = @file_get_contents($url);
  6. if ( preg_match('@<title>(.*)</title>@', $path, $array) )
  7. {
  8. return $array[1];
  9. }
  10. else
  11. {
  12. return $url;
  13. }
  14. }
  15.  
  16. echo get_url_title('http://onet.pl');
  17.  
  18. ?>


Efekt: "http://onet.pl" ;/
ethann
pokaż co zwraca
  1. var_dump(get_url_title('http://onet.pl'));
Majkelo23
Kod
string(14) "http://onet.pl"


Dodam, że przy http://nk.pl otrzymuję:

Cytat
nk.pl - Serwis społecznościowy nk.pl - platforma komunikacji dla wszystkich internautów


Czyli ok, krzaki sam poprawię.
ethann
hm no fakt, zwróć zamiast
  1. return $array[1];

to:
  1. return $array;


i wtedy var_dump.
Majkelo23
Cholera, znalazłem problem. Te wszystkie strony korzystają z 'http://www.'. Jak to zrobić tak uniwersalnie, że w przypadku wymuszonego 'www' skrypt jakoś to przegryzie? Da się to jakoś ugryźć?

EDIT:

I...na odwrót. http://www.nk.pl/ tez nie śmiga. Dopiero po usunięciu 'www.' ;/
greycoffey
Musisz podążać za przekierowaniami, lub napisać funkcję sprawdzającą najpierw http://strona.pl potem http://www.strona.pl.
Majkelo23
Własnie po napisaniu pytania, sam wpadłem na to, że muszę w przypadku niepowodzenia sprawdzić link dla "z www." i "bez www.".

Funkcja jest taka:

  1. function get_url_title($url)
  2. {
  3. $path = @file_get_contents($url);
  4. if ( preg_match('@<title>(.*)</title>@', $path, $array) )
  5. {
  6. return $array[1];
  7. }
  8. else
  9. {
  10. if ( strstr($url, 'www.') == FALSE )
  11. {
  12. $url = str_replace('http://', 'http://www.', $url);
  13. $path = @file_get_contents($url);
  14. if ( preg_match('@<title>(.*)</title>@', $path, $array) )
  15. {
  16. return $array[1];
  17. }
  18. }
  19. else if ( strstr($url, 'www.') !== FALSE )
  20. {
  21. $url = str_replace('www.', '', $url);
  22. $path = @file_get_contents($url);
  23. if ( preg_match('@<title>(.*)</title>@', $path, $array) )
  24. {
  25. return $array[1];
  26. }
  27. }
  28. else
  29. {
  30. return $url;
  31. }
  32. }
  33. }


Ale...nadal nic. Może Wy widzicie jakiegoś byka?

EDIT:

dla http://onet.pl/ już działa - dopisuje "www.". Jednak w przypadku http://www.nk.pl/ - nie chce wywalać tego "www." ;/
ethann
Zależy. możesz to zrobić w prosty sposób samemu wpisując 2 adresy (z WWW oraz bez WWW) np.
  1. function get_url_title_x($linka, $linkb) {
  2. if(($ret = get_url_title($linka)) !== false) {
  3. return $ret;
  4. }
  5. else {
  6. return get_url_title($linkb);
  7. }
  8. }
  9.  
  10. get_url_title_x("http://nk.pl/", "http://www.nk.pl/");


Ewentualnie sprawdzić regexp'em czy występuje w linku fragment "www.", jeśli nie to po prostu przygotować 2 zmienne, jedna z wartością normalnego linka, a drugą z takim samym linkiem tylko dopisać do niego "www." zaraz po ukośnikach (http://) i wtedy wykonać np. część zawartą w get_url_title_x (kod który podałem wyżej).
Majkelo23
Dla http://onet.pl/ już działa - dopisuje "www.". Jednak w przypadku http://www.nk.pl/ - nie chce wywalać tego "www." ;/
ethann
przede wszystkim włącz ostrzeżenia w php.ini, albo dopisz na górze pliku dopisz error_reporting(E_ALL);
I nie wyciszaj tego co krzyczą funkcję póki kod nie będzie działał poprawnie.
Majkelo23
Niestety, nic to nie dało.
IProSoft
Gotowa i działająca:

  1. function get_url_title_x($url) {
  2. $curl_options = array(
  3. CURLOPT_FOLLOWLOCATION => true,
  4. CURLOPT_MAXREDIRS => 3,
  5. CURLOPT_RETURNTRANSFER => true,
  6. CURLOPT_UNRESTRICTED_AUTH => true,
  7. CURLOPT_CONNECTTIMEOUT => 30,
  8. CURLOPT_DNS_CACHE_TIMEOUT => 30,
  9. CURLOPT_TIMEOUT => 30,
  10. CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 5.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0'
  11. );
  12. $curl = curl_init();
  13. curl_setopt_array($curl, $curl_options);
  14. curl_setopt($curl, CURLOPT_URL, $url);
  15. $data = curl_exec( $curl );
  16. curl_close( $curl );
  17. if ( preg_match('@<title>(.*)</title>@', $data, $array) )
  18. {
  19. return $array[1];
  20. }
  21. return false;
  22. }
Majkelo23
Problem w tym, że mam coś wyłączonego na serwerze, co powoduje, że Twoja funkcja nie działa:

Cytat
Warning: curl_setopt_array() [function.curl-setopt-array]: CURLOPT_FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set in /home/


;/ nie bawie się na darmówkach tylko na normalnym hostingu.
Moja funkcja jest nie do poprawy?
IProSoft
Sprawdziłem funkcję z postu: http://forum.php.pl/index.php?s=&showt...st&p=965893 i działa pieknie, dla jakiej strony nie pobiera Ci title?

Usuń wszystkie @ z kodu i daj error_reporting(E_ALL); przed wywołaniem funkcji.
Majkelo23
Facet na innym forum też twierdził, że mu działa ta funkcja. Mi z kolei ona nie działa. Inny napisał, że "to kwestia requiestów..." cokolwiek to oznacza.
IProSoft
Niestety nikt bez jakichkolwiek komunikatów/błędów nie będzie mógł raczej znaleźc rozwiązania.
Majkelo23
Ta, tylko że ja nie mam żadnych błędów/komunikatów, tyle tylko że nie pobiera mi tego title. Kod, który kazałeś dodać dodałem i napisałem pare postów wcześniej - nic to nie zmieniło.
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.