Здравствуйте уважаемые обитатели этого форума!
Передо мной встала задача и я испытываю некоторые затруднения в ее решении. Прошу помочь дельными советами, поделиться опытом, подсказать по теме. А я опишу, в чем суть задачи и что я пытался предпринять.
В связи с нерегулярным доступом в сеть, мне захотелось иметь у себя на ноутбуке локальную копию сайта-коллекции текстов песен с аккордами для гитары. Обычно за аккордами для нужной песни я хожу на amdm.ru, поэтому я и попытался тупо скачать весь этот сайт, но администрация этого ресурса наложила ограничения на пользователей, скачать сайт не удается. Ну я и открыл для себя pesenki.ru
Скачиваю сайт целиком с помощью такого вот заклинания:
nohup wget -c --mirror --convert-links --no-verbose --no-parent \
--page-requisites --user-agent="Mozilla/5.0 (compatible; \
Konqueror/4.3; Linux 2.6.30-2-amd64; X11; x86_64; ru) KHTML/4.3.2 (like Gecko)" pesenki.ru &
Качаю уже несколько дней, ибо во-1х канал не особо широк, и во-2х, через несколько часов работы процесс wget потихоньку заполняет собой всю оперативную память и комп люто бешено висит, почти не реагируя ни на что. В общем, пока скачалось примерно
280 000 страниц, общим размеров примерно 5 Гб.
Это присказка. Смешно будет дальше.
По интернетам я ползаю посредством iceweasel, а локальные html-файлы у меня по дефолту открываются konqueror-ом. На iceweasel конечно же установлен adblock, а на konqueror конечно нет, поэтому, когда я открыл им для проверки одну из скачанных страничек - мягко говоря, удивился - аккуратный и прилежный сайт-справочник превратился в сплошное ПЫЩЬ ПЫЩЬ ОЛОЛОЛО, реклама была повсюду.
Я взглянул на исходный код и был поражён.
Одна из страничек с сайта pesenki.ru, для примера). Я проникся искренним сочуствием к тем пользователям, которые не знают о таком счастье, как adblock... Но не суть.
Встала задача выпилить к чертовой матери все ненужное из исходного кода. Относительно элегантно проблема должна была решиться бы, если бы удалось удалить блоки текста такого вида: <script.*?</script> и по аналогии с другими тэгами.
Я долго экспериментировал со связкой команд find и sed, и периодически что-то у меня получалось. В итоге самое умное до чего я додумался это что-то такое примерно:
find /home/leonder/downloads/pesenki.ru/ -iname "*html" -print0 | \
xargs -0 -P 2 sed -e '/<script/,/<\/script>/d' \
-e '/<noscript/,/<\/noscript>/d' -e '/<iframe/,/<\/iframe>/d' \
-e '/<!--/,/-->/d'
но тут я столкнулся с проблемой...
Выражаясь человеческим языком, от sed мне нужно следующее: найти и вырезать куски текста, соответствующие шаблону - ПЕРВОЕ вхождение сроки «<script», потом сколько угодно любого текста вплоть до ПЕРВОГО же вхождения строки «</script>». Но мне так и не удалось составить нужное рег. выражение ((( А то, что я употребил - находит текст между ПЕРВЫМ вхождением ПЕРВОГО выражения и ПОСЛЕДНИМ вхождением второго выражения.
Нужного эффекта мне когда-то ранее (давно) удавалось добиться на PHP, когда я написал скрипт - своеобразное зеркало башорга. В общем я посидел ночь и сваял вот такое рекурсивное чудо, которое работает иначе - не вырезает ненужный код, а наоборот - компонует новый файл из нужных кусков:
<?php
$count=0;
function cleancode($dirname)
{
global $count;
$dir = opendir($dirname);
while (($file = readdir($dir)) !== false)
{
if($file !== "." && $file !== "..")
{
//Если очередной $file - каталог, то нырнуть в него, рекурсивно применя функцию
$sub_dir = $dirname.'/'.$file;
if(is_dir($sub_dir))
{
cleancode($sub_dir);
}
$file_arr=explode(".", $file);
$ext = strtolower(end($file_arr));
if( $ext=="shtml" || $ext=="html" || $ext=="htm" )
{
$file_source_all[][$dirname]=$file;
#echo $dirname.'/'.$file.'<br/>';
$file_content = file_get_contents ($dirname.'/'.$file);
$pattern="'<script[^>]*?>.*?</script>'si";
$pattern1="'<noscript[^>]*?>.*?</noscript>'si";
$pattern2="'<iframe[^>]*?>.*?</iframe>'si";
$pattern3="'<br><noindex>.*?</noindex>'si";
$replace="";
$file_content=preg_replace($pattern, $replace, $file_content);
$file_content=preg_replace($pattern1, $replace, $file_content);
$file_content=preg_replace($pattern2, $replace, $file_content);
$file_content=preg_replace($pattern3, $replace, $file_content);
$new_file_content = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Локальная копия сайта pesenki.ru</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
</head>
<body bgcolor="#e5e5e5">
';
preg_match('#<strong style="font-size:110%;">(.*?)</strong>#si',$file_content,$res);
$new_file_content.=$oglavlenie = $res[0].'<br><br>';
preg_match('#<div class=zag>(.*?)</div>#si',$file_content,$res);
$new_file_content.=$div_zag = $res[0].'<br>';
preg_match('#<div class=wzag>(.*?)</div>#si',$file_content,$res);
$new_file_content.=$div_zag2 = $res[0].'<br>';
preg_match('#<font><b>(.*?)</b></font>#si',$file_content,$res);
$new_file_content.=$list = $res[0].'<br>';
preg_match_all('#<td class=m1><b><a href="(.*?)><b class=(.*?)</a>#si',$file_content,$res);
foreach ($res[0] as $link) $new_file_content.= $list2 = str_replace(' class=ctxt','',$link).'<br>';
preg_match('#<pre>(.*?)</pre>#si',$file_content,$res);
$new_file_content.= $text_with_chords = $res[0];
$new_file_content.='</body></html>';
if(file_put_contents('/tmp/cleaning/'.$file, $new_file_content))
{
$count++;
$percent=round($count/670,2);
echo '<b>'.$percent.'%</b>, файл №'.$count.' из 70000, '.$dirname.'/'.$file.': <b>Завершено!</b><br/>' ;
}
}
}
}
closedir($dir);
}
cleancode('/home/leonder/downloads/pesenki.ru/authors/');
?>
В общем-то это работает, но я чую, что делаю очень неправильные действия. Например, наверное, надо этот php скрипт модифицировать так, чтобы он принимал на вход имя файла и обрабатывал только его (не умею)... или еще как-то. Ибо опция max_execution_time должна вроде как твикаться до получаса у php.ini...
В общем, дорогие товарищи, помогите советами пожалуйста!
Заранее большое спасибо за внимание тем, кто решится его уделить!