3

静的情報を含む古い (内部) Web サイトがあります。より良いものに置き換えるため、すべての情報を取得する必要があります。以前は正規表現を使用してこれを行っていましたが、最近、正規表現を使用して HTML から情報を解析すると、cthulhu がこのレルムに招待されるという記事をいくつか見つけました。

そこで、いくつかの新しいトリックを学び、最初からやり直して DOM 方式で行うことにしました。必要な HTML 部分は次のようになります。

<table id="articles">
    <tr>
    <th>
        <a href='articles/aa123.html'><img src="/iamges/aa123.jpg" alt="some article"></a>
        <br />short description
    </th>
    <td>
        <table class='details'>
        <tr><th><a href='articles/aa123.html'>Some Article</a></th></tr>
        <tr><th>Type:</th><td>article type</td></tr>
        <tr><th>Price:</th><td>€ 99</td></tr>
        <tr><th>Manufacturer:</th><td>Some Company</td></tr>
        <tr><th>Warehouse:</th><td>x</td></tr>
        </table>
    </td>
</tr>   
</table>

そしてこれまでのところ、私はこれを得ました:

$dom = new DOMDocument();
@$dom->loadHTMLFile ($file);
$xpath = new DOMXPath($dom);
$query = "/html/body/table[@id='articles']//th"; //catch all TH's 
$data = $xpath->evaluate($query);

そして、それは私が立ち往生するところです。返された TH のすべてのコンテンツが ChildNodes にあることはわかっていますが、値を取得するのに苦労しています。詳細ページへの URL と Price 列の値が必要です。

それらを抽出するにはどうすればよいですか?

現在、私は次のことを思いつきました:

$query = '//table[@class="details"]//td';
$data= $xpath->evaluate($query);
$c = $ths->length;

for ($i = 0; $i < $c; $i++) {   
    echo htmlentities($data->item($i)->nodeValue);      
}

ただし、これは TD のテキスト値のみを表示します。コンテンツがリンクの場合、リンク タイトルのみが表示されます。URLではありません。

更新 ファブの提案のおかげで、私は何とか進歩を予約することができました. 現在、私は次のものを手に入れました:

$tables = $xpath->query('//table[@class="details"]');
foreach($tables as $table) {
    $url = $xpath->evaluate('//th/a/@href', $table);
    $articleName= $xpath->evaluate('//th/a', $table);
    $Manufacturer= $xpath->evaluate('//th[text()="Manufacturer:"]/../td', $table);

    echo 'articleName:' . $articleName . ' <br />';
    echo 'Manufacturer:' . $Manufacturer. ' <br />';
    echo 'url:' . $url. ' <br />';
    echo '<br />';
}

しかし、何らかの理由で、常に最初のアクティクルのデータが表示されます (ページにある記事の数だけ繰り返されます)。あたかも「foreach」ステートメントが常に最初に見つかったテーブルを返すかのように。任意のヒント?

4

1 に答える 1

1

URL の XPath は次のようになります。

//table[@class="details"]//th/a@href

価格列の場合:

//table[@class="details"]//th[text()="Price:"]/../td

おそらく、各テーブルの URL と価格を個別に取得する必要があるでしょう。そのためには、最初DOMNodeListにすべての「詳細」テーブルを収集してから (コンテキスト パラメーターを使用して) 検索することができます。

$tables = $xpath->query('//table[@class="details"]');
foreach($tables as $table) {
    $url = $xpath->evaluate('//th/a@href', $table);
    $price = $xpath->evaluate('//th[text()="Price:"]/../td', $table);
    echo "$url - $price <br>";
}

アップデート

忘れていたことが 1 つあります。コンテキスト パラメータは相対パスでのみ有効であり、//th/...絶対パスです。最初にドットを追加する必要があります。.//th/...

ご覧ください:作業デモ

(また、最初の項目の値を交換evaluateし、明示的にアクセスする必要がありました。query

$xpath->query(...)->item(0)->nodeValue;
于 2013-02-28T14:11:21.307 に答える