0

次の形式のドキュメントを考えてみましょう。

<!DOCTYPE html>
<html>
<head>
<title></title>
<body>
   <div class="blog_post_item first">
       <?php // some child elements ?>
   </div><!-- end blog_post_item -->
</body>
</html>

PHP cURL を使用して、このようなドキュメントをあるドメインから別のドメインにロードしています。div.blog_post_item.firstとその子のみを含めるように cURL の結果をトリミングしたいと思います。他のページの構造は知っていますが、編集できません。preg_match開始タグと終了タグを見つけるために使用できると思います。最後のコメントを含め、常に同じように表示されます。

私は、cURL/XPath/XSLT などを使用したスクリーン スクレイピングの例/チュートリアルを検索しました。そのほとんどは、HTML 解析ライブラリの名前の周期的なガタガタ音です。そのため、簡単な作業例を提供してください。正規表現を使用した HTML の解析が潜在的なセキュリティの脆弱性であると簡単に説明しないでください。さらに読む必要があるライブラリ仕様単にリストないでください

簡単な PHP cURL コードがいくつかあります。

$ch = curl_init("http://a.web.page.com");
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch);
curl_close($ch);

もちろん、$outputソース全体が含まれています。その要素の内容だけを取得するにはどうすればよいですか?

4

3 に答える 3

3

開始と終了が常に同じであると確信している場合、これは非常に簡単です。あなたがしなければならないのは、最初と最後を検索し、その間のすべてを一致させることです. 正規表現を使用して HTML を少し検索したことに対して、多くの人が腹を立てると思いますが、それで十分です。

// cURL
$ch = curl_init("http://a.web.page.com");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);

if(empty($output)) exit('Couldn\'t download the page');

// finding your data
$pattern = '/<div class="blog_post_item first">(.*?)<\/div><!-- end blog_post_item -->/';

preg_match_all($pattern, $output, $matches);
var_dump($matches); // all matches

あなたがクロールしようとしているウェブサイトがわからないため、これが機能するかどうかわかりません。


かなり長い間 (正確には 26 分) 検索した後、なぜ機能しなかったのかがわかりました。ドット ( .) は改行と一致しません。HTMLは改行だらけで内容が一致しませんでした。少し汚れたハックを使用して、とにかく一致させることができました(すでに答えを選んでいましたが)。

// cURL
$ch = curl_init('http://blogg.oscarclothilde.com/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
curl_close($ch);

if(empty($output)) exit('Couldn\'t download the page');

// finding your data
$pattern = '/<div class="blog_post_item first">(([^.]|.)*?)<\/div><!-- end blog_post_item -->/';

preg_match_all($pattern, $output, $matches);
var_dump($matches[1][0]); // all matches
于 2012-08-03T09:47:35.427 に答える
2

このコードは動作するはずです (>= 5.3.6 および dom 拡張):

$s = <<<EOM
<!DOCTYPE html>
<html>
<head>
<title></title>
<body>
   <div class="blog_post_item first">
       <?php // some child elements ?>
   </div><!-- end blog_post_item -->
</body>
</html>
EOM;

$d = new DOMDocument;
$d->loadHTML($s);

$x = new DOMXPath($d);

foreach ($x->query('//div[contains(@class, "blog_post_item") and contains(@class, "first")]') as $el) {
        echo $d->saveHTML($el);
}
于 2012-08-03T09:56:13.983 に答える
2

次の構造について確信がある場合:

<div class="blog_post_item first">
   WHATEVER
</div><!-- end blog_post_item -->

そして、終了コードが何にも表示されないことを確信している場合は、単にそれを取得できます。

(元の PHP を WHATEVER に置き換えたことに注意してください。CURL は HTML のみをフェッチし、PHP ではなくコンテンツを含みます。)

正規表現は必要ありません。以下の例のように、必要な文字列を検索するだけでそれを行うこともできます。

$curlResponse = '
<!DOCTYPE html>
<html>
<head>
<title></title>
<body>
   <div class="blog_post_item first">
       <?php // some child elements ?>
   </div><!-- end blog_post_item -->
</body>
</html>';

$startStr = '<div class="blog_post_item first">';
$endStr = '</div><!-- end blog_post_item -->';

$startStrPos = strpos($curlResponse, $startStr)+strlen($startStr);
$endStrPos = strpos($curlResponse, $endStr);

$wanted = substr($curlResponse, $startStrPos, $endStrPos-$startStrPos );

echo htmlentities($wanted);
于 2012-08-03T10:07:13.723 に答える