ネタまとめ

かつて、はてなダイアリーというサービスがあった

simple_html_dom を試してみよう

人力検索で、id:a-kuma3 さんが*1書きました。

お二方が書いたセレクタを検証してないで書いてます m(_ _)m

そうそう、このパターンの事は頭の片隅に入っていたのです。(ただし、BAの二重取得については仕様という考え)
URIが出てきたので、試します。

まずは、何がどうなっているのかを確認。

<?php
include_once('simple_html_dom.php');
$html = file_get_html('http://q.hatena.ne.jp/1380187850');
$src = array();
//質問文
//>find('[.answer-body p],[.answer-comment-detail p]');
//コメントNo.1
//>find('[.answer-formatted-body p],[.answer-comment-detail p]');
//コメントNo.1b
//>find('.answer-formatted-body p,.answer-comment-detail p');
//コメントNo.2
//>find('div[class*=answer-formatted-body] p,div[class*=answer-comment-detail] p');
//コメントNo.3a
//>find('#read_answer_list .answer-formatted-body p, #read_answer_list .answer-comment-detail p');
//コメントNo.3b
//>find('div[id=read_answer_list] div[class*=answer-formatted-body] p, div[id=read_answer_list] div[class*=answer-comment-detail] p');
$c=$html->find('[.answer-body p],[.answer-comment-detail p]');
$i=0;
echo '<table border=1>';
foreach($c as $key => $element){
	echo '<tr><td>' .$i .'</td><td>';
	$src[$key] = $element->innertext;
	echo $src[$key] . '</td></tr>';
	$i++;
}
echo '</table>';

※追記20131112
コメントにてセレクタの使用方法に突っ込みが有ったので、No.1bを追記。
No.1bでもちゃんと動きます。

//質問文
//>find('[.answer-body p],[.answer-comment-detail p]');

とりあえず、質問文にあるセレクタを使う。

はい、重複しています。では、次。

//コメントNo.1
//>find('[.answer-formatted-body p],[.answer-comment-detail p]');

[.answer-formatted-body p]のみではコメント部分は取得できないので、おそらくこの書き方で合っていると思います。

二重に取得してしまいますね。では、次。

//コメントNo.1b
//>find('.answer-formatted-body p,.answer-comment-detail p');


二重に取得されることは無くなりましたが、ベストアンサーが選出されている場合、同じデータが表示されるようになります。
抽出された要素数:26
※追記20131112

//コメントNo.2
//>find('div[class*=answer-formatted-body] p,div[class*=answer-comment-detail] p');


二重に取得されることは無くなりましたが、ベストアンサーが選出されている場合、同じデータが表示されるようになります。
抽出された要素数:26

//コメントNo.3a
//>find('#read_answer_list .answer-formatted-body p, #read_answer_list .answer-comment-detail p');

ベストアンサーを除いた回答・コメントが表示されます。

抽出された要素数:14

//コメントNo.3b
//>find('div[id=read_answer_list] div[class*=answer-formatted-body] p, div[id=read_answer_list] div[class*=answer-comment-detail] p');

ベストアンサーを除いた回答・コメントが表示されます。

抽出された要素数:14


大体こんな感じです。
では、次。

補足あり+「ここでベストアンサー」という文字列が有る場合。
No.2 4要素
No.3a 2要素
No.3b 2要素
「ここでベストアンサー」という文字列が無い場合。
No.2 1要素
No.3a 無し
No.3b 無し
「ベストアンサーが失格」という場合。
No.2 無し
No.3a 無し
No.3b 無し

(データが無い)

最後に、「回答オープンが必要」な場合。
No.2 無し
No.3a 無し
No.3b 無し

「id="unread_answer_list"」に囲まれている。構造が違うので対応できていない。


結論:スクレイピングは頭を使う。

以下雑記

simple_html_domは、ざっくりとググってみるとメモリ云々の問題があるような記事があるので、便利そうだなぁと思いつつ見送ります。検証とかはきっと誰かがやってくれるでしょう。
ささやかなサービスの画像取得には別な方法を組み込んであるのですが、上手く使えば便利ではないかな?と思います。
もうちょっと流行らないかな、アレ。