Получение заголовка страницы в PHP: варианты реализации
Методы получения заголовка страницы в PHP
Задача получения тега
Основное решение с использованием DOMDocument
Класс DOMDocument позволяет загрузить HTML и извлечь заголовок надёжно, не полагаясь на регулярные выражения.
$url = 'https://example.com';
$html = @file_get_contents($url);
if ($html === false) {
die('Ошибка получения содержимого');
}
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML($html);
libxml_clear_errors();
$titleNode = $dom->getElementsByTagName('title')->item(0);
$title = $titleNode ? $titleNode->nodeValue : 'Заголовок не найден';
echo $title;Php get title (получение заголовка страницы в php)
Пояснение:
file_get_contentsполучает HTML-код.DOMDocument::loadHTMLпарсит строку.getElementsByTagName('title')возвращает коллекцию; берётся первый элемент.- Обработка ошибок парсинга через
libxml_use_internal_errors.
Возможные проблемы:
- Неверная кодировка (например, windows-1251). Решение: перед загрузкой преобразовать строку через
mb_convert_encoding. - Таймаут при получении контента. Решение: использовать cURL с таймаутом.
- Отсутствие тега
<title>– проверка наnull.
Как быстро извлечь заголовок без загрузки DOM?
Вариант с регулярным выражением. Подходит для простых случаев, когда структура HTML не содержит вложенных сложностей.
$html = file_get_contents('https://example.com');
preg_match('/([^<]*)<\/title>/i', $html, $matches);
$title = $matches[1] ?? 'Не найден';
echo $title; Регулярка ищет содержимое между
s (PCRE_DOTALL) и учитывать возможные пробелы.Ошибка: при многострочном заголовке или вложениях. Корректная регулярка: /. Используется нежадный квантификатор и s для точки.
Как получить заголовок с сайта, требующего обработку редиректов и заголовков?
cURL даёт контроль над запросом: можно установить таймаут, User-Agent, следовать редиректам.
$ch = curl_init('https://example.com');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_USERAGENT => 'Mozilla/5.0',
]);
$html = curl_exec($ch);
curl_close($ch);
$dom = new DOMDocument();
@$dom->loadHTML($html);
$title = $dom->getElementsByTagName('title')->item(0);
echo $title ? $title->nodeValue : 'Не найден';Цель: обеспечить надёжное получение контента даже при редиректах и блокировках.
Ошибки: сертификаты SSL, пустой ответ. Для игнорирования SSL можно добавить CURLOPT_SSL_VERIFYPEER => false (не рекомендуется на production).
Как упростить парсинг при помощи сторонней библиотеки?
Библиотека Simple HTML DOM Parser предоставляет простой синтаксис для поиска элементов.
include 'simple_html_dom.php';
$html = file_get_html('https://example.com');
$title = $html->find('title', 0)->plaintext;
echo $title;Плюс: интуитивно понятные методы. Минус: библиотека не обновляется, может быть медленной.
Как извлечь title из локального файла на сервере?
Если страница уже сохранена, достаточно указать путь к файлу.
$html = file_get_contents('/path/to/page.html');
$dom = new DOMDocument();
$dom->loadHTML($html);
$title = $dom->getElementsByTagName('title')->item(0)->nodeValue;Аналогично для строки.
Какие меры предосторожности при недоступности сайта?
Важно обрабатывать таймауты, ошибки соединения и пустые ответы. Пример с cURL и проверкой:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$html = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (!$html || $httpCode != 200) {
$title = 'Не удалось получить страницу';
} else {
$dom = new DOMDocument();
@$dom->loadHTML($html);
$title = $dom->getElementsByTagName('title')->item(0)->nodeValue ?? 'Нет title';
}Рекомендуется также устанавливать обработчик исключений.
Типичные ошибки и их решение
- Неверная кодировка: заголовок отображается кракозябрами. Решение – принудительно установить кодировку перед парсингом:
$html = mb_convert_encoding($html, 'HTML-ENTITIES', 'auto');или$dom->loadHTML('<?xml encoding="utf-8" ?>' . $html); - Многострочный заголовок: регулярка без флага
sне находит. Решение – использовать DOMDocument, который корректно обрабатывает переносы. - Отсутствие тега <title>: всегда проверять результат на null или искать альтернативы (meta og:title).
- SSL-ошибки: на этапе разработки можно отключить проверку сертификата, в production настроить CA-сертификаты.
- Ограничение памяти: при загрузке больших страниц увеличить memory_limit или использовать потоковую загрузку.
Расширенные примеры с пояснениями
Детальные сценарии для надёжного получения заголовка.
Пример 1: Корректная обработка кодировки с DOMDocument
$url = 'https://example.com';
$html = @file_get_contents($url);
if ($html === false) {
exit('Не удалось получить HTML');
}
$encoding = mb_detect_encoding($html, ['UTF-8', 'Windows-1251', 'KOI8-R'], true);
if ($encoding && $encoding != 'UTF-8') {
$html = mb_convert_encoding($html, 'UTF-8', $encoding);
}
$dom = new DOMDocument();
@$dom->loadHTML($html);
$title = $dom->getElementsByTagName('title')->item(0);
$titleText = $title ? $title->nodeValue : 'Заголовок не определён';
echo $titleText;Пример вывода: "Добро пожаловать на Example.com" (в правильной кодировке)
Пример 2: cURL с полным контролем и обработкой редиректов
$url = 'https://example.com';
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_TIMEOUT => 15,
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; MyBot/1.0)',
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_CAINFO => '/path/to/cacert.pem',
]);
$html = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($html === false || $info['http_code'] !== 200) {
$error = curl_error($ch);
echo "Ошибка: $error";
} else {
$dom = new DOMDocument();
@$dom->loadHTML($html);
$title = $dom->getElementsByTagName('title')->item(0);
echo $title ? $title->nodeValue : 'Не найден';
}Вывод: успешный заголовок или сообщение об ошибке.
Пример 3: Циклический обход нескольких страниц с логированием
$urls = ['https://site1.com', 'https://site2.com', 'https://site3.com'];
foreach ($urls as $url) {
$html = @file_get_contents($url, false, stream_context_create([
'http' => ['timeout' => 5, 'user_agent' => 'MyParser/1.0']
]));
if ($html === false) {
error_log("Не удалось загрузить $url");
continue;
}
$dom = new DOMDocument();
@$dom->loadHTML($html);
$titleNode = $dom->getElementsByTagName('title')->item(0);
$title = $titleNode ? trim($titleNode->nodeValue) : 'N/A';
echo "$url: $title\n";
}https://site1.com: Первый сайт https://site2.com: Второй сайт https://site3.com: N/A
Пример 4: Использование библиотеки Guzzle для асинхронного получения
use GuzzleHttp\Client;
$client = new Client(['timeout' => 10]);
$promises = [];
$urls = ['https://site1.com', 'https://site2.com'];
foreach ($urls as $url) {
$promises[$url] = $client->getAsync($url)->then(function ($response) {
$html = (string)$response->getBody();
$dom = new DOMDocument();
@$dom->loadHTML($html);
$title = $dom->getElementsByTagName('title')->item(0);
return $title ? $title->nodeValue : 'нет';
});
}
$results = GuzzleHttp\Promise\settle($promises)->wait();
foreach ($results as $url => $result) {
echo "$url: " . ($result['value'] ?? 'ошибка') . "\n";
}(пример вывода при успешном выполнении)
Пример 5: Обработка заголовка с пробелами и специальными символами через DOMXPath
$html = ' Привет, мир! "Тест" ';
$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$titles = $xpath->query('//title/text()');
$title = '';
if ($titles->length > 0) {
$title = trim($titles->item(0)->nodeValue);
}
echo htmlspecialchars($title);Привет, мир! "Тест"
Примечание:
- Использование XPath даёт гибкость для сложных условий.
- Всегда экранируется вывод через
htmlspecialcharsдля безопасности.