我一直在尝试通过使用DOMelements来解析一个网站。一切都很正常,除了这个问题对我来说没有意义。
有一个选择框,我需要所有可能的选项值的内容:
<select name="super_attribute[141]" id="attribute141" class="required-entry super-attribute-select">
<option value="">Choose size</option>
<option value="36" price="0">36</option>
<option value="38" price="0">38</option>
<option value="41" price="0">40</option>
<option value="43" price="0">42</option>
<option value="45" price="0">44</option>
<option value="47" price="0">46</option>
<option value="49" price="0">48</option>
</select>
我想检索一个包含值(innerHTML或"value"属性)的数组。我使用这个代码:
foreach ($dom->getElementsByTagName('option') as $option_tag) {
$sizes_list[] = $option_tag->getAttribute('value');
}
但是,始终只返回一个"option"标记,其值为空。所以我尝试了一种不同的方法:
$item_options = $dom->getElementById('attribute141');
print(sizeof($item_options->childNodes)); // Prints "1"
foreach ($item_options->childNodes as $child) {
$sizes_list[] = $child->getAttribute('value');
}
$cloth_item->setSizes($sizes_list);
再一次,它似乎发现了这个单一的空值。。。为什么我不能访问其余选项?
当您从URL解析HTML页面时,决不能引用浏览器页面检查器,因为检查器在DOM/js解析后显示源代码。您需要参考"查看页面源代码"浏览器命令,或者——更好——在php:中执行此操作
$html = file_get_contents( 'http://www.example.com/your/url.html' );
file_put_contents( '/Path/Local/Download/Page.html', $html );
然后,用文本编辑器打开下载的文件,查看您正在使用的真实HTML。
在您的特定情况下,您只能检索一个<option>
,因为。。。加载的页面中只有一个<option>
:
<div class="input-box">
<select name="super_attribute[141]" id="attribute141" class="required-entry super-attribute-select">
<option>בחר אפשרות...</option>
</select>
</div>
其他选项由JavaScript加载。它们的值以JSON格式存储在同一页面的脚本中。没有一种干净的方法来检索它。你可以使用PhantomJS,但正如你在这里或其他Stack Overflow问题上看到的那样,这种方法使用php并不容易。
一种肮脏的方法可能是:查看HTML源代码,你可以看到你的数据是这样的格式:
<script type="text/javascript">
var spConfig = new Product.Config({ (...) });
</script>
因此,您可以检索所有<script>
节点并搜索new Product.Config
值。
使用纯DOM:
$nodes = $dom->getElementsByTagName('script'); // Result: 70 nodes
使用DOMXPath:
$xpath = new DOMXPath( $dom );
$nodes = $xpath->query('//script[@type="text/javascript"]'); // Result: 58 nodes
然后,遍历所有节点,找到正则表达式模式并对其进行解码:
foreach( $nodes as $node )
{
if( preg_match( '~new Product'.Config'((.+?)');~', $node->nodeValue, $matches ) )
{
$data = json_decode( $matches[1] );
break;
}
}
此时,在$data
中,您已经解码了JSON:
stdClass Object
(
[attributes] => stdClass Object
(
[141] => stdClass Object
(
[id] => 141
[code] => size
[label] => מידה
[options] => Array
(
[0] => stdClass Object
(
[id] => 36
[label] => 36
[price] => 0
[oldPrice] => 0
[products] => Array
(
[0] => 93548
)
)
(...)
)
)
)
)
因此,要访问第一个<option>
id,您可以使用以下内容:
echo $data->attributes->{141}->options[0]->id; // Output: 36
# ↑ note curly brackets to access to a not-valid property key
等等:
echo $data->attributes->{141}->options[1]->id; // Output: 38
echo $data->attributes->{141}->options[1]->label; // Output: 38
echo $data->attributes->{141}->options[1]->price; // Output: 0