Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Как парсится информация с других сайтов?


Автор: americanets 15.2.2007, 20:38
Как выдернуть необходимую информацию с другого сайта, например с вингарда smile вот такой код и вставить его в свою страницу? 

Код

    <P><B>Новичкам:</B></P>
      <UL>
        <LI>PHP редакторы собираются и обсуждаются <A 
        href="http://forum.vingrad.ru/topic-4898.html" target=_blank>здесь</A> 
        <LI>Электронные книги по PHP, документацию можно найти <A 
        href="http://forum.vingrad.ru/topic-34297.html" target=_blank>здесь</A> 
        <LI>Интерпретатор PHP, полную документацию можно скачать на <B><A 
        href="http://php.net/php.net" target=_blank>PHP.NET</A></B> </LI></UL>
      <P><B>Важно:</B></P>
      <UL>
        <LI>Не брезгуйте пользоваться тегами 
Код
КОД
 для повышения 
        читабельности текста/кода. 
        <LI>Перед созданием новой темы воспользуйтесь <A 
        href="http://forum.vingrad.ru/act-Search/f-6.html" 
        target=_blank>поиском</A> и загляните в <B><A 
        href="http://forum.vingrad.ru/section-557/module/vingradfaq/act-module.html" 
        target=_blank>FAQ</A></B> 
        <LI>Действия модераторов можно обсудить <A 
        href="http://forum.vingrad.ru/Guestbook.html" target=_blank>здесь</A> 
        </LI></UL>
      <P><B>Внимание:</B></P>
      <UL>
        <LI>В <A href="http://forum.vingrad.ru/PHP-forum.html" 
        target=_blank>корневом разделе</A> находятся темы со ссылками на 
        вопросы, которые уже обсуждались. 
        <LI>Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в 
        форум <A href="http://forum.vingrad.ru/web-tech.html" 
        target=_blank>"Web-технологии"</A> 
        <LI>Темы с именами: "Срочно", "помогите", "не знаю как делать" будут 
        <B>УДАЛЯТЬСЯ</B> </LI></UL>
      <HR>
      </HR>
      <P>Если Вам понравилась атмосфера форума, заходите к нам чаще! С 
      уважением, <A 
      href="http://vingrad.ru/@IZ@TOP">http://vingrad.ru/@IZ@TOP</A>, <A 
      href="http://vingrad.ru/@Mal%20Hack">Mal Hack</A>, <A 
      href="http://vingrad.ru/@-=Ustas=-">-=Ustas=-</A>, <A 
      href="http://vingrad.ru/@PARROT">PARROT</A>, <A 
      href="http://vingrad.ru/@Opik">Opik</A>.</P>

Автор: murod 15.2.2007, 20:48
его можно получить AJAX ом. Делаеш запрос по нужному адресу. Получаеш ответ и парсиш на JavaScript'e

Автор: americanets 15.2.2007, 22:29
а при помощи php как ? 

Автор: mishaSL 16.2.2007, 18:01
Саму страницу берешь через curl или сокеты, как вариант вот так:
Код

/* $cUrl - соединение через curl_init(), $url - адрес необходимой страницы*/
function FileGetContents(& $cUrl, $url, $port = 80, $timeout = 10, $errCount = 1)
{
    curl_setopt($cUrl, CURLOPT_URL, $url);
    curl_setopt($cUrl, CURLOPT_PORT, $port);
    curl_setopt($cUrl,CURLOPT_RETURNTRANSFER,1);
    curl_setopt($cUrl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)");
    curl_setopt($cUrl, CURLOPT_TIMEOUT, $timeout);
    $content = curl_exec($cUrl);
    if (curl_getinfo($cUrl,CURLINFO_HTTP_CODE) != 200) {
        return (($errCount < 3) ? FileGetContents($url, $port, $timeout, $errCount++) : false);
    } else {
        return $content;
    }
}


А далее регулярные выражения:
http://forum.vingrad.ru/topic-131511.html
http://php.net/preg_match

Добавлено @ 18:02 
murod, совсем не нужен тут AJAX.

Автор: BuShaRt 26.2.2007, 16:52
mishaSL
а почему бы просто не взять странцу функцией file

Автор: mishaSL 26.2.2007, 18:31
Цитата(BuShaRt @  26.2.2007,  16:52 Найти цитируемый пост)
mishaSL, 
а почему бы просто не взять странцу функцией file 


Т.к. это не безопасно. На эту тему можешь прочитать следующую статью:
http://vingrad.ru/PHP-PHPNETHTTP-003044

Автор: Powerhead 1.3.2007, 14:41
Цитата(mishaSL @  26.2.2007,  18:31 Найти цитируемый пост)
Т.к. это не безопасно. На эту тему можешь прочитать следующую статью:
http://vingrad.ru/PHP-PHPNETHTTP-003044 

1. Эти функции работают с удаленными хостами толдько при включенной директиве allow_url_fopen в php.ini (установить эту директиву в .htaccess или скрипте нельзя). Как правило хостеры ее отключают. По крайней мере умные.
2. fopen не имеет параметра тайм-аута, что самое важное,т.к. в случае если сайт не отвечает или тяжело отвечает, скрипт может легко "подвиснуть".
3. Если где-то используется fopen и случайно пропущена обработка возможности ошибочного входного параметра, то может быть XSS или переполнения буфера.
4. Нет возможности указать порт, по которому необходимо соединиться с сервером.
5. Лишние операции, т.к. тот же fopen вызывать будет сокеты. Зачем использовать сверх функции?



1. Не факт, что отключение allow_url_fopen - признак ума. Опция включена по умолчанию и я не вижу ни одной причины, по которой хостеру стоило бы беспокоится на её счет. По моему мнению, у большинства хостеров она включена.

2. Ну и подвиснет до set_time_limit. В случае использования сокетов, он тоже подвиснет до таймаута, не вижу особой разницы.

3. Если случайно пропущена обработка входного параметра, то никакие сокеты не помогут.

4. Неправда. $url='http://www.ya.ru:80'; или любой другой порт

5. Затем, что это проще и позволяет сэкономить время. Мы же не работаем напрямую с процессором, к примеру. И еще не факт, что использование sockets даст хоть какой-то прирост в производительности.





Автор: mishaSL 1.3.2007, 20:35
Цитата(Powerhead @  1.3.2007,  14:41 Найти цитируемый пост)
Ну и подвиснет до set_time_limit. В случае использования сокетов, он тоже подвиснет до таймаута, не вижу особой разницы.


Огромная разница когда скрипт виснет или когда скрипт корректно завершает работу через скажем 10 секунд.

Цитата(Powerhead @  1.3.2007,  14:41 Найти цитируемый пост)
Если случайно пропущена обработка входного параметра, то никакие сокеты не помогут.


Через тотже curl при передачи некорректного url ошибка не появляется и скрипт не виснет, а ошибку без проблем получаем curl_errno() или  curl_error().
Если передать некорректный url в file_get_contents(). То соответственно возникает Warning.

И еще не надо забывать то, что в большинстве случаев необходимо получить код ответа сервера. В данном случае хотябы проверить 200 или нет...


В общем Powerhead, PHP позволяет осуществить эту задачу различными способами, но для каждой задачи предназначены определенные функции. Функции fopen, file, file_get_contents предназначены для работы с локальными файлами. А для работы c удаленными файлами предназначены функции с сокетами и curl-ом.

Автор: Powerhead 2.3.2007, 03:45
Цитата(mishaSL)
Огромная разница когда скрипт виснет или когда скрипт корректно завершает работу через скажем 10 секунд.

В случае fopen, file_get_contents и тд, скрипт сразу же выдаст вполне корректный warning на несуществующий хост или страницу. Зачем усложнять себе жизнь? Конечно, если нужен скрипт с функциональностью броузера - тогда согласен. Но, в большинстве случаев, проще воспользоваться врапперами http, https, ftp и тд, которые все поддерживаются fopen. 
Таймаут на tcp соединение устанавливается очень просто: ini_set('default_socket_timeout', 10);  и по умолчанию равен 60.

Цитата(mishaSL)
И еще не надо забывать то, что в большинстве случаев необходимо получить код ответа сервера. В данном случае хотябы проверить 200 или нет...

А по-моему, в большинстве случаев это лишнее. Но если сильно нужно, то разве не проще так? 

Код

$f = fopen('http://www.ya.ru', 'r');
   
$info = stream_get_meta_data($f);

print_r($info['wrapper_data']);


Получаем:
Код

Array
(
    [0] => HTTP/1.0 200 OK
    [1] => Connection: close
    [2] => Content-Type: text/html; charset=windows-1251
    [3] => ETag: "-369396913"
    [4] => Accept-Ranges: bytes
    [5] => Last-Modified: Mon, 15 Jan 2007 14:07:39 GMT
    [6] => Content-Length: 2377
    [7] => Date: Fri, 02 Mar 2007 00:38:52 GMT
    [8] => Server: httpd
)


Цитата(mishaSL)
Функции fopen, file, file_get_contents предназначены для работы с локальными файлами.

Далеко не только для этого: http://www.php.net/manual/ru/wrappers.php

Автор: BuShaRt 2.3.2007, 17:48
Цитата

Т.к. это не безопасно. На эту тему можешь прочитать следующую статью:


Хм, не безопасно? а ты хочешь пользовательский интерфейс для парсинга делаешь что ли? тогда быть может, а вообше парсеры как правило юзаються из админки, ну а если у тебя дырявая админка, то тут уже нету разнцы, что ты юзаешь... Да и проблем не каких не было с $file, отлично он все воспринимает и подготавливает файлы к парсингу)

Автор: mishaSL 2.3.2007, 21:06
Цитата(Powerhead @  2.3.2007,  03:45 Найти цитируемый пост)
выдаст вполне корректный warning


Что значит вполне корректный warning? Warning - это и есть warning, он не может быть корректным или нет.


BuShaRtPowerhead, я не пытаюсь вас переспорить, я пытаюсь объяснить минусы данного подхода.


Цитата(Powerhead @  2.3.2007,  03:45 Найти цитируемый пост)
А по-моему, в большинстве случаев это лишнее. 


В грабере необходимо проверять получил ты ответ 200 или 404 к примеру.
Получяя информацию с помощью stream_get_meta_data(), при ответе сервера(к примеру 401, 404, 503 и т.д.) данная функция не будет работать и fopen будет возвражать warning. И соответственно разработчика (т.е. нам) не узнать отклик, либо новость поменяля адрес (404), либо сайта больше нет (тогда его необходимо занести в отдельный список для дальнейшей проверки)




Цитата(BuShaRt @  2.3.2007,  17:48 Найти цитируемый пост)
Хм, не безопасно?

В этом подходе есть минусы, которые приводят к warning-ам, что очень плохо. И недостаточность получаемой информации...

Цитата(Powerhead @  1.3.2007,  14:41 Найти цитируемый пост)
Не факт, что отключение allow_url_fopen - признак ума


Со стороны хостеров - это уменьшает возможность XSS атак, причем очень сильно уменьшает...
А зачем оставлять такую возможность, если без allow_url_fopen можно обойтись.

Цитата(BuShaRt @  2.3.2007,  17:48 Найти цитируемый пост)
а и проблем не каких не было с $file, отлично он все воспринимает и подготавливает файлы к парсингу


Причем тут готов или нет... А если адрес устарел или еще что с ним...


Автор: americanets 7.3.2007, 12:14
Загружаю курс валют с ЦБ, на локальном компьютере все ОК, а вот на сервере не работает, они закрывают доступ к внешним данным (Warning: fopen(http://www.cbr.ru/scripts/XML_daily.asp)) можно ли его обойти? 



Код

<?php 
  $content = get_content(); 
  $pattern = "#<Valute ID=\"([^\"]+)[^>]+>[^>]+>([^<]+)[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>([^<]+)[^>]+>[^>]+>([^<]+)#i"; 
  preg_match_all($pattern, $content, $out, PREG_SET_ORDER); 
  $dollar = ""; 
  $euro = ""; 
  foreach($out as $cur) 
  { 
    if($cur[2] == 840) $dollar = str_replace(",",".",$cur[4]); 
    if($cur[2] == 978) $euro   = str_replace(",",".",$cur[4]); 
    if($cur[2] == 826) $funt   = str_replace(",",".",$cur[4]);
  } 
  echo "Доллар - ".$dollar."<br>"; 
  echo "Евро - ".$euro."<br>"; 
  echo "Фунт стерлингов  - ".$funt."<br>";
  function get_content() 
  { 
    $link = "http://www.cbr.ru/scripts/XML_daily.asp"; 
    $fd = fopen($link, "r"); 
    $text=""; 
    if (!$fd) echo "Запрашиваемая страница не найдена"; 
    else 
    { 
      while (!feof ($fd)) $text .= fgets($fd, 4096); 
    } 
    fclose ($fd); 
    return $text; 
  } 
?>
Заменил function get_content()
на, 

Код

<?  function get_content(& $cUrl, $port = 80, $timeout = 10, $errCount = 1)
  {
curl_setopt($cUrl, CURLOPT_URL, "http://www.cbr.ru/scripts/XML_daily.asp");
curl_setopt($cUrl, CURLOPT_PORT, $port);
curl_setopt($cUrl,CURLOPT_RETURNTRANSFER,1);
curl_setopt($cUrl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)");
curl_setopt($cUrl, CURLOPT_TIMEOUT, $timeout);
$text = curl_exec($cUrl);
if (curl_getinfo($cUrl,CURLINFO_HTTP_CODE) != 200) {
return (($errCount < 3) ? FileGetContents("http://www.cbr.ru/scripts/XML_daily.asp", $port, $timeout, $errCount++) : false);
    } else {
return $text;
    }
  }?>


Но  что-то не работает ? 

Автор: mishaSL 7.3.2007, 17:22
Вот так должно работать:

Код

<?php 
  $cUrl = curl_init();
  $content = get_content($cUrl); 
  curl_close($cUrl);
  $pattern = "#<Valute ID=\"([^\"]+)[^>]+>[^>]+>([^<]+)[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>[^>]+>([^<]+)[^>]+>[^>]+>([^<]+)#i"; 
  preg_match_all($pattern, $content, $out, PREG_SET_ORDER); 
  $dollar = ""; 
  $euro = ""; 
  foreach($out as $cur) 
  { 
    if($cur[2] == 840) $dollar = str_replace(",",".",$cur[4]); 
    if($cur[2] == 978) $euro   = str_replace(",",".",$cur[4]); 
    if($cur[2] == 826) $funt   = str_replace(",",".",$cur[4]);
  } 
  echo "Доллар - ".$dollar."<br>"; 
  echo "Евро - ".$euro."<br>"; 
  echo "Фунт стерлингов  - ".$funt."<br>";

function get_content(& $cUrl, $port = 80, $timeout = 10, $errCount = 1)
{
    curl_setopt($cUrl, CURLOPT_URL, "http://www.cbr.ru/scripts/XML_daily.asp");
    curl_setopt($cUrl, CURLOPT_PORT, $port);
    curl_setopt($cUrl,CURLOPT_RETURNTRANSFER,1);
    curl_setopt($cUrl, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)");
    curl_setopt($cUrl, CURLOPT_TIMEOUT, $timeout);
    $text = curl_exec($cUrl);
    if (curl_getinfo($cUrl,CURLINFO_HTTP_CODE) != 200) {
        return (($errCount < 3) ? FileGetContents("http://www.cbr.ru/scripts/XML_daily.asp", $port, $timeout, $errCount++) : false);
    } else {
        return $text;
    }
}

?>

Автор: americanets 9.3.2007, 13:50
работает а что за функция curl_init() ? 

Автор: mishaSL 9.3.2007, 14:33
Цитата(americanets @  9.3.2007,  13:50 Найти цитируемый пост)
работает а что за функция curl_init() ?  


http://ru.php.net/curl_init - Инициализирует сеанс CURL

Автор: lasalexx 20.3.2007, 23:05
если CURL не сможет открыть страницу в течении time_out а, то скрипт прервёт работу, или работу прервёт лижь функция, а скрипт дальше продолжит работу?

Автор: mishaSL 21.3.2007, 15:27
Цитата(lasalexx @  20.3.2007,  23:05 Найти цитируемый пост)
работу прервёт лижь функция, а скрипт дальше продолжит работу? 


да, работу прервет функция. smile 

Автор: CyClon 14.4.2007, 12:33
Почему я чаще использую сокеты, а не file для работы с удаленными страницами? Потому что многие сайты любят выдавать заголовок Location...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)