Я получил содержимое этой веб-страницы http://www.dw.com/ar/تقرير-استخباري-اميركي-القاعدة-تسيطر-على-غرب-العراق/a-2251369
и сохранил его в $webpage
,
ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ:
На этой веб-странице есть ряд <meta>
теги. Один из этих мета-тегов является виновником и вызывает некоторые проблемы. Этот метатег <meta property="og:description" content="" />
, Обратите внимание, что значение content
пустая строка
Я читаю содержание веб-страницы следующим образом:
<?php
$url = 'http://www.dw.com/ar/تقرير-استخباري-اميركي-القاعدة-تسيطر-على-غرب-العراق/a-2251369';
$webpage = file_get_contents($url);
$og_entry_title = "";
$og_entry_content = "";
$doc = new DOMDocument;
$doc->loadHTML($webpage);
$meta_tags = $doc->getElementsByTagName('meta');
foreach ($meta_tags as $meta_tag) {
if ($meta_tag->getAttribute('property') == 'og:title') {
$og_entry_title = $meta_tag->getAttribute('content');
}
if ($meta_tag->getAttribute('property') == 'og:description') {
$og_entry_content = $meta_tag->getAttribute('content');
}
}
// print the results
echo
'$og_entry_title: ' . $og_entry_title
.PHP_EOL.
'$og_entry_content: ' . $og_entry_content;
Когда я закончу, у меня есть следующие значения для $og_entry_title
а также $og_entry_content
:
$og_entry_title: TOP STORIES | DW.COM $og_entry_content: News and analysis of the top international and European topics Current affairs and background information on poltics, business, science, culture, globalization and the environment.
Обратите внимание на следующее в результате:
$og_entry_title
правильно и содержит заголовок страницы, поэтому здесь нет проблем
$og_entry_content
дает другое значение, чем я ожидал. Я ожидаю, что пустая строка будет сохранена в $og_entry_content
; Однако строка «Новости и аналитика ведущих международных и европейских тем. Актуальные вопросы и справочная информация о политике, бизнесе, науке, культуре, глобализации и окружающей среде». сохраняется Эта строка представляется запасным значением (или значением по умолчанию), которое возвращается всякий раз, когда метатег содержит пустую строку.
После дальнейшего расследования выяснилось, что go:description
получает значение метатега из http://www.dw.com
страница интернета. Похоже, это произошло потому, что моя веб-страница содержала пустую строку. Возвращаемое значение извлекается из корневой страницы сайта.
У меня есть следующие вопросы о $og_entry_content
:
Как мне убедиться, что пустая строка (не резервное значение) сохранена в $og_entry_content
?
Почему это значение возврата из корневой страницы все равно возвращается?
Благодарю.
Ваш веб-адрес содержит специальные символы, которые должны быть URL закодирован.
Прежде всего, предположение, что …
$og_entry_title
правильно и содержит заголовок страницы, поэтому здесь нет проблем
…неправильно.
Это название:
<meta property="og:title" content="تقرير استخباري اميركي: القاعدة تسيطر على غرب العراق | أخبار | DW.COM | 28.11.2006" />
не совпадает с этим названием:
<meta property="og:title" content="TOP STORIES | DW.COM" />
Во-вторых, большинство современных браузеров достаточно хороши, чтобы кодировать URL-адреса на лету, и при этом по-прежнему отображать специальные символы в адресной строке.
Вы можете увидеть заголовки ответа с веб-сервера для получения дополнительной информации.
<?php
$url = 'http://www.dw.com/ar/تقرير-استخباري-اميركي-القاعدة-تسيطر-على-غرب-العراق/a-2251369';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$url");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
$response = curl_exec($ch);
// Then, after your curl_exec call:
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
echo '
header
------
'.substr($response, 0, $header_size);
Результаты показывают, что он не распознает связь между URL и этой страницей:
header ------ HTTP/1.1 301 Moved Permanently Server: Apache-Coyote/1.1 Location: / Content-Length: 0 Accept-Ranges: bytes X-Varnish: 99639238 Date: Thu, 16 Jun 2016 15:42:51 GMT Connection: keep-alive
Код ответа HTTP 301
это уведомление (перманентно) перенаправить на другую страницу. Location: /
указывает, что вы должны просто пойти в домашняя страница. Это обычная неаккуратная практика — просто отправлять кого-то на домашнюю страницу, когда он не знает, что с вами делать.
Curl не будет следовать перенаправлениям по умолчанию, именно так мы можем проверить заголовок ответа 301. Но file_get_contents
будет следовать перенаправлениям, поэтому вы получаете контент, отличный от ожидаемого. (С возможными исключениями: есть сообщение об ошибке где некоторые замечают, что это не всегда следует за перенаправлениями.)
Обратите внимание, что домашняя страница делает иметь content
в его og:description
:
<?php
echo file_get_contents('http://www.dw.com/ar/تقرير-استخباري-اميركي-القاعدة-تسيطر-على-غرب-العراق/a-2251369');
Результаты в этом выводе:
…
<meta property="og:description" content="News and analysis of the top international and European topics Current affairs and background information on poltics, business, science, culture, globalization and the environment. " />
…
<meta property="og:title" content="TOP STORIES | DW.COM" />
…
Первое, что вам нужно сделать, это rawurlencode
веб-адрес:
$url = rawurlencode($url);
Тогда осознай, что rawurlencode
плохо назван, потому что действительный URL будет содержать протокол HTML http://
или же https://
и может также содержать косую черту для разделения частей. Это проблематично, потому что rawurlencode
преобразует двоеточия :
в %3A
и косая черта /
в %2F
что делает для недопустимого URL, как http%3A%2F%2Fwww.dw.com%2Far%2F...
, Это должно было быть названо rawurlencode_parts_of_URL
Но они не спросили меня 🙂 И процитировал Фила Карлтона в их защиту:
В информатике есть только две сложные вещи: аннулирование кэша и называть вещи.
Поэтому преобразуйте косую черту и двоеточие в их первоначальную форму:
$url = str_replace('%3A',':',str_replace('%2F','/',$url));
Наконец, последнее, что вам нужно сделать, это отправьте заголовок своим клиентам, чтобы сообщить им, какую кодировку шрифта ожидать.
header("content-type: text/html; charset=utf-8");
В противном случае ваши клиенты могут читать некоторые абракадабра это может выглядеть примерно так:
ªÙ Ø ± Ø Ø ± ± ± ± ± § ³ ³ ³ ³ ³ · · · · ·:::::::: · · · · · · · · Ø · · · · · · §Ù «Ø¹Ø ± اÙ
<?php
// let's see error output on screen while in development
// remove these lines for production, and use log files only
error_reporting(-1);
ini_set('display_errors', 'On');
$url = 'http://www.dw.com/ar/تقرير-استخباري-اميركي-القاعدة-تسيطر-على-غرب-العراق/a-2251369';
// URL encode special chars
$url = rawurlencode($url);
// fix colons and slashses for valid URL
$url = str_replace('%3A',':',str_replace('%2F','/',$url));
// make request
$webpage = file_get_contents($url);
$og_entry_title = "";
$og_entry_content = "";
$doc = new DOMDocument;
$doc->loadHTML($webpage);
$meta_tags = $doc->getElementsByTagName('meta');
foreach ($meta_tags as $meta_tag) {
if ($meta_tag->getAttribute('property') == 'og:title') {
$og_entry_title = $meta_tag->getAttribute('content');
}
if ($meta_tag->getAttribute('property') == 'og:description') {
$og_entry_content = $meta_tag->getAttribute('content');
}
}
// set the character set for the client
header("content-type: text/html; charset=utf-8");
// print the results
echo
'$og_entry_title: ' . $og_entry_title
.PHP_EOL.
'$og_entry_content: ' . $og_entry_content;
Результаты в этом выводе:
$og_entry_title: تقرير استخباري اميركي: القاعدة تسيطر على غرب العراق | أخبار | DW.COM | 28.11.2006 $og_entry_content:
Если вы смотрите на свой журналы ошибок, и ты действительно должен всегда просматривая журналы ошибок при разработке, вы заметите множество предупреждений:
Warning: DOMDocument::loadHTML(): htmlParseStartTag: misplaced <html> tag in Entity, line: 4 in ... Warning: DOMDocument::loadHTML(): htmlParseStartTag: misplaced <html> tag in Entity, line: 5 in ... Warning: DOMDocument::loadHTML(): htmlParseStartTag: misplaced <html> tag in Entity, line: 6 in ... Warning: DOMDocument::loadHTML(): htmlParseStartTag: misplaced <html> tag in Entity, line: 7 in ... Warning: DOMDocument::loadHTML(): ID topMetaInner already defined in Entity, line: 300 in ... Warning: DOMDocument::loadHTML(): ID langSelectTrigger already defined in Entity, line: 315 in ... Warning: DOMDocument::loadHTML(): htmlParseEntityRef: no name in Entity, line: 546 in ... Warning: DOMDocument::loadHTML(): htmlParseEntityRef: no name in Entity, line: 546 in ... Warning: DOMDocument::loadHTML(): htmlParseEntityRef: no name in Entity, line: 548 in ... Warning: DOMDocument::loadHTML(): htmlParseEntityRef: no name in Entity, line: 548 in ...
Это потому, что вы пытаетесь использовать класс DOMDocument с недействительный HTML и не правильно сформированные документы XML. Но это тема для другого вопроса.
Других решений пока нет …