Автор Тема: Интересная вещь - парсинг хтмл  (Прочитано 3674 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн AlieN

  • Абыр!=)
  • Ветеран
  • *****
  • Сообщений: 1315
  • +0/-1
  • 2
    • Просмотр профиля
Интересная вещь - парсинг хтмл
« : 26 Июля 2002, 19:38:53 »
Суть задачи:
скрипт выкачивает файл откуда-то и парсит все ссылки
($buffer - весь возвратившийся от того сайта HTML код)

preg_match_all
("|<a(.*)href=\\"(.*)\\"(.*)>|U",$buffer,$regs,PREG_SET_ORDER);
for(
$i=0;$i<sizeof($regs);++$i)
	

	
{
	
if(
substr($regs[$i][2],0,7)!="http://")
	
	
{
	
	
if(
substr($regs[$i][2],0,1)!="/")
	
	
	
{
	
	
	
$h="$url2/".$regs[$i][2];
	
	
	
$buffer=str_replace($regs[$i][2],$h,$buffer);
	
	
	
print 
"
 WAS -- "
.$regs[$i][2].";
 NOW -- 
$h";
	
	
	
}
	
	
}
	
}

Всё бы хоршо а вот если ссылка встречается в файле более 1 раза то появляются такие фишки: http://server/http://server/somefile

Как от этого избавиьтся может кто сталкивался ХЕЛП :)
The Chemical Brothers - Hey Boy Hey Girl (User Friendly Mix)
Peter Presta pres - Set Sail(Peter Presta Apple Jaxx Dub) She S.Sunshine Feat Mila - Bring The Beat Back (Club Mix) Jerry Ropero - Home Alone (Dub Mix)

Оффлайн GotZfild

  • Универсал
  • Старожил
  • ****
  • Сообщений: 456
  • +0/-0
  • 2
    • Просмотр профиля
    • http://myphp.dem.ru
Интересная вещь - парсинг хтмл
« Ответ #1 : 26 Июля 2002, 20:31:38 »
Я бы немного переделал

preg_match_all
("|<a(.*)href=\\"(.*)\\"(.*)>|U"$buffer$regs);
$regs[2] = array_unique($regs[2]);
$regs[2] = array_values($regs[2]);
for(
$i=0;$i sizeof($regs[2]);$i++)    {
    if(
substr($regs[2][$i],0,7)!="http://")
        {
        if(
substr($regs[2][$i],0,1)!="/")
            {
            
$h="$url2/".$regs[2][$i];
            
$buffer=str_replace($regs[2][$i],$h,$buffer);
            print 
"
 WAS -- "
.$regs[2][$i].";
 NOW -- 
$h";
            }
        }
    }
После трех дней без программирования жизнь становится бессмысленной.

Оффлайн ThE0ReTiC

  • Главный по тарелочкам
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 4041
  • +2/-0
  • 2
    • Просмотр профиля
    • http://
Интересная вещь - парсинг хтмл
« Ответ #2 : 27 Июля 2002, 01:10:14 »
AlieN
А это не поможет?
http://php.spb.ru/php/url.html
AS IS...

Оффлайн Макс

  • vir magni ingenii
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3534
  • +0/-0
  • 2
    • Просмотр профиля
Интересная вещь - парсинг хтмл
« Ответ #3 : 27 Июля 2002, 03:03:42 »
вообще для html-парсинга есть библиотека htmlparser =>
http://anton.concord.ru/

Насчет твоей ситуации то проблема вероятно в  str_replace() - он ведь все вхождения заменяет. Можно preg_replace() использовать, только limit=1 укажи .
First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack. ( George Carrette )

Оффлайн GotZfild

  • Универсал
  • Старожил
  • ****
  • Сообщений: 456
  • +0/-0
  • 2
    • Просмотр профиля
    • http://myphp.dem.ru
Интересная вещь - парсинг хтмл
« Ответ #4 : 27 Июля 2002, 13:59:04 »
Макс
ИМХО, htmlparser\'ом изменять ссылки - это из серии пушкой по воробьям. Parser - вещь хорошая, но уж слишком громоздкая. Так, например, чтобы изменить все ссылки на данной странице, потребовалось 2.2778771 сек. Все же многовато.
Вот сам тест (если кто не верит)

require "parser/htmlparser.inc";
require 
"parser/common.inc";
$p=new HtmlParser("index.htm",unserialize(Read_File("htmlgrammar.cmp")),"index.htm",1);
$p->parse();
ChangeLinks(&$p->content);
GetPageSrc(&$p->content,&$src);

function 
ChangeLinks($c) {
      for (
$i 0$i <= $c[\'contentpos\']; $i++) {
            if ($c[$i][\'type\'] == "tag" && $c[$i][\'data\'][\'type\'] == "open") {
                  if ($c[$i][\'data\'][\'name\'] == "a" && $c[$i][\'pars\'][\'href\']) {
                        if (substr($c[$i][\'pars\'][\'href\'][\'value\'], 0, 7)!="http://" && $c[$i][\'pars\'][\'href\'][\'value\'][0] !="/") {
                              $c[$i][\'pars\'][\'href\'][\'value\'] = "http://myserver.com/".$c[$i][\'pars\'][\'href\'][\'value\'];
                        }
                  }
            }
            if ($c[$i][\'content\']) ChangeLinks(&$c[$i][\'content\']);
      }
      return $c;
}
После трех дней без программирования жизнь становится бессмысленной.

Оффлайн AlieN

  • Абыр!=)
  • Ветеран
  • *****
  • Сообщений: 1315
  • +0/-1
  • 2
    • Просмотр профиля
Интересная вещь - парсинг хтмл
« Ответ #5 : 29 Июля 2002, 13:26:09 »
Ну и что делать-то?
preg_replace выдает ошибку:

Warning: Delimiter must not be alphanumeric or backslash in /usr/local/apache/htdocs/catalog/mail/index.phtml on line 144

Вот код:

	
preg_match_all("|<a(.*)[Hh][Rr][Ee][Ff]=\\"(.*)\\"(.*)>|U",$buffer,$regs,PREG_SET_ORDER);
	
$regs[2] = array_unique($regs[2]);
	
$regs[2] = array_values($regs[2]);
	
for(
$i=0;$i<sizeof($regs);++$i)
	

	
	
{
	
	
if(
substr($regs[$i][2],0,7)!="http://")
	
	
	
{
	
	
	
if(
substr($regs[$i][2],0,1)!="/")
	
	
	
	
{
	
	
	
	
$h="$url2/".$regs[$i][2];
	
	
	
	
preg_replace(str_replace("\\\\","\\\\\\\\",$regs[$i][2]),str_replace("\\\\","\\\\\\\\",$h),$buffer);
	
	
	
	
print 
"
 WAS -- "
.$regs[$i][2]."
 NOW -- 
$h";
	
	
	
	
}
	
	
	
}
	
	
}
The Chemical Brothers - Hey Boy Hey Girl (User Friendly Mix)
Peter Presta pres - Set Sail(Peter Presta Apple Jaxx Dub) She S.Sunshine Feat Mila - Bring The Beat Back (Club Mix) Jerry Ropero - Home Alone (Dub Mix)

Оффлайн GotZfild

  • Универсал
  • Старожил
  • ****
  • Сообщений: 456
  • +0/-0
  • 2
    • Просмотр профиля
    • http://myphp.dem.ru
Интересная вещь - парсинг хтмл
« Ответ #6 : 29 Июля 2002, 16:20:05 »
Попробуй сменить delmiter в regexp\'е на / или букву, либо цифру.
Цитировать
(.*)[Hh][Rr][Ee][Ff]=

для этого есть модификатор i
И убери
Цитировать
PREG_SET_ORDER
После трех дней без программирования жизнь становится бессмысленной.

Оффлайн GotZfild

  • Универсал
  • Старожил
  • ****
  • Сообщений: 456
  • +0/-0
  • 2
    • Просмотр профиля
    • http://myphp.dem.ru
Интересная вещь - парсинг хтмл
« Ответ #7 : 29 Июля 2002, 16:23:20 »
Ой ё. Этого не заметил
Цитировать
preg_replace(str_replace("\\","",$regs[$i][2]),str_replace("","",$h),$buffer);

Зачем тебе preg_replace нужен?
Посмотри выше, я тебе там привел рабочий пример.
После трех дней без программирования жизнь становится бессмысленной.

Оффлайн AlieN

  • Абыр!=)
  • Ветеран
  • *****
  • Сообщений: 1315
  • +0/-1
  • 2
    • Просмотр профиля
Интересная вещь - парсинг хтмл
« Ответ #8 : 29 Июля 2002, 16:45:51 »
GotZfild
твой пример что-то совсем не пашет
The Chemical Brothers - Hey Boy Hey Girl (User Friendly Mix)
Peter Presta pres - Set Sail(Peter Presta Apple Jaxx Dub) She S.Sunshine Feat Mila - Bring The Beat Back (Club Mix) Jerry Ropero - Home Alone (Dub Mix)

Оффлайн GotZfild

  • Универсал
  • Старожил
  • ****
  • Сообщений: 456
  • +0/-0
  • 2
    • Просмотр профиля
    • http://myphp.dem.ru
Интересная вещь - парсинг хтмл
« Ответ #9 : 29 Июля 2002, 16:56:23 »
У меня пашет
Вот протестил:

$buffer 
= \'
<p><a href="http://ya.ru">линк</a></p>
<p><a href="/page.htm">линк</a> <a href="page2.htm">еще линк</a> - - <a href="another.htm">два
  линк</a></p>
<p><a href="page2.htm">и еще</a></p>\';

preg_match_all("|<a(.*)href=\\"(.*)\\"(.*)>|U", $buffer, $regs);
$regs[2] = array_unique($regs[2]);
$regs[2] = array_values($regs[2]);
$url2 = "http://new_domen";
for($i=0;$i < sizeof($regs[2]);$i++)    {
    if(substr($regs[2][$i],0,7)!="http://")
        {
        if(substr($regs[2][$i],0,1)!="/")
            {
            $h="$url2/".$regs[2][$i];
            $buffer=str_replace($regs[2][$i],$h,$buffer);
            print "
 WAS -- ".$regs[2][$i].";
 NOW -- $h";
            }
        }
    }

echo "<pre>".htmlspecialchars($buffer);

Вывел
WAS -- another.htm;
NOW -- [url]http://new_domen/another.htm[/url]
WAS -- page2.htm;
NOW -- [url]http://new_domen/page2.htm[/url]

линк


линк еще линк - - два
  линк


и еще


После трех дней без программирования жизнь становится бессмысленной.

Оффлайн AlieN

  • Абыр!=)
  • Ветеран
  • *****
  • Сообщений: 1315
  • +0/-1
  • 2
    • Просмотр профиля
Интересная вещь - парсинг хтмл
« Ответ #10 : 29 Июля 2002, 20:01:35 »
GotZfild
спасибаЧЧки, после небольшой доработки:

	
preg_match_all("|<a(.*)href=\\"(.*)\\"(.*)>|U"$buffer$regs); 
	
$regs[2] = array_unique($regs[2]);
	
$regs[2] = array_values($regs[2]); 
	
for(
$i=0;$i sizeof($regs[2]);$i++)    
	
	
{
    
	
if(
substr($regs[2][$i],0,7)!="http://")
        
	
{
        
	
if(
substr($regs[2][$i],0,1)!="/")
            
	
{
            
	
$h="$url2/".$regs[2][$i];
            
	
$buffer=str_replace($regs[2][$i],$h,$buffer);
            
	
}
	
	
	
if(
substr($regs[2][$i],0,1)=="/")
            
	
{
            
	
$h="$url1".$regs[2][$i];
            
	
$buffer=str_replace($regs[2][$i],$h,$buffer);
            
	
}
        
	
}
    
	
}

Всё заработало идеально
The Chemical Brothers - Hey Boy Hey Girl (User Friendly Mix)
Peter Presta pres - Set Sail(Peter Presta Apple Jaxx Dub) She S.Sunshine Feat Mila - Bring The Beat Back (Club Mix) Jerry Ropero - Home Alone (Dub Mix)

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28