tag name loadhtml php web-scraping

name - php dom loadhtml



Raspando dentro de una mesa usando PHP DOM (1)

El problema que obtienes de todos los <img> src -attributes es básicamente porque corres

$images = $dom->getElementsByTagName(''img'');

Eso dice que quieres obtener todos los elementos <img> de todo el documento. Pero en realidad solo quieres obtener esas imágenes que están dentro de una tabla específica. Al menos ahora mismo, piensa así, pero hagámoslo de forma directa por el momento. La tabla que está buscando es la decimotercera tabla en orden de documento. Entonces, lo que debes hacer ahora para solucionar tu problema es que primero obtienes la <table> y luego obtienes todos los elementos <img> de ella:

$tables = $dom->getElementsByTagName(''table''); $table = $tables->item(12); # 13th table in the document $images = $table->getElementsByTagName(''img'');

Esto ya le dará las imágenes que solicita en su pregunta (extracto de los atributos src):

//cdn3.volusion.com/sfvhn.cpdkd/v/vspfiles/photos/SPL12-00BK-1.jpg?1381182668 /v/vspfiles/templates/ammunition/images/clear1x1.gif /v/vspfiles/templates/ammunition/images/clear1x1.gif /v/vspfiles/templates/ammunition/images/clear1x1.gif /v/vspfiles/templates/ammunition/images/clear1x1.gif /v/vspfiles/templates/ammunition/images/buttons/btn_addtocart_small.gif /v/vspfiles/templates/ammunition/images/clear1x1.gif ...

Obviamente, esto lleva a algunos problemas adicionales:

  1. La lista de imágenes tiene toneladas de las que no le interesan. Desea los archivos .jpg y no todos los que tienen 1-pixel-gif o shopping-cart-buttons.
  2. El número de la tabla está codificado. Esto no es muy estable, sería mejor que class="v65-productDisplay" atributo class="v65-productDisplay" (ya lo escribe en su pregunta).
  3. Las URL de la imagen son relativas al documento, por lo que deben resolverse.

Primero mostraré cómo resolver los dos primeros problemas.

Parece que getElementsByTagName incluso si es útil, no es tan flexible para sus necesidades de raspado. Y hay una mejor manera de consultar elementos del documento, y eso se llama xpath ( ref ). Es un lenguaje de consulta en el que expresas qué elementos quieres. Por lo tanto, queremos que los atributos src de la imagen desde una tabla específica sean jpegs. La consulta xpath se ve así:

//table[@class="v65-productDisplay"]/tr/td/a/img/@src[contains(., ".jpg")]

Esto se ejecuta con la ayuda de un DOMXPath ilustrado de la siguiente manera:

$xpath = new DOMXPath($dom); $srcQuery = ''//table[@class="v65-productDisplay"]/tr/td/a/img/@src[contains(., ".jpg")]''; /** @var DOMAttr $src */ foreach ($xpath->query($srcQuery) as $src) { echo $src->nodeValue, "/n"; }

Esto ahora ya reduce la lista en gran medida a lo que estás buscando y es menos detallado:

//cdn3.volusion.com/sfvhn.cpdkd/v/vspfiles/photos/SPL12-00BK-1.jpg?1381182668 //cdn3.volusion.com/sfvhn.cpdkd/v/vspfiles/photos/GTL1275-1.jpg?1380206953 //cdn3.volusion.com/sfvhn.cpdkd/v/vspfiles/photos/SS12L8-1.jpg?1390326206 //cdn3.volusion.com/sfvhn.cpdkd/v/vspfiles/photos/LEF127RS-1.jpg?1368458526 //cdn3.volusion.com/sfvhn.cpdkd/v/vspfiles/photos/LE13300-1.jpg?1368458467 //cdn3.volusion.com/sfvhn.cpdkd/v/vspfiles/photos/ADLE13300AC-1.jpg?1393516003 ...

Así que ahora solo queda el problema con la limpieza de los URI, es decir, con la resolución del URI del documento (ya que no hay más URI base en el documento) y, probablemente, limpiando la cadena de consulta. Lo hago con la ayuda de Net_URL2 , aquí el procesamiento src solo:

/** @var DOMAttr $src */ foreach ($xpath->query($srcQuery) as $src) { $href = $uri->resolve($src->nodeValue); $href->setQuery(false); echo $href, "/n"; }

Y aquí hay un ejemplo completo:

<?php /* * @link http://stackoverflow.com/questions/24344420/scraping-within-a-table-using-php-dom * @auhtor hakre <http://hakre.wordpress.com> */ # uses Net_URL2 -- http://pear.php.net/package/Net_URL2/ -- https://packagist.org/packages/pear/net_url2 require __DIR__ . ''/vendor/autoload.php''; $uri = new Net_URL2(''http://www.ammunitiondepot.com/12-Gauge-Shotgun-Ammo-s/1922.htm''); $cache = ''12-Gauge-Shotgun-Ammo-s-1922.htm''; if (is_readable($cache)) { $html = file_get_contents($cache); } else { $options = [ ''http'' => [ ''user_agent'' => "Godzilla/42.4 (Gabba Gandalf Client 7.3; C128; Z80) Lord of the Table Weed Edition (KHTML, like Gold Dust Day Gecko) Chrome/97.0.43043.0 Safari/1337.42", ''max_redirects'' => 1, # do not follow redirects ] ]; $context = stream_context_create($options); $html = file_get_contents($uri, null, $context); file_put_contents($cache, $html); } $dom = new domDocument; $dom->preserveWhiteSpace = false; $save = libxml_use_internal_errors(true); $dom->loadHTML($html); libxml_use_internal_errors($save); $dom->documentURI = $uri; $xpath = new DOMXPath($dom); $srcQuery = ''//table[@class="v65-productDisplay"]/tr/td/a/img/@src[contains(., ".jpg")]''; /** @var DOMAttr $src */ foreach ($xpath->query($srcQuery) as $src) { $href = $uri->resolve($src->nodeValue); $href->setQuery(false); echo $href, "/n"; }

Y aquí está el HTML para referencia futura: http://pastebin.com/HCTTRm9E

Así que he estado experimentando con PHP Simple HTML Parser y el analizador PHP DOM incorporado para PHP 5 para raspar un sitio web.

Tomaremos esto como un ejemplo: http://www.ammunitiondepot.com/12-Gauge-Shotgun-Ammo-s/1922.htm

Intento capturar todas las imágenes del producto dentro de la tabla v65-productoDisplay. Puedo tomar todas las imágenes de la página, pero tengo dificultades para intentar capturar solo las imágenes de la tabla.

Este es el código que estoy usando para tomar todas las imágenes:

$html = file_get_contents(''http://www.ammunitiondepot.com/12-Gauge-Shotgun-Ammo-s/1922.htm''); $dom = new domDocument; $dom->loadHTML($html); $dom->preserveWhiteSpace = false; $images = $dom->getElementsByTagName(''img''); foreach ($images as $image) { echo $image->getAttribute(''src''); }