![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Удаление тегов из ХТМЛ-страницы
Pcrepair © (2012-01-18 20:47:00)Добрый день
есть код:
var
Form1: TForm1;
HTML : ustring;
//////////////////////////////////
procedure TForm1.Button1Click(Sender: TObject);
var
URL : string;
begin
URL := Edit1.Text;
Chromium1.Browser.MainFrame.LoadUrl(URL);
end;
procedure TForm1.Chromium1LoadEnd(Sender: TObject; const browser: ICefBrowser;
const frame: ICefFrame; httpStatusCode: Integer; out Result: Boolean);
begin
if (httpStatusCode <> 200) then Exit;
Memo1.Clear;
Chromium1.Browser.MainFrame.VisitDomProc(
procedure(const Dom: ICefDomDocument)
begin
HTML := Dom.Document.AsMarkup;
end );
Memo1.Clear;
Memo1.Lines.Add(HTML);
end;
end.
Код закачивает страницу с заданным УРЛ, производит обработку скриптов и размещает код страницы в ПЕРЕМ типа ustring
Все работает.
Далее необходимо переработать код в ПЕРЕМ ХТМЛ. В частности нужно удалить все теги типа <script..мусор...>..мусор...</script>, <style type=..мусор>...мусор...</style> и прочие такие же, типа ( ), не содержащие информации. в общем нужно радикально зачистить страницу, оставив только теги ссылок <a href= " ">...........</a> и теги таблиц <TR></TR>, чтоб ни рекламы. ни флеша, ни картинок
ВОПРОС:
каким способом это лучше сделать? может есть каки то проверенные способы уже
может есть какие то модули типа TParser? или типа того
Всем ответившим по делу - спасибо
megavoid (2012-01-22 10:29:00) [1][0] Можно так, убираем все тэги, при этом то, что за неправильной кавычкой отбрасываем, предварительно помечаем a href, потом возвращаем его на место
function RemoveTags(const s: string): string;
var
i: Integer;
InTag: Boolean;
begin
Result := '';
InTag := False;
for i := 1 to Length(s) do begin
if s[i] = '<' then inTag := True
else if s[i] = '>' then inTag := False
else if not InTag then Result := Result + s[i];
end;
end;
S := 'код хтмл';
S := AnsiReplaceStr(S, '<a href=', '$$$$$');
S := AnsiReplaceStr(S, '</a>', '#####');
S := ReplaceTags;
S := AnsiReplaceStr(S, '$$$$$', '<a href=');
S := AnsiReplaceStr(S, '#####', '</a>');
Eraser (2012-01-22 03:13:00) [2]я вообще к чему веду. для задачи автора в интернетах наверняка можно нарыть ряд типовых и качественных решений написанных для preg_replace и работающих с удовлетворительным качеством. все можно найти адаптировать за пару-тройку часов и заниматься проектом дальше. для того, чтобы написать такое вручную, может потребоваться куда больше времени и в самый не подходящий момент могут (даже наверняка) начнут лезть баги.
Eraser (2012-01-22 03:08:00) [3]> [22] DVM © (21.01.12 21:36)
насчет ковычек - одна из самых распространенных проблем, главное разработать правило, как работать со сбойными ковычками. соглашусь, что 100% вариантов предусмотреть не получится, но получится куда лучше и на порядки проще, чем писать конечный автомат вручную.
я разрабатывал типограф для одной известной cms в свое время, да, есть ряд сложностей, но все решаемо. при нынешних мощностях процессоров просчет даже сложнейших рег. выражений точно не узкое место.
DVM (2012-01-21 22:25:00) [4]По сути регулярное выражение это ни что иное как общее описание работы конечного автомата аналогичного приведенному мной. При компиляции регулярного выражения движком как раз примерно такой код и будет построен.
Но платой за универсальность является меньшая их наглядность начиная с некоторого момента. Мне попадались регулярные выражения аж на 100 строк(!) Таким выражением например будет выражение выделяющее 99.9% всех валидных emal адресов в тексте (кто думает что в таком выражение от силы символов 50, тот сильно ошибается). Понять как работает такое выражение непросто даже писавшему его через некоторое время. Тем более модифицировать.
Другим моментом является скорость. Конечно все сильно зависит от конкретной реализации движка для работы с регулярными выражениями, но быстрее чем один проход по строке они точно быть не могут. Иногда это критично.
DVM (2012-01-21 21:36:00) [5]
> Eraser © (21.01.12 19:37) [21]
Облажаются регулярные выражения, споткнувшись о первую незакрытую кавычку на реальных страницах, готов спорить. Точнее сами по себе регулярные выражения не виноваты, но человек составляющий это выражение непременно что-то не учтет ибо нереально (хотя теоретически наверное возможно).
Eraser (2012-01-21 19:37:00) [6]> [13] DVM © (19.01.12 22:54)
вся прелесть рег. выражений в том, что они настраиваются на определенные условия. для задачи определения url в любых тегах, задача сводится к следующему:
1. определяем, что текст находится внутри тэга.
2. по какием то определенным признакам определыем, что подстрока является url.
т.е. для наглядности можно даже не писать одно сложное выражение (хотя это возможно), а можно просто два раза вызвать функцию. первый раз выделяем все тэги (элементарная задача). второй раз выделяем url.
Eraser (2012-01-21 19:29:00) [7]> [13] DVM © (19.01.12 22:54)
задача весьма тривиальна для preg_replace. года 4 назад я бы не задумываясь написал да выложил пример, но сейчас увы, у рег. выражений есть такое неприятное свойство, если не пользуешься ими - напрочь забываются )
автору рекомундую глянуть
http://php.net/manual/en/function.preg-replace.phpи погуглить по запросу "preg_replace remove html tags"
KilkennyCat (2012-01-21 01:35:00) [8]Как народ любит регулярные выражения... я иногда их такие монструозные встречаю, что мне хочется или самому повеситься, или любителя того повесить.
> 3. сложности написания кода (regexp надо устанавливать в
> РАД, а pos это ведь "Работы со строками"?)
не нужен тут пос. долго будет, а простоты реализации не даст. DVM [4] - идеальное решение для данной задачи. и готовое почти.
нонамэ (2012-01-21 00:21:00) [9]
> роде проблем быть не должно?
нет не должно, делай
Pcrepair (2012-01-20 16:09:00) [10]глючит сервис
(б)
то что между тегами не удаляется, это нужно, удаляются сами теги, как не несущие информации(/б) - вот так правильно, имелся ввиду тег Б
Pcrepair (2012-01-20 16:07:00) [11]DVM, интересная информация, буду думать
с другой стороны речь идет об удалении ненужного.
например:
если написать циклический код, просматривающий все символы в ПЕРЕМ (код хтмл-страницы) и удаляющий конструкции типа то что между тегами не удаляется, это нужно, удаляются сами теги, как не несущие информацииили <script..мусор...> вот тут все удаляется, ЖАБА код уже не нужен</script>
вроде проблем быть не должно? при обработке самых разных страниц. какой вариант предпочтительнее (pos или regexp) по критериям:
1. возможной глючности
2. скорости обработки (средняя страница 200 кб, ну 10 000 символов?)
3. сложности написания кода (regexp надо устанавливать в РАД, а pos это ведь "Работы со строками"?)
DVM (2012-01-19 23:06:00) [12]А для поисковика есть еще одна непростая задачка - комбинация базового и относительного урлов на странице для перехода паука. Это очень непростая задача. На сайте консорциума WWW есть специальные тесты для функций выполняющих комбинацию, практически ни один браузер не проходит их все.
Вот большинство из них:
TestCombineUrl(' http://a/b/c/d;p?q', 'g', ' http://a/b/c/g');
TestCombineUrl(' http://a/b/c/d;p?q', './g', ' http://a/b/c/g');
TestCombineUrl(' http://a/b/c/d;p?q', 'g/', ' http://a/b/c/g/');
TestCombineUrl(' http://a/b/c/d;p?q', '/g', ' http://a/g');
TestCombineUrl(' http://a/b/c/d;p?q', '//g', ' http://g');
TestCombineUrl(' http://a/b/c/d;p?q', '?y', ' http://a/b/c/d;p?y');
TestCombineUrl(' http://a/b/c/d;p?q', 'g?y', ' http://a/b/c/g?y');
TestCombineUrl(' http://a/b/c/d;p?q', '#s', ' http://a/b/c/d;p?q#s');
TestCombineUrl(' http://a/b/c/d;p?q', 'g#s', ' http://a/b/c/g#s');
TestCombineUrl(' http://a/b/c/d;p?q', 'g?y#s', ' http://a/b/c/g?y#s');
TestCombineUrl(' http://a/b/c/d;p?q', ';x', ' http://a/b/c/;x');
TestCombineUrl(' http://a/b/c/d;p?q', 'g;x', ' http://a/b/c/g;x');
TestCombineUrl(' http://a/b/c/d;p?q', 'g;x?y#s', ' http://a/b/c/g;x?y#s');
TestCombineUrl(' http://a/b/c/d;p?q', '.', ' http://a/b/c/');
TestCombineUrl(' http://a/b/c/d;p?q', './', ' http://a/b/c/');
TestCombineUrl(' http://a/b/c/d;p?q', '..', ' http://a/b/');
TestCombineUrl(' http://a/b/c/d;p?q', '../', ' http://a/b/');
TestCombineUrl(' http://a/b/c/d;p?q', '../g', ' http://a/b/g');
TestCombineUrl(' http://a/b/c/d;p?q', '../..', ' http://a/');
TestCombineUrl(' http://a/b/c/d;p?q', '../../', ' http://a/');
TestCombineUrl(' http://a/b/c/d;p?q', '../../g', ' http://a/g');
TestCombineUrl(' http://a/b/c/d;p?q', '../../../g', ' http://a/g');
TestCombineUrl(' http://a/b/c/d;p?q', '../../../../g', ' http://a/g');
TestCombineUrl(' http://a/b/c/d;p?q', '/./g', ' http://a/g');
TestCombineUrl(' http://a/b/c/d;p?q', '/../g', ' http://a/g');
TestCombineUrl(' http://a/b/c/d;p?q', 'g.', ' http://a/b/c/g.');
TestCombineUrl(' http://a/b/c/d;p?q', '.g', ' http://a/b/c/.g');
TestCombineUrl(' http://a/b/c/d;p?q', 'g..', ' http://a/b/c/g..');
TestCombineUrl(' http://a/b/c/d;p?q', '..g', ' http://a/b/c/..g');
TestCombineUrl(' http://a/b/c/d;p?q', './../g', ' http://a/b/g');
TestCombineUrl(' http://a/b/c/d;p?q', './g/.', ' http://a/b/c/g/');
TestCombineUrl(' http://a/b/c/d;p?q', 'g/./h', ' http://a/b/c/g/h');
TestCombineUrl(' http://a/b/c/d;p?q', 'g/../h', ' http://a/b/c/h');
TestCombineUrl(' http://a/b/c/d;p?q', 'g;x=1/./y', ' http://a/b/c/g;x=1/y');
TestCombineUrl(' http://a/b/c/d;p?q', 'g;x=1/../y', ' http://a/b/c/y');
TestCombineUrl(' http://a/b/c/d;p?q', 'g?y/./x', ' http://a/b/c/g?y/./x');
TestCombineUrl(' http://a/b/c/d;p?q', 'g?y/../x', ' http://a/b/c/g?y/../x');
TestCombineUrl(' http://a/b/c/d;p?q', 'g#s/./x', ' http://a/b/c/g#s/./x');
TestCombineUrl(' http://a/b/c/d;p?q', 'g#s/../x', ' http://a/b/c/g#s/../x');
TestCombineUrl(' http://a/b/c/d;p?q', './g:h', ' http://a/b/c/g:h');
TestCombineUrl(' http://a/b/c/d;p?q', ' http://a/b/c/g', ' http://a/b/c/g');
TestCombineUrl(' http://a', '/b/c/g', ' http://a/b/c/g');
TestCombineUrl('a', '../b/c/g', ' http://a/b/c/g');
TestCombineUrl('a', './b/c/g', ' http://a/b/c/g');
TestCombineUrl('a', 'b/c/g', ' http://a/b/c/g');
TestCombineUrl('', 'a/b/c/g', 'a/b/c/g') ;
TestCombineUrl(' http://a/', '', ' http://a/');
TestCombineUrl(' http://a', '', ' http://a/');
TestCombineUrl('', '', '');
DVM (2012-01-19 23:02:00) [13]А на реальных страницах есть еще такая штука как не совсем корректный html, который тем не менее глотается браузерами.И это далеко не редкость. Почти любой крупный интернет ресурс изобилует ошибками в html. Если парсить по каким то заранее заданным правилам, то парсер может сработать неправильно. Ориентироваться надо по конкретной ситуации на странице иногда на ходу исправляя неверный код.
DVM (2012-01-19 22:54:00) [14]Имхо не тривиальная задача это и не для регулярных выражений. Только для выборки URL придется написать нехилое выражение. Например, надо не тупо выделять то, что начинается с http, а находить урлы, записанные самым экзотическим способом. Есть прорва тегов, которые могут содержать URL. Не надо реагировать на URL встречающиеся в тексте как текст и на те что внутри некоторых особых тегов.
Например, теги в которых может быть URL:
function TagHasUrl(const ATagName, ATagParam: string): Boolean;
var
Tag, Param: string;
begin
Tag := LowerCase(ATagName);
Param := LowerCase(ATagParam);
Result := ((Tag = 'a') and (Param = 'href')) or
((Tag = 'applet') and (Param = 'codebase')) or
((Tag = 'applet') and (Param = 'code')) or
((Tag = 'applet') and (Param = 'archive')) or
((Tag = 'area') and (Param = 'href')) or
((Tag = 'bgsound') and (Param = 'src')) or
((Tag = 'blockquote') and (Param = 'cite')) or
((Tag = 'body') and (Param = 'background')) or
((Tag = 'del') and (Param = 'cite')) or
((Tag = 'embed') and (Param = 'src')) or
((Tag = 'frame') and (Param = 'longdesc')) or
((Tag = 'frame') and (Param = 'src')) or
((Tag = 'head') and (Param = 'profile')) or
((Tag = 'iframe') and (Param = 'longdesc')) or
((Tag = 'iframe') and (Param = 'src')) or
((Tag = 'ilayer') and (Param = 'background')) or
((Tag = 'ilayer') and (Param = 'src')) or
((Tag = 'img') and (Param = 'longdesc')) or
((Tag = 'img') and (Param = 'src')) or
((Tag = 'img') and (Param = 'usemap')) or
((Tag = 'img') and (Param = 'dynsrc')) or
((Tag = 'img') and (Param = 'lowsrc')) or
((Tag = 'input') and (Param = 'src')) or
((Tag = 'input') and (Param = 'usemap')) or
((Tag = 'input') and (Param = 'dynsrc')) or
((Tag = 'input') and (Param = 'lowsrc')) or
((Tag = 'ins') and (Param = 'cite')) or
((Tag = 'layer') and (Param = 'background')) or
((Tag = 'layer') and (Param = 'src')) or
((Tag = 'link') and (Param = 'href')) or
((Tag = 'link') and (Param = 'href')) or
((Tag = 'object') and (Param = 'codebase')) or
((Tag = 'object') and (Param = 'classid')) or
((Tag = 'object') and (Param = 'data')) or
((Tag = 'object') and (Param = 'archive')) or
((Tag = 'object') and (Param = 'usemap')) or
((Tag = 'q') and (Param = 'cite')) or
((Tag = 'script') and (Param = 'src')) or
((Tag = 'table') and (Param = 'background')) or
((Tag = 'td') and (Param = 'background')) or
((Tag = 'th') and (Param = 'background')) or
((Tag = 'xml') and (Param = 'src')) or
((Tag = 'base') and (Param = 'href'));
end;
Это к моей задаче.
Задача автора вопроса не менее сложная, а то и более.
Мне кажется лучше всего будет произвести построение DOM модели чем то вот таким http://htmlp.sourceforge.net/, фильтрация не нужных параметров и тегов и обратная сборка документа. Там есть пример подобного. Но с конечным автоматом быстрее конечно, но более трудоемко.
Dimka Maslov (2012-01-19 22:48:00) [15]
> Eraser © (19.01.12 22:25) [10]
Мы уже узнали, что нет переменных есть только ПЕРЕМ, что читать MSDN и RFC бесполезно, что буфер обмена работает только на виртуальной машине, что нельзя использовать pos и regexp (как будто есть что-то другое). Но зато это будет поисковая программа! Круче чем гугл! Супер-пупер-мега-крутая. Вот только флудеры и теоретики мешают гению бездумно тырить код в этих ваших интернетах, а кроме того нагло отказываются писать за автора код... Тем более, что и в хромиуме наверняка есть свойства innerText и аnchors (или их аналоги), которые решают поставленную задачу мгновенно.
Dimka Maslov (2012-01-19 22:38:00) [16]есть теория, что использование таких вот программистов может привести к непредсказуемым результатам
Eraser (2012-01-19 22:25:00) [17]> [9] Pcrepair © (19.01.12 21:32)
кто автор теории? )
Pcrepair (2012-01-19 21:32:00) [18]есть теория что использование pos/regexp может привести к непредсказуемым результатам, при обработке самых разных страниц (это будет поисковая программа)
Eraser (2012-01-19 16:27:00) [19]> [0] Pcrepair © (18.01.12 20:47)
это тривиальная задача для любого php программера, решаемая с помощью регулярных выражений. Прикрути regexp.
Dimka Maslov (2012-01-19 15:15:00) [20]
> ПЕРЕМ
п е р е м е н н а я
Запиши на большими буквами на бумаге и повесь на стену.