個人的な情報収集用に、まとめサイトのアンテナを作って自分で見ているのですが、取得を停止しているまとめの取得を再開しようと考えました。となると、過去記事の情報をなんとかして取らないといけないわけでして、記事一覧に埋め込まれてるrdf部分だけを取得できないか考えました(知恵袋で知恵を拝借しました)
xpathで取得しようと思ったけど、うまくいかないので、まずは力技で抜く
サンプルなんですけど、例としてhttp://workingnews.blog117.fc2.com/ このサイトから。
中身をみると、以下のような内容が含まれています
<!--<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/">
<rdf:Description rdf:about="http://workingnews.blog117.fc2.com/blog-entry-12228.html" trackback:ping="http://workingnews.blog117.fc2.com/tb.php/12228-5fa1fc55" dc:title="年商10億以上の会社に勤めてるけどボーナス入ったから明細うpしとくわ" dc:identifier="http://workingnews.blog117.fc2.com/blog-entry-12228.html" dc:subject="その他・特殊業界" dc:description="元スレ:http://news4vip/1545222338/ 1 :以下、?ちゃんねるからVIPがお送りします:2018/12/19(水) 21:25:38.365 ID:i9IRZFVe0.net せめて平均くれよん 2 :以下、?ちゃんねるからVIPがお送りします:2018/12/19(水) 21:26:09.899 ID:9FxRyD8Bp.net 手渡し? 3 :以下、?ちゃんねるからVIPがお送りします:2018/12/19(水) 21:26:33.317 ID:FTxUFyRSM.net 手書きwww 4 :以下、?ちゃん..." dc:creator="waku_new" dc:date="2018-12-21T01:06:11+09:00" />
</rdf:RDF>
-->
他のブログサイトではきっちり改行されていますが、あえて改行されていなかったこのサイトを例にしました。
ページの中に数カ所該当する部分がありますので、各箇所を切り取ってみて、配列に入れたいと思います。
strposを使って開始位置と終了位置を特定、その数値を以って切り取る
理屈的には、「<rdf:RDF」が始まる位置を特定して、次に「</rdf:RDF>」の最後の文字のところを特定して切り取る。「</rdf:RDF>」は10文字なので、strposで出てきた位置+10で終了位置を決める。
以下、コード
$html = @file_get_contents($target_url);
if ($html === false) { die('read abort'); }
$rdf = [];
while (($start = strpos($html, '<rdf:RDF')) !== false) {
$str = substr($html, $start);
$end = strpos($str, '</rdf:RDF>') + 10;
$rdf[] = substr($str, 0, $end);
$html = substr($str, $end+1);
}
最初に出てきたrdfのブロックを取得したら、取得終わったところまでをカットして、カットしたテキストに対して再度rdfを探すループを繰り返しています。※知恵袋で回答してもらった内容
rdfの配列には各記事のrdfが入っているので、今度はその中身に対して、それぞれ記事情報を1件ずつ取得していきます。
正規表現で各データを取得する
rdfを取得できたら、今度は各パラメータで欲しい部分を取得していきます。
以下、コード。
foreach($rdf as $r){
///title
preg_match("/.*dc:title.*/",$r,$match);
$title= trim(preg_replace('/.*dc:title="(.*?)".*/','$1',$match[0]));
//url preg_match("/.*dc:identifier.*/",$r,$match);
$url= trim(preg_replace('/.*dc:identifier="(.*?)".*/','$1',$match[0]));
///description
preg_match("/.*dc:description.*/",$r,$match);
$description= strip_tags(trim(preg_replace('/.*dc:description="(.*?)".*/','$1',$match[0])));
///author
preg_match("/.*dc:creator.*/",$r,$match);
$user_nick= trim(preg_replace('/.*dc:creator="(.*?)".*/','$1',$match[0]));
///date preg_match("/.*dc:date.*/",$r,$match);
$date= trim(preg_replace('/.*dc:date="(.*?)".*/','$1',$match[0]));
}
今回のデータでは、改行が入ってなかったデータだったので、まずは該当の名前空間のデータがあるかどうかをチェックしてから、正規表現で取り出すようにしました。無事に綺麗に取れました。
で、最後のページまでデータを取るためには、最初の取得ページのurlを次のページへ差し替えないといけません。上記処理が終わったら、以下内容を実行して、次のurlに差し替えます。※ただし、該当タグが入っていればですが。
///次ページがあるか確認
$dom = new DOMDocument;
@$dom->loadHTML(mb_convert_encoding(file_get_contents($target_url), 'HTML-ENTITIES', 'UTF-8'));
$xpath = new DOMXPath($dom);
// metaタグに次ページの指定があれば、そこから取得する。
//今回のサイトでは、url=で指定があったため、getAttributeをurlにしてますが
//他のサイトではhrefがほとんどでした。
$tmp=$xpath->query('//link[@rel="next"]');
if(method_exists($tmp->item(0),'getAttribute')){
$target_url=$tmp->item(0)->getAttribute("url");
}
else{
//最後のページの時の処理
}
こんな感じで、ひとまずメモがてらでした。