PHP Scraping с использованием XPath - html5 проблема? - PullRequest
1 голос
/ 17 февраля 2012

Я пытаюсь очистить значение поля ввода от URL.Кажется, у меня проблемы с моей реализацией XPath.

Страница, которую нужно очистить, выглядит примерно так:

<!DOCTYPE html> 
<html lang="en">
    <head></head>
    <body>
        <div><span>Blah</span></div>
        <div><span>Blah</span> Blah</div>
        <div>
            <form method="POST" action="blah">
                <input name="SomeName" id="SomeId" value="GET ME"/>
                <input type="hidden" name="csrfToken" value="ajax:3575644127378754050" id="csrfToken-login">
            </form>
        </div>
    </body>
</html>

, и я пытаюсь разобрать ее следующим образом:

$Contents = file_get_contents("https://www.linkedin.com/uas/login");
$Selector = "//input[@id='csrfToken-login']/@value";
print_r($Selector);
$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHtml($Contents);
$xpath = new DOMXPath($dom);
libxml_use_internal_errors(false);
print_r($xpath->query($Selector));

Примечание: dump() просто переносит print_r(), но добавляет некоторую информацию о трассировке стека и форматирование.

Вывод выглядит следующим образом:

14:50:08 scraper.php 181: (Scraper->Test)
//input[@id='csrfToken-login']/@value

14:50:08 scraper.php 188: (Scraper->Test)
DOMNodeList Object
(
)

Какой ячто означает, что не удалось найти в документе ничего, что соответствует моему селектору?Я попробовал несколько вариантов, просто чтобы посмотреть, смогу ли я получить что-то назад:

/input/@value
/input
//input
/div

Единственный селектор, который мне удалось получить что-нибудь from это /, который возвращает весь документ.

Что я делаю не так?

EDIT: Поскольку некоторые не могут воспроизвести проблему со старымНапример, я заменил его почти идентичным примером, который также демонстрирует проблему, но использует общедоступный URL (страница входа в LinkedIn).

Было высказано предположение, что это невозможно из-за засорения парсераhtml5 - (как это внутренняя страница) кто-нибудь имеет опыт этого?

Ответы [ 3 ]

2 голосов
/ 17 февраля 2012

Если ваш селектор начинается с одной косой черты (/), это означает абсолютный путь от корня.Вам необходимо использовать двойную косую черту (//), которая выбирает все подходящие элементы независимо от их расположения.

print_r не будет работать для этого.В вашем коде все было хорошо, за исключением фактического получения значения.Классы списков в PHP обычно имеют свойство length, проверьте это вместо этого.

$Contents = file_get_contents("https://www.linkedin.com/uas/login");
$Selector = "//input[@id='csrfToken-login']/@value";
$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHtml($Contents);
$xpath = new DOMXPath($dom);
libxml_use_internal_errors(false);
$b = $xpath->query($Selector);
echo $b->item(0)->value;
1 голос
/ 17 февраля 2012

DOMXPath выглядит хорошо для меня.

Что касается xpath, используйте ярлык по убыванию или самостоятельно //, чтобы перейти к тегу ввода

//input[@id='SomeId']/@value
0 голосов
/ 18 февраля 2012

Я был на указанной вами странице входа в LinkedIn, и она повреждена; даже в вашем урезанном примере есть незамкнутый input узел. Я ничего не знаю о реализации PHP XPath, но я предполагаю, что ни один прямой XPath API никогда не будет работать с искаженным документом.

Кстати, ваш XPath правильный.

Возможно, вам понадобится промежуточный шаг, использующий TagSoup , чтобы "правильно сформировать" источник перед тем, как вы начнете его запрашивать, или Google "tag суп php" для любых специфических для PHP решений / реализаций.

Надеюсь, это поможет,
Zachary

...