Estoy usando "@nesk/puphpeteer": "^2.0.0" Enlace a Github-Repo y quiero obtener el texto y el atributo href de un enlace.
Intenté lo siguiente:
<?php require_once '../vendor/autoload.php'; use Nesk\Puphpeteer\Puppeteer; use Nesk\Rialto\Data\JsFunction; $debug = true; $puppeteer = new Puppeteer([ 'read_timeout' => 100, 'debug' => $debug, ]); $browser = $puppeteer->launch([ 'headless' => !$debug, 'ignoreHTTPSErrors' => true, ]); $page = $browser->newPage(); $page->goto('http://example.python-scraping.com/'); //get text and link $links = $page->querySelectorXPath('//*[@id="results"]/table/tbody/tr/td/div/a', JsFunction::createWithParameters(['node']) ->body('return node.textContent;')); // iterate over links and print each link and its text // get single text $singleText = $page->querySelectorXPath('//*[@id="pagination"]/a', JsFunction::createWithParameters(['node']) ->body('return node.textContent;')); $browser->close();Cuando ejecuto el script anterior, obtengo los nodos de la página, ¿PERO no puedo acceder a los atributos o al texto?
¿Alguna sugerencia de cómo hacer esto?
¡Agradezco sus respuestas!
querySelectorXPath devuelve la matriz de ElementHandle . una cosa más querySelectorXPath no admite la función de devolución de llamada.
primero obtenga todos los nodos ElementHandle
$links = $page->querySelectorXPath('//*[@id="results"]/table/tbody/tr/td/div/a');luego recorra los enlaces para acceder a los atributos o al texto del nodo
foreach($links as $link){ // for text $text = $link->evaluate(JsFunction::createWithParameters(['node']) ->body('return node.innerText;')); // for link $link = $link->evaluate(JsFunction::createWithParameters(['node']) ->body('return node.href;')); }Descargo de responsabilidad: esta es solo una respuesta intermedia: actualizaría una vez que tenga solicitudes más específicas sobre atributos HTML u otras expectativas para recuperar.
tl; dr : el paquete de compositor mencionado nesk/puphpeteer realmente es solo un envoltorio para la implementación subyacente basada en NodeJS de puppeteer . Por lo tanto, el acceso a datos y estructuras tiene que ser "similar" a sus contrapartes de JavaScript...
Tal vez Codeception (sin cabeza) o symfony/dom-crawler (marcado sin procesar) podrían ser alternativas mejores y más maduras.
De todos modos, elijamos el ejemplo de arriba y analicémoslo paso a paso:
$links = $page->querySelectorXPath( '//*[@id="results"]/table/tbody/tr/td/div/a', JsFunction::createWithParameters(['node'])->body('return node.textContent;') );$x() daría como resultado una matriz de elementos ElementHandlenode.textContent exportado (desde JsFunction ), los datos correspondientes se obtienen a través ElementHandle.getProperty(prop)ElementHandle.jsonValue()Así, después de eso tendríamos algo como esto:
$links = $page->querySelectorXPath( '//*[@id="results"]/table/tbody/tr/td/div/a', JsFunction::createWithParameters(['node'])->body('return node.textContent;') ); /** @var \Nesk\Puphpeteer\Resources\ElementHandle $link */ foreach ($links as $link) { var_dump($link->getProperty('textContent')->jsonValue()); }Que genera los siguientes datos sin procesar (recuperados de http://example.python-scraping.com/ ):
string(12) " Afghanistan" string(14) " Aland Islands" string(8) " Albania" string(8) " Algeria" string(15) " American Samoa" string(8) " Andorra" string(7) " Angola" string(9) " Anguilla" string(11) " Antarctica" string(20) " Antigua and Barbuda"