所以我一直在试验PHP Simple HTML Parser和用于PHP 5的内置PHP DOM解析器来搜索网站。
我们以此为例:http://www.ammunitiondepot.com/12-Gauge-Shotgun-Ammo-s/1922.htm
我正在尝试抓取v65-productDisplay表中的所有产品图片。我能够抓住页面上的所有图像,但是我很难尝试只抓取表格中的图像。
这是我用来抓取所有图片的代码:
$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');
}
答案 0 :(得分:1)
您获得所有<img>
src
- 属性的问题基本上是因为您运行
$images = $dom->getElementsByTagName('img');
这表示您希望从整个文档中获取所有<img>
个元素。但实际上,您只想获得特定表中的图像。至少你现在这么认为,但让我们暂时这样做。您要查找的表是文档顺序中的第13个表。那么你现在要解决的问题是你先得到<table>
,然后从中获取所有<img>
元素:
$tables = $dom->getElementsByTagName('table');
$table = $tables->item(12); # 13th table in the document
$images = $table->getElementsByTagName('img');
然后,这将为您提供您在问题中要求的图像(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
...
显然这会导致一些进一步的问题:
.jpg
个文件,而不是所有那些1像素的GIF或购物车按钮。class="v65-productDisplay"
属性(你甚至已经在你的问题中写了它)。我现在先说明如何解决前两个问题。
似乎getElementsByTagName
即使有用也不能灵活满足您的拼抢需求。还有一种更好的方法来查询文档中的元素,称为xpath(ref)。它是一种查询语言,您可以在其中表达所需的元素。所以我们希望特定表中的图像src属性是jpegs。 xpath查询看起来像这样:
//table[@class="v65-productDisplay"]/tr/td/a/img/@src[contains(., ".jpg")]
这是在DOMXPath的帮助下运行的,如下所示:
$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";
}
现在已经将列表大大减少到你正在寻找的内容,而不是那么冗长:
//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
...
所以现在只有问题留给了URI的清理,即文档URI的解析(因为文档中没有其他基URI)并且可能清理查询字符串。我是在Net_URL2的帮助下完成的,这里只有src处理:
/** @var DOMAttr $src */
foreach ($xpath->query($srcQuery) as $src) {
$href = $uri->resolve($src->nodeValue);
$href->setQuery(false);
echo $href, "\n";
}
这是一个完整的例子:
<?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";
}
以下是供将来参考的HTML:http://pastebin.com/HCTTRm9E