PHP - DOMelement select不返回选项值

时间:2016-05-05 10:08:13

标签: php parsing dom

我一直试图通过使用DOMelements来解析网站。 一切都运转正常,除了这个对我没有意义的问题。

有一个选择框,我需要所有可能的选项值的内容:

foreach ($dom->getElementsByTagName('option') as $option_tag) {
    $sizes_list[] = $option_tag->getAttribute('value');
}

我想检索一个包含值的数组(innerHTML或' value'属性)。我使用这段代码:

$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);

然而,只有一个选项'返回标记,值为空。 所以我尝试了另一种方法:

{
        "name": "Launch Chrome",
        "type": "chrome",
        "request": "launch",
        "url": "http://localhost:7246/",
        "runtimeArgs": [
            "--new-window",
            "--remote-debugging-port=9222"
        ],
        "webRoot": "${workspaceRoot}/app/"
}

再次似乎找到了这个空值...为什么我不能访问其余的选项?

1 个答案:

答案 0 :(得分:0)

从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,但是 - 正如您可以看到hereother Stack Overflow questions - 这种方式使用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