устранение ошибки свойства xpath, хотя xpath выглядит хорошо - PullRequest
1 голос
/ 06 марта 2020

Я пытался извлечь информацию о версии с веб-страницы, но я получаю сообщение об ошибке, хотя XPath выглядит хорошо на странице HTML.

код, который я пытался использовать,

use DOMDocument;
use DOMXPath;
function getVersionFromDownloads(string $url): string
{
    // support only windows
    $content = $this->fetch($url);
    $curl = curl_init($url);

    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_FRESH_CONNECT, true);
    $content = curl_exec($curl);
    curl_close($curl);

    $dom = new DOMDocument();
    @$dom->loadHTML($content);

    $xpath = new DOMXPath($dom);

    $result = $xpath->query("//a[contains(text(),'paint.net')]");

    $header = $result->item(0)->textContent;
    echo $header;

}
getVersionFromDownloads('https://www.dotpdn.com/downloads/pdn.html');

Желаемый результат - 4.2.10

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

ошибка с учетом заявления: $header = $result->item(0)->textContent;

Ответы [ 2 ]

0 голосов
/ 07 марта 2020

Во время тестирования моих решений я получал много ошибок DOM, используя $dom->load(). Вы можете просмотреть всю недействительную разметку с помощью онлайн-валидатора html, например https://www.freeformatter.com/html-validator.html. Эта программа лаяла о многих незначительных упущениях, а затем о некоторых заметных элементах, таких как:

Неправильная последовательность байтов: «a9».

и

Неправильная последовательность байтов: «ae».

Когда я пытался написать свой собственный код php с помощью $dom->loadHTML() ...

$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->load('https://www.dotpdn.com/downloads/pdn.html');
$xpath = new DOMXPath($dom);
return libxml_get_last_error();

, я напечатал ответ значение на экране с var_export(), чтобы увидеть:

LibXMLError :: __ set_state (массив ('level' => 3, 'code' => 77, 'column' => 8, 'message' => 'Преждевременный конец данных в теге html строка 1', 'файл' => 'https://www.dotpdn.com/downloads/pdn.html', 'строка' => 153,))


РЕКОМЕНДУЕТСЯ

Поэтому вместо использования load() я решил попробовать file_get_contents($url), чтобы получить исходный код и передать его анализатору DOM.

function getVersionFromDownloads($url)
{
    $dom = new DOMDocument();
    $dom->loadHTML(file_get_contents($url));
    $xpath = new DOMXPath($dom);
    $text = $xpath->query("//a[contains(text(),'paint.net')]")->item(0)->textContent;
    return preg_replace('/paint\.net\s+/', '', $text);
}
var_export(getVersionFromDownloads('https://www.dotpdn.com/downloads/pdn.html'));

Вывод:

'4.2.10'
  • Чтобы удалить одинарные кавычки, используйте echo вместо var_export(). Я использовал его только для демонстрации отсутствия пробелов в начале или в конце.

  • preg_replace() используется перед возвратом, так что paint.net, за которым следуют несколько последовательных пробелов внутри строки, удаляются.

  • Для записи, этот метод извлечения будет работать так же:

     $xpath->query("//a[contains(text(),'paint.net')]/text()")->item(0)->nodeValue;
    
  • В вашем:

     function getVersionFromDownloads(string $url): string
    

    * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 1066 ”*” ”” ”” ”” ”требует, чтобы строковое значение было возвращено вашей функцией, но вы просто повторяете" »- обязательно верните строковое значение”. ”

0 голосов
/ 06 марта 2020
 $result = explode(" ",trim($xpath->query("//b/a")[0]->nodeValue))[1];

это то, что вы ищете?

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