Как получить содержательную часть страницы?

Доброго дня хабрасообществу!


Через cURL прочитана страница, теперь нужно из неё вытащить содержательную часть, т.е. сам текст, без меню, комментариев, шапок, подвалов и прочего. Посоветуйте, как это можно сделать «малой кровью»? Подозреваю, что это должен быть какой-то шаблон в preg_match…
  • Вопрос задан
  • 11515 просмотров
Пригласить эксперта
Ответы на вопрос 15
EugeneOZ
@EugeneOZ
Не надо парсить HTML регулярками.
Читайте на StackOverflow: stackoverflow.com/a/1732454/680786
Ответ написан
Комментировать
metamorph
@metamorph
Люди на эту тему научные статьи пишут, а Вы хотите preg_match обойтись :)
Ответ написан
Комментировать
Urvin
@Urvin
function getContentFromHtml($aText)
{
	return preg_replace(
			array(
				'@<head[^>]*?>.*?</head>@siu',
				'@<style[^>]*?>.*?</style>@siu',
				'@<script[^>]*?.*?</script>@siu',
				'@<object[^>]*?.*?</object>@siu',
				'@<embed[^>]*?.*?</embed>@siu',
				'@<applet[^>]*?.*?</applet>@siu',
				'@<noframes[^>]*?.*?</noframes>@siu',
				'@<noscript[^>]*?.*?</noscript>@siu',
				'@<noembed[^>]*?.*?</noembed>@siu',

				'@</?((address)|(blockquote)|(center)|(del))@iu',
				'@</?((div)|(h[1-9])|(ins)|(isindex)|(p)|(pre))@iu',
				'@</?((dir)|(dl)|(dt)|(dd)|(li)|(menu)|(ol)|(ul))@iu',
				'@</?((table)|(th)|(td)|(caption))@iu',
				'@</?((form)|(button)|(fieldset)|(legend)|(input))@iu',
				'@</?((label)|(select)|(optgroup)|(option)|(textarea))@iu',
				'@</?((frameset)|(frame)|(iframe))@iu',
				'@<[^>]*>@siu',
				'@&[^;]+?;@siu',
				'@(\s+)@siu'
			),
			array(
				'',
				'',
				'',
				'',
				'',
				'',
				'',
				'',
				'',

				'$0',
				'$0',
				'$0',
				'$0',
				'$0',
				'$0',
				'$0',
				'',
				' ',
				' '
			),
			$aText
		);
}


Вот такое есть в моем загашнике. Не фонтан, конечно.
Ответ написан
Gesper
@Gesper
Попробуйте раскурить code.google.com/p/boilerpipe/
Ответ написан
librarian
@librarian
code.google.com/p/arc90labs-readability/ proof of concept от создателей ReadAbility.
Ответ написан
Комментировать
avalak
@avalak
Используйте Simple HTML DOM или другие библиотеки с аналогичным функционалом.
Ответ написан
m08pvv
@m08pvv
Если речь о статье на Хабре, то открыв код статьи сразу видно, что вся статья содержится в
<div id="post_123456" class="post shortcuts_item">

При этом post_123456 — номер поста, который есть в URL

Сам текст (без заголовка, списка хабов и т.д.) содержится в
<div class="content html_format">

Ну а если речь идёт про общий случай, то надо использовать парсер html, ибо регулярками не обойтись
Ответ написан
AterCattus
@AterCattus
Люблю быстрый backend
Многие сайты, выполненные на популярных движках, имеют шаблонную верстку. А это вам на руку. Всякие DLE, WordPress и подобные четко выделяют css-классами основной контент страницы. Можно идентифицировать на этой основе примененный движок и однократно написать запросы к SHD (Simple HTML DOM, выше упоминалось). Для нераспознанных сайтов стоит искать знаковые блоки (main, content, body и т.п.).
Ответ написан
Комментировать
uadeveloper
@uadeveloper
Можно и «почти» готовым вариантом воспользоваться
habrahabr.ru/post/114323/
Ответ написан
@Zawchik Автор вопроса
Спасибо всем за решения, однако всё равно остаётся много вопросов.
Например, сайты, которые будут основными при обкатке скрипта, мало того, что не содержат тега h1 в принципе, так ещё и свёрстаны на таблицах и ASP со всем вытекающим мусором.
А вот, скажем, плагин к хрому evernote сразу безошибочно выделил нужный столбец. Или вот как ВКонтакте сделали — скармливаешь им ссылку, они сразу «просмотр» и там содержательная часть статьи.
Вот нужно что-то аналогичное…
Ответ написан
Какой либо универсальный парсер думаю вы не найдете.
Можно конечно попробовать написать функционал для всех популярных CMS, но стоит ли оно того?

Для парсинга тоже рекомендую Simple HTML DOM. Он как раз отлично подходит для этой задачи.
Ответ написан
Комментировать
deadkrolik
@deadkrolik
У вас стоит задача написать универсальный парсер? Чтобы для любой страницы примерно мог выдать заголовок и тело?
Ответ написан
akhmelev
@akhmelev
программист
Очень актуально. Поделитесь, решение было найдено?
Ответ написан
Комментировать
Mendel
@Mendel
PHP-developer
Вот здесь я использовал для этих целей два алгоритма — добавить всё это уже описанныйе варианты отбора чистого текста. Отфильтровать тут было чуть умнее — все i, strong, h1 и т.п. заменял на b.
Все p, span, div и т.п. заменял на разделитель какой-то (не помню уже). Все незначащие теги типа head img и т.п. удалял.

В результате получалось множество блоков текста, в которых был чистый текст, выделенный текст и текст со ссылками.
дальше я вычислял для каждого блока количество текста в блоке, какой процент этого текста выделенный, и какой под ссылкой.
Блоки в которых текст был слишком коротким или в нем было слишком много выделений или ссылок я отбрасывал.

Если кому будет интересен мой говнокод шестилетней давности (а он 99% что дикий был), то могу дать в личку. Но лучше воспроизведите алгоритм сами. Будет адекватнее :)
Ответ написан
Комментировать
photo_profile
@photo_profile
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы