KsI-wiki online documents

Perl html parsing

Материал из Ksimute

Перейти к: навигация, поиск

Коробанов Сергей
Декабрь 22, 2007



Сразу скажу. Я не программист.
Код мой страшен, программеры ужасаются, но читабелен и работающий.
Девелоперские задачи решаю небольшие, а для серьезных проектов у нас есть штатные разработчики.

Но тем не менее каждый админ должен знать bash,sed,awk, regexp, и Perl (перл рулез), еще VBA, WSH, HTA, HTML, SQL, PHP и C.

Хотябы немножко :) и знать какой мануал вкурить.

Содержание

Исходная задача:

Имеем каталог с html файлами. Каждый файл содержит различный трэш из тэгов, рекламы, непонятного контента.

нечто похожее на.



<html>
<head>
</head>
<body>

	Всякий контент
	<h1>Вася<h1>
	Итак Вашему вниманию представлены высказывания Васи на последней корпоративке.
	<ul>
		<li> 1 супер-мега фраза про боулинг
		<li> 2 сногшибательный загнул анекдот про программеров
		<li> 3 мега-супер высказывание про политику
	<ul>

	Он жестоко накосячил в вопросе политики, за что будет взят на карандаш нашей службой 
	СБ и под колпак системой СОРМ-2. :) :).
</body>
</html>



Нас интересует тэг:
<H1>автор высказывания</H1>

И тэги


<LI>, содержащие фразы Автора.

Необходимо создать SQL запрос, для добавления в таблицу table двух полей author и frase.

В каждом файле <H1></H1> встречается только один раз, а

<LI></LI> может быть несколько.

Используем HTML::TreeBuilder. Тянем его с http://www.cpan.org и ставим.

 ksi~#gcpan -i HTML::TreeBuilder

Читаем документацию:

perldoc HTML::TreeBuilder

perldoc HTML::Element

Скрипт:


 #!/usr/bin/perl
 
 use HTML::TreeBuilder;
 
 my $author;
 my $frase;
 my $dir='./*.shtml';
 
 #get directory listing
 @dir_list=glob($dir);
 
 foreach $File(@dir_list){
 my $tree = HTML::TreeBuilder->new;
 $tree->parse_file($File);
 
 #Ищем автора т.к. переменная h1 объявлена как скаляр, вернется только 
 #первый найденный элемент.
 
 my $h1 = $tree->find('H1');
 if ($h1)
     {
     $author = $h1->as_text;
     }
 
 #Ищем высказывание т.к.	переменная @li объявлена как массив, она будет 
 #содержать все найденные LI
 
 my @li = $tree->find('LI');
 
 foreach (@li){
     $frase=$_->as_text;
     print "INSERT into table set author=`$author`,frase=`$frase`\;\n";
 }
 $tree->delete; #clear memory
 }

Все! стартуем скрипт, гоним через поток вывод в result.sql, конвертируем с помощью iconv в требуемую кодировку,

 ksi~#cat result.sql | iconv -f koi8-r -t cp1251 > result-cp1251.sql

и кормим базу.

Ссылки

http://cpan.org/