Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум Регулярные Выражения

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Граббер телевизионной программы на PHP
 
 автор: trashz   (19.11.2005 в 21:35)
 
 

Как создать такую вещь? Использую регулярные выражения?
Как, анпример, пограбить всю программу с http://tv.rambler.ru/ ?

   
 
 автор: goddamn   (19.11.2005 в 22:06)   письмо автору
 
   для: trashz   (19.11.2005 в 21:35)
 

а если конкретнее ? что именно "грабить" и как часто ?

   
 
 автор: cheops   (20.11.2005 в 14:01)   письмо автору
 
   для: trashz   (19.11.2005 в 21:35)
 

План должен быть следующим:
1) Загрузка страниц при помощи файловых функций, например, get_file_contents() или fopen()+fread() или при помощи сокетов.
2) Разбор страниц
<?php
  $text 
file_get_contents("opr012GM.html");
  
$pattern "|<tr valign=\"top\">(.*)</tr>|isU";
  
preg_match_all($pattern,$text,$out);
  
print_r($out);
?>

Только нужно чётче прописать какую информацию вы хоите извлечь? Блоки таблицы, или просто чистый текст?

   
 
 автор: trashz   (20.11.2005 в 16:15)
 
   для: trashz   (19.11.2005 в 21:35)
 

Спасибо за ответы, друзья.
Я решил, что tv.rambler.ru - слишком много там ненужного.

Вобщем, я буду брать ифну с http://tv.yandex.ru/?day=13107&hour=6&period=24&flag=&channel=103 , где параметр channel будет изменяться.
Как мне из этой ссылки ( http://tv.yandex.ru/?day=13107&hour=6&period=24&flag=&channel=103 ) вырезать информацию, начинающуюся после
<table width="59%" border="0" cellspacing="0" cellpadding="10" class="channel"><tr><td class="hr"><div><spacer></spacer></div></td></tr></table>

и кончающуюся перед
<br><table width="100%" border="0" cellspacing="0" cellpadding="0" class="searchResults"><tr valign="top">
?

Будет ли работать такая система: в начале своего пхп-файла я буду копировать страничку http://tv.yandex.ru/?day=13107&hour=6&period=24&flag=&channel=103, а потом уже её обрабатывать? Как это сделать?
copy("http://tv.yandex.ru/?day=13107&hour=6&period=24&flag=&channel=103", "page.html");
или как-нибудь по-другому можно?

   
 
 автор: cheops   (20.11.2005 в 21:19)   письмо автору
 
   для: trashz   (20.11.2005 в 16:15)
 

Да такая система будет работать, возможно вам будет удобнее сразу копировать содержимое страницы в переменную $text
<?php
$text 
file_get_contents("http://tv.yandex.ru/?day=13107&hour=6&period=24&flag=&channel=103""page.html");
?.

   
 
 автор: trashz   (20.11.2005 в 21:25)
 
   для: cheops   (20.11.2005 в 21:19)
 

Окей, а не поможете написать регулярное выражение для ссылки, приведенной выше?

   
 
 автор: cheops   (21.11.2005 в 13:01)   письмо автору
 
   для: trashz   (20.11.2005 в 21:25)
 

Можно воспользоваться следующим скриптом
<?php
  $text 
file_get_contents("http://tv.yandex.ru/?day=13107&hour=6&period=24&flag=&channel=103");
  
$pattern "|<div class=\"gone\">[\s]*(.*)</div>|isU";
  
preg_match_all($pattern,$text,$out);
  foreach(
$out[1] as $line)
  {
    echo 
$line."<br>";
  }
?>

   
 
 автор: trashz   (21.11.2005 в 15:00)
 
   для: cheops   (21.11.2005 в 13:01)
 

Спасибо, а как сделать так, чтобы время оставалось в теге <b></b>, а то сохраняется только текст с линком на времени.
Или вот на этой ссылке( http://tv.yandex.ru/?hour=6&period=24&day=13107&flag=&channel=1 ) скрипт выводит
0:10 Бокс. Бой сильнейших профессионалов мира

Жирным цветом название. Как это убрать?
И ещё, как сделать, чтобы линк "broadcast.xml?id=3451072" шел не на мой хост, а на tv.yandex.ru?
Заранее спасибо

   
 
 автор: cheops   (21.11.2005 в 21:43)   письмо автору
 
   для: trashz   (21.11.2005 в 15:00)
 

Можно поступить следующим образом
<?php
  $text 
file_get_contents("http://tv.yandex.ru/?day=13107&hour=6&period=24&flag=&channel=103");
  
$pattern "|<div class=\"gone\">[\s]*[^>]+>([\d]+:[\d]+)<[^>]+>(.*)</div>|isU";
  
preg_match_all($pattern,$text,$out);
  for(
$i 0$i count($out[1]); $i++)
  {
    echo 
$out[1][$i]." - ".$out[2][$i]."<br>";
  }
?>

   
 
 автор: trashz   (21.11.2005 в 21:54)
 
   для: cheops   (21.11.2005 в 21:43)
 

Супер! Спасибо огромное, cheops.
Ещё одна, вероятно, последняя, просьба. :)
Можно как-нибудь выдрать линки, которые стоят на времени? Или оставить их на месте?
Чтобы вид выдбранной информации блы таков:
<a href="http://tv.yandex.ru/broadcast.xml?id=3433363(туту меняется)">22:10</a> название передачи


Огромное спасибо ещё раз за оказанную помощь.

   
 
 автор: cheops   (22.11.2005 в 01:05)   письмо автору
 
   для: trashz   (21.11.2005 в 21:54)
 

Имеется ввиду вытащить http://tv.yandex.ru/broadcast.xml?id=3433363 или нет?

   
 
 автор: trashz   (22.11.2005 в 07:54)
 
   для: cheops   (22.11.2005 в 01:05)
 

Да, чтобы массив со временем содержал ссылку, которая указана на tv.yandex.ru. Только полную, т.е. http://tv.yandex.ru/broadcast.xml?id=3433363, а не просто broadcast.xml?id=3433363

   
 
 автор: cheops   (22.11.2005 в 13:39)   письмо автору
 
   для: trashz   (22.11.2005 в 07:54)
 

Можно поступить следующим образом
<?php 
  $text 
file_get_contents("http://tv.yandex.ru/?day=13107&hour=6&period=24&flag=&channel=103"); 
  
$pattern "|<div class=\"gone\">[\s]*<a href=\"([^\"]+)\"[^>]+>([\d]+:[\d]+)<[^>]+>(.*)</div>|isU"
  
preg_match_all($pattern,$text,$out); 
  for(
$i 0$i count($out[1]); $i++) 
  { 
    echo 
"<a href=http://tv.yandex.ru".$out[1][$i].">".$out[2][$i]."</a> - ".$out[3][$i]."<br>"
  } 
?>

   
 
 автор: Axxil   (22.11.2005 в 17:24)   письмо автору
 
   для: cheops   (22.11.2005 в 13:39)
 

А можно тогда со страницы например:
http://tv.yandex.ru/broadcast.xml?id=3433371
вытащить описание и название фильма?

Можно таким образом достаточно быстро составить базу описаний фильмов. Пригодится.

   
 
 автор: cheops   (23.11.2005 в 01:29)   письмо автору
 
   для: Axxil   (22.11.2005 в 17:24)
 

Можно попробовать так
<?php 
  $text 
file_get_contents("opr00KWU.htm"); 
  
$pattern "|<h1>([^<]+)</h1>|is"
  
preg_match($pattern,$text,$out); 
  echo 
$out[1]."<br>"
  
$pattern "|</b>(.*)<p>|isU";
  
preg_match($pattern,$text,$out); 
  echo 
$out[1]."<br>"
?>

но мне если честно не очень нравится последнее регулярное выражение - не очень устойчивое, его тестировать следует...

   
 
 автор: Axxil   (23.11.2005 в 12:14)   письмо автору
 
   для: cheops   (23.11.2005 в 01:29)
 

Вроде работает нормально...

Тут другая проблема. В яндексе просмотренные передачи становятся серыми. И поэтому если брать текущий день, то после разбора выводятся передачи только которые уже кончились, т.е. имеющие серый цвет. Как можно решить такую штуку?

И ещё в той же программе фильмы выделяются картинкой с кинокамерой. Можно ли как-то после разбора страницы вывести исключительно фильмы, т.е. строки с картинкой в виде камеры.

   
 
 автор: cheops   (23.11.2005 в 13:01)   письмо автору
 
   для: Axxil   (23.11.2005 в 12:14)
 

А что-то с серым не очень понятно - там добавляются дополнительные тэги? Можно ссылку...

   
 
 автор: Axxil   (23.11.2005 в 16:46)   письмо автору
 
   для: cheops   (23.11.2005 в 13:01)
 

Приложил в атаче 2 файла:
1. gray.html кусок кода с серыми записями. Всё отличие там только в значении класса.
class=gone - передача кончилась цвет серый
class=bold - передача идёт цвет чёрный
Я так понимаю в регулярном выражении надо учитывать оба случая...
Может так?

<?php 
  $text 
file_get_contents("http://tv.yandex.ru/?day=13107&hour=6&period=24&flag=&channel=103"); 
  
$pattern "|<div class=\"[^\"]{4}\">[\s]*<a href=\"([^\"]+)\"[^>]+>([\d]+:[\d]+)<[^>]+>(.*)</div>|isU"
  
preg_match_all($pattern,$text,$out); 
  for(
$i 0$i count($out[1]); $i++) 
  { 
    echo 
"<a href=http://tv.yandex.ru".$out[1][$i].">".$out[2][$i]."</a> - ".$out[3][$i]."<br>"
  } 
?> 


2. yatv.html кусок кода страницы телепрограммы яндекса с фильмами. Там фильм отдичается от обычной передачи тем что перед ним стоит тег <IMG
class=noprint height=16 alt=Фильм src="/i/i16-movie.gif" width=16 align=middle
border=0>. Мне кажется по этому принципу можно вытащить со страницы только фильмы. Или нельзя?

   
 
 автор: Axxil   (24.11.2005 в 09:16)   письмо автору
 
   для: Axxil   (23.11.2005 в 16:46)
 

Тема ещё не исчерпана :)

У меня вопрсы остались. Пост выше...

   
 
 автор: cheops   (24.11.2005 в 13:01)   письмо автору
 
   для: Axxil   (24.11.2005 в 09:16)
 

1) Попробуйте так
<?php 
  $text 
file_get_contents("http://tv.yandex.ru/?day=13107&hour=6&period=24&flag=&channel=103"); 
  
$pattern "|<div [^>]+>[\s]*<a href=\"([^\"]+)\"[^>]+>([\d]+:[\d]+)<[^>]+>(.*)</div>|isU"
  
preg_match_all($pattern,$text,$out); 
  for(
$i 0$i count($out[1]); $i++) 
  { 
    echo 
"<a href=http://tv.yandex.ru".$out[1][$i].">".$out[2][$i]."</a> - ".$out[3][$i]."<br>"
  } 
?>

   
 
 автор: cheops   (24.11.2005 в 13:04)   письмо автору
 
   для: Axxil   (24.11.2005 в 09:16)
 

2) Можно предварительно искать вхождение указанной строк и <img ...> при помощи обычных строковых функций - если она есть - парсим, если нет, игнорируем страницу.

   
 
 автор: Axxil   (24.11.2005 в 13:57)   письмо автору
 
   для: cheops   (24.11.2005 в 13:04)
 

Так вот именно что нужно игнорировать не всю страницу, а только НЕ фильмы. Может быть в здоровенной программе быть один всего фильм (теоретически).
Может это можно как-то в цикле делать, или возможно регулярное выражение фильтрующее таким образом?

   
 
 автор: cheops   (25.11.2005 в 18:26)   письмо автору
 
   для: Axxil   (24.11.2005 в 13:57)
 

Хм... т.е имеется ввиду список передач, а не описание?

   
 
 автор: Axxil   (25.11.2005 в 20:12)   письмо автору
 
   для: cheops   (25.11.2005 в 18:26)
 

Нет с описанием мы же уже разобрались :)
А сейчас нужно из списка передач вытащить только фильмы, чтобы потом по ссылкам на которые они ведут можно было вытащить их описания.
Фильм маркируется картинкой и интуитивно мне кажется что проблем быть не должно, но к сожалению знаний для подтверждения интуиции не хватает :(

   
 
 автор: cheops   (26.11.2005 в 13:40)   письмо автору
 
   для: Axxil   (25.11.2005 в 20:12)
 

Можно использовать следующий скрипт
<?php 
  $text 
file_get_contents("http://tv.yandex.ru/?day=13107&hour=6&period=24&flag=&channel=103"); 
  
$pattern "|<div class=\"movie_f\">[\s]*<[^>]+>[\s]*<a href=\"([^\"]+)\">([\d]+:[\d]+)<[^>]+><[^>]+>[^>]+>[^>]+>(.*)</span>|isU"
  
preg_match_all($pattern,$text,$out);
  for(
$i 0$i count($out[1]); $i++) 
  { 
    echo 
"<a href=http://tv.yandex.ru".$out[1][$i].">".$out[2][$i]."</a> - ".$out[3][$i]."<br>"
  } 
?>

   
 
 автор: Олег87   (26.11.2005 в 18:18)   письмо автору
 
   для: cheops   (26.11.2005 в 13:40)
 

не могли бы вы полностью объяснить вот эту строку:
|<div class=\"movie_f\">[\s]*<[^>]+>[\s]*<a href=\"([^\"]+)\">([\d]+:[\d]+)<[^>]+><[^>]+>[^>]+>[^>]+>(.*)</span>|isU
что оэначают знаки | : . isU

спасибо.

   
 
 автор: cheops   (26.11.2005 в 21:40)   письмо автору
 
   для: Олег87   (26.11.2005 в 18:18)
 

| - означает границу регулярного выражения, вместо этого символа может быть любой другой, например, следующие регулярные выражения эквивалентны
|<div class=\"movie_f\">[\s]*<[^>]+>[\s]*<a href=\"([^\"]+)\">([\d]+:[\d]+)<[^>]+><[^>]+>[^>]+>[^>]+>(.*)</span>|isU
#<div class=\"movie_f\">[\s]*<[^>]+>[\s]*<a href=\"([^\"]+)\">([\d]+:[\d]+)<[^>]+><[^>]+>[^>]+>[^>]+>(.*)</span>#isU
/<div class=\"movie_f\">[\s]*<[^>]+>[\s]*<a href=\"([^\"]+)\">([\d]+:[\d]+)<[^>]+><[^>]+>[^>]+>[^>]+>(.*)<\/span>/isU


: - означает :, там просто время в формате ##:##

. - означает любой символ, если необходимо обозначать символ точки - его обязательно следует экранировать \.

isU - это Perl-модификаторы, i - это независимость от регистра, s - искать по всему тексту, а не до первого перевода строки, U - инвертирует жадность - вообще регулярные выражения по умолчанию жадные, т.е. ищут максимально длинное соответствие. Этот модификатор сообщает о том, что следует искать максимально короткие соответствия. Без модификатора U выражение .* лучше не использовать - ничего хорошего не выйдет.

   
 
 автор: Олег87   (26.11.2005 в 23:35)   письмо автору
 
   для: cheops   (26.11.2005 в 21:40)
 

прочитал все что есть про рег.выр., прочитал весь этот форум про РВ(кстати, я так много инфы как здесь нигде не встречал), скачал все твои примеры на этом форуме, cheops, и все-равно не могу понять как ты их составляшь..:)) поделись секретом..

   
 
 автор: cheops   (27.11.2005 в 13:41)   письмо автору
 
   для: Олег87   (26.11.2005 в 23:35)
 

Это делается очень просто :))) В обязательном порядке достаётся книга Дж. Фридл "Регулярные выражения" - не очень простое чтение, но прочитать её следует несколько раз (хотя бы до середины :). Однако этого не достаточно, необходима практика - например, можно выбрать форум и пытаться отвечать на все вопросы по регулярным выражениям, даже если кто-то приводит решение - всё-равно необходимо писать своё. Или как вариант пытаться при помощи их решать любую задачу на строковые функции, даже если сначала вам проще обойтись без регулярных выражений.

Дело в том, что регулярные выражения являются мини-языком и подходить к их изучению следует именно с позиции изучения нового языка программирования. Т.е. с покупкой книг, их изучением, тренировкой - иначе всё это будет казаться вам магией :))) Усилий на их изучение требуется много - но они вам с лихвой окупятся - это всё равно что знать десятипальцевый метод.

PS Вы можете задавать в этом разделе любые вопросы по регулярным выражениям, всё что знаю - расскажу :)))

   
 
 автор: Олег87   (27.11.2005 в 15:18)   письмо автору
 
   для: cheops   (27.11.2005 в 13:41)
 

>Это делается очень просто :))) В обязательном порядке
>достаётся книга [url =
>http://www.softtime.ru/article/index.php?id_article=62]Дж.
>Фридл &quot;Регулярные выражения&quot; [/url] - не очень
>простое чтение, но прочитать её следует несколько раз (хотя
>бы до середины :).

я её уже достал :) http://www.phpfaq.ru/files/friedl.rar ещё завтра в библиотеку схожу, возьму там, чтобы в оффлайне, перед сном читать :))

>Дело в том, что регулярные выражения являются мини-языком и
>подходить к их изучению следует именно с позиции изучения
>нового языка программирования. Т.е. с покупкой книг, их
>изучением, тренировкой - иначе всё это будет казаться вам
>магией :)))
>Усилий на их изучение требуется много - но они
>вам с лихвой окупятся - это всё равно что знать
>десятипальцевый метод.

Всё ясно :)

>PS Вы можете задавать в этом разделе любые вопросы по
>регулярным выражениям, всё что знаю - расскажу :)))

Это я уже понял когда в первый раз сюда зашел :)

   
 
 автор: trashz   (23.11.2005 в 19:06)
 
   для: trashz   (19.11.2005 в 21:35)
 

спасибо, cheops, за помощь!

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования