【PHP】手動でRSSの内容を取得する

概要

手作業でRSS取得するというちょっと意味のわからない事をしました。
サムネイルは遷移先のimgタグ直前のクラスを指定するか、正規表現も使えます。

コード

save_rss( 'https://noarts.net/feed/' );

function save_rss( $url ) {
	$rss = @simplexml_load_file( $url, 'SimpleXMLElement', LIBXML_NOCDATA );

	$datas = null;
	if ( ! empty( $rss->channel->item ) ) {
		$datas = $rss->channel->item;
	} else if ( ! empty( $rss->item ) ) {
		$datas = $rss->item;
	} else if ( ! empty( $rss->entry ) ) {
		$datas = $rss->entry;
	} else {
		echo 'error';
		var_dump( $rss );
		die();
	}
	//直上クラスをarray('class_name','class_name2');のような形にいれて指定する
	//個人サイトとかでmetaがない場合ぐらいしか使わないはず
	$class_list = null;
	// hp上のメタデータのサムネイルを取得する
	$override_preg = '/og:image\"\s*content\s*=\s*[\"|\'](.*?)[ \"|\'][^<>]*/i';
	save_cdata( $datas, $class_list, $override_preg );
}

// URL遷移先からサムネイル取得
function pick_thumbnail( $target_text, $class, $override_preg = null ) {
	$image_thumbnail_url = '';

	//直上クラスからデータ取得
	$preg = '/' . $class . '[^<]*<img[^<>]*src\s*=\s*[\"|\'](.*?)[\"|\'][^<>]*>/i';
	if ( empty( $class ) ) {
		// imgタグが一個しかないからそこから取得する(description内に画像がある場合だけ使う)
		$preg = '/<img[^<>]*src\s*=\s*[\"|\'](.*?)[\"|\'][^<>]*>/i';
	}
	if ( ! empty( $override_preg ) ) {
		$preg = $override_preg;
	}

	preg_match_all( $preg, $target_text, $img_path_list );
	if ( ! empty( $img_path_list[1][0] ) ) {
		$image_thumbnail_url = $img_path_list[1][0];
	}
	$image_thumbnail_url = preg_replace( '/^\/\//i', 'https://', $image_thumbnail_url );

	return $image_thumbnail_url;
}

//タイトル取得
function pick_feed_title( $item ) {
	if ( ! empty( $item->title ) ) {
		return (string) $item->title;
	}

	return '';
}

//リンク取得
function pick_feed_link( $item ) {
	$link = '';
	if ( ! empty( $item->link ) ) {
		$link = (string) $item->link;
	} elseif ( @ ! empty( $item->link->attributes()->href ) ) {
		$link = (string) $item->link->attributes()->href;
	}

	return $link;
}

//公開日取得
function pick_feed_date( $item ) {
	if ( ! empty( $item->{'dc:date'} ) ) {
		$published_at = date( "Y/n/j H:i", strtotime( ! empty( $item->{'dc:date'} ) ) );
	} else if ( ! empty( $item->pubDate ) ) {
		$published_at = date( "Y/n/j H:i", strtotime( $item->pubDate ) );
	} else {
		$published_at = date( "Y/n/j H:i" );
	}

	return $published_at;
}

function save_cdata( $datas, $class_list, $override_preg = null ) {
	foreach ( $datas as $item ) {
		$article_title       = null;
		$article_url         = null;
		$published_at        = null;
		$image_thumbnail_url = null;

		$article_title = pick_feed_title( $item );
		$article_url   = pick_feed_link( $item );
		$published_at  = pick_feed_date( $item );

		// サムネイル取得
		$media_content   = @(string) $item->children( 'media', true )->content->attributes()->url;
		$enclosure_url   = @(string) $item->enclosure['url'];
		$media_thumbnail = @(string) $item->children( 'media', true )->thumbnail->attributes()->url;

		if ( ! empty( $media_content ) ) {
			$image_thumbnail_url = $media_content;
		} elseif ( ! empty( $enclosure_url ) ) {
			$image_thumbnail_url = $enclosure_url;
		} elseif ( ! empty( $media_thumbnail ) ) {
			$image_thumbnail_url = $media_thumbnail;
		}

		//descriptionにサムネイルがあるパターン
		if ( ! empty( $item->description ) && empty( $image_thumbnail_url ) ) {
			$image_thumbnail_url = pick_thumbnail( $item->description, '' );
		}

		// URLの遷移先のクラス名などから画像取ってくるパターン
		if ( ! empty( $class_list ) && empty( $image_thumbnail_url ) ) {
			foreach ( $class_list as $class ) {
				$file_content        = file_get_contents( $article_url );
				$image_thumbnail_url = pick_thumbnail( $file_content, $class );
			}
		}
		// $override_pregに書かれた正規表現でリンク先の画像URLを抜くパターン
		if ( ! empty( $override_preg ) && empty( $image_thumbnail_url ) ) {
			$file_content        = file_get_contents( $article_url );
			$image_thumbnail_url = pick_thumbnail( $file_content, null, $override_preg );
		}

		var_dump(
			$article_title,
			$article_url,
			$published_at,
			$image_thumbnail_url );
	}
}

実行例

この記事書いた時に画像ある記事がなかったので最後の行は空になっています

/var/www/html/test.php:141:string '【Amazon Linux】php7.1にZend OPcacheとAPCuはインストールできない?' (length=82)
/var/www/html/test.php:141:string 'https://noarts.net/archives/400' (length=31)
/var/www/html/test.php:141:string '2018/4/20 20:13' (length=15)
/var/www/html/test.php:141:string '' (length=0)

まとめ

RSSのAPIって偉大だね…。
RSSのバージョンは確認していないので多分網羅はしてないです。

タイトルとURLをコピーしました