LINUX.ORG.RU

[find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.


0

0

Здравствуйте уважаемые обитатели этого форума!

Передо мной встала задача и я испытываю некоторые затруднения в ее решении. Прошу помочь дельными советами, поделиться опытом, подсказать по теме. А я опишу, в чем суть задачи и что я пытался предпринять.

В связи с нерегулярным доступом в сеть, мне захотелось иметь у себя на ноутбуке локальную копию сайта-коллекции текстов песен с аккордами для гитары. Обычно за аккордами для нужной песни я хожу на 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...

В общем, дорогие товарищи, помогите советами пожалуйста!
Заранее большое спасибо за внимание тем, кто решится его уделить!

Re: [find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.

perl -i.bak -ne 'if (/<script/i)   { $f=1     };  \
                 if ($f==0)        { print $_ };  \
                 if (/<\/script/i) { $f=0     }'  besimsa-chords.shtml 
sdio ★★★★★ ()

[find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.

>По интернетам я ползаю посредством iceweasel, а локальные html-файлы у меня по дефолту открываются konqueror-ом.

что мешает настроить, чтобы локальные файлы открывались в мозилле? :)

nu11 ★★★★★ ()

[find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.

если тебе не нужна визуальная мишура, а нужен только текст со страниц, то делается все гораздо проще:

find <path> -iname "*html" -print0 | xargs -0 \
php -r "$html=file_get_contents($argv[1]); $phpdom = new DOMDocument(); @$phpdom->loadHTML($html); file_put_contents($argv[1],$phpdom->textContent);"

nu11 ★★★★★ ()

[find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.

поправка

find <path> -iname "*html" -print0 | xargs -0 \
php -r '$html=file_get_contents("$argv[1]"); $phpdom = new DOMDocument(); @$phpdom->loadHTML($html); file_put_contents("$argv[1]",$phpdom->textContent);' --

nu11 ★★★★★ ()

[find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.

проще все таки открывать страницы в мозилле :) Или настроить таки adblock в конке.

nu11 ★★★★★ ()

[find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.

drull@ubuntu:~$ cat fillle
aaaaaaaaaaaaaaaaaaaa
<script>11111111</script>
bbbbbbbbbbbbbbbb
<script>222222222222222</script>
ccccccccccccccccccccccc
drull@ubuntu:~$ sed "s/<script.*<\/script>//" fillle
aaaaaaaaaaaaaaaaaaaa

bbbbbbbbbbbbbbbb

ccccccccccccccccccccccc

drull ★☆☆☆ ()

[find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.

а насчет пхп скрипта - принимай имя через ГЕТ-запрос.

drull ★☆☆☆ ()

Re: [find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.

Обычно javascript занимает больше одной строки, иначе хватило бы банального grep -v ...

sdio ★★★★★ ()

[find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.

да, но как показала практика, этого вполне достаточно чтоб срезать хоть половину рекламы. только что проверил на страничке которую ТС дал для примера: убирается контекстная реклама бегуна(справа), баннер от imhonet (сверху) и большой баннер слева.

drull ★☆☆☆ ()

[find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.

а вообще сед не умеет делать нежадный разбор, так что лучше использовать тот же перл.

drull ★☆☆☆ ()

[find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.

>а насчет пхп скрипта - принимай имя через ГЕТ-запрос.

какой GET в консольном скрипте, о чем вы? :)

nu11 ★★★★★ ()

[find][sed][regexp][php]Прошу помочь обработать скриптом очень большое количество текстовых файлов.

ну поднять вебсервер слушающий на локалхосте?

drull ★☆☆☆ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.