Парсер HTML в MySQL. Как?

Статус
В этой теме нельзя размещать новые ответы.

GEEPERS

Знаток
Регистрация
26 Янв 2008
Сообщения
162
Реакции
25
Есть например, HTML-страница:
HTML:
<html>
<head>
<title>A Title</title>
</head>
<body>
Hello World!
<a href="http://w3.org">HTML</a>
page.
<p>More text... <a href="#">a link</a>, blah-blah-blah.</p>
<img src="img/image.jpg" alt="some image" />
</body>
Как распарсить теги (их содержимое: <a>*</a>, <p>*</p>), каждую категорию в отдельную таблицу в мускуль?
Причем, если напр., тег <р> содержит внутри себя <а>, то <а> не должен попасть в таблицу к <р>.

пока есть такое начало:
PHP:
$url="http://site.com";
function html_to_array( $url, $element = null )
{
    if( !( $data = file_get_contents( $url ) ) )
        return false;
    
    preg_match_all( '~<img.*?>(</img>)?~si', $data, $page['img'] );
    preg_match_all( '~<p.*?>.*?[^<]</p>~', $data, $page['p'] );
    preg_match_all( '~<a.*?[^>].*[^<]</a>~', $data, $page['Link'] );
    return !is_null( $element ) ? $page[ $element ] : $page ;
}
 
определитесь с допустимой нагрузкой.
если вы не собираетесь сутками парсить, на самом дешевом хосте, то я полагаю вам подойдет DOM Document из стандартных функций.
это целый набор классов для работы с XML(HTML также поддерживается)
на самом деле, DOM есть во многих языках
насколько я понял вашу задачу, DOM вам отлично подойдет.
он подходит для широкого спектра задач c (X)HTML и XML
 
:) А зачем скобка в первом регулярном выражении?
 
ioleg, некоторые теги(например img) закрыватся могут двумя способами
HTML:
<img src='test.JPG'/>
HTML:
<img src='test.JPG'></img>
вот для второго и сделаны круглые скобки, показывающие возможную, но необязательную необхоимость(квантификатор ?) закрывающего тега
 
Причем, если напр., тег <р> содержит внутри себя <а>, то <а> не должен попасть в таблицу к <р>.
Т.е. очистить внутренности тега от тегов что ли?
 
Т.е. очистить внутренности тега от тегов что ли?

да, и от их содержимого (<а>*</а>)

UPD: ok, вот что получилось с помощью DOM'a:
PHP:
// find all link
foreach($html->find('a') as $e) 
    echo $e->href . '<br>';
// find all image with full tag
foreach($html->find('img') as $e)
    echo $e->outertext . '<br>';
// find all p tag
foreach($html->find('p') as $e)
    echo $e->outertext . '<br>';
Теперь вопросы:
  1. Как исключить из результата содержимое <а>*</а> (вместе с самим тегом)?
  2. Как полученным значениям присвоить переменные для последующей обработки (занесения в базу)?
    Простое $х=$e->href... - не работает, т.к. показывает только одну ссылку.
 
Проверка наличия определенного значения из массива:

PHP:
foreach ($array as $val)
     if(isset($e->$val))   
 echo $e->$val;
как занести результаты (тоесть все значения $e->$val) каждый в свою переменную?
т.к. $а=$e->$val; содержит только последнее значение, полученное из foreach.
 
А может просто убрать из файла все кроме тех тегов которые нужны путем ф-ии strip_tags()
$string = strip_tags($string, '<a><b><i><u>');

будет убрано все кроме содержимых этих тегов <a><b><i><u>
 
2GEEPERS
Если вы используете simplehtmldom хотя я не думаю что в каких то дом есть отличия то
выдерание всех p
PHP:
$p_arr=array();
foreach($html->find('p') as $p) {
    foreach($p->find('a, img') as $e)
        $e->outertext = '';
    $p_arr[]=$p->innertext;
}
P.S. на правильность не проверял и писал по памяти
 
2swer:
не то, мне нужно то, что вне этих тегов, причем не сплошным текстом, а по частям, пронумерованным в том же порядке, в котором они расположены в исх. тексте.

2bunny:
да, почти. вот что у меня получилось с simplehtmldom:
PHP:
$html = file_get_html('http://site.com');
  foreach($html->find('body') as $e) //put <body> tag to $e
   $body = $e->innertext . '<br>';	//get <body>
    echo '<p><b><u>This is the body: </u></b>'.$body .'</p>{end body}<br>'; 
	
$array = $e->children(); 	//put <body> children tags to an array
  foreach ($array as $key=>$val)
	echo "<br><b>Body's child #$key:</b> <p>$val</p>";

//put all common <body>	attributes to an array
$body_attr_arr=
    array('class','dir','id','lang','style','title','xml:lang','alink','background','bgcolor','link','text','vlink');
  
   foreach ($body_attr_arr as $attr)
    if(isset($e->$attr))    //check if <body> has an attribute from the array and extract its (attrib.) value
     $return[] = $e->$attr;  //the results to an array
 
   foreach ($return as $key=>$val) 
	echo "<br>Body's $key attribute: <u><i>$val</i></u><br>";

это все работает, осталось две задачи: выделить текст из <body> и занести это все в mysql.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху