俺氏、本を読む

30歳になるまでに本を読んで勉強しようかと。主に啓発、お金についての本を読むつもり。一応プログラマーなのでその辺のことも。あと、せどり(転売)の仕入れ見込み商品をリサーチして仕入先と一緒に投稿します

【PHP】「おーぷん2ちゃんねる」の画像とかをヌク【画像取得】

「おーぷん2ちゃんねる」のトップページで紹介されている画像を取得してDB(MySql)に登録する方法!
とりあえずテーブルを作成して、そのテーブルに画像情報を突っ込んでいく!
 

テーブルの作成

とりあえず画像の情報を保持できるテーブルを作成。
サイズとかは特に意識してないので気になる方は勝手に変えちゃっていいと思います。

CREATE TABLE thread_img (
  cat_id varchar(32) NOT NULL,
  thread_id varchar(32) NOT NULL,
  res_no smallint(5) unsigned NOT NULL,
  img_url1 varchar(128) NOT NULL,
  img_url2 varchar(128) DEFAULT NULL,
  thread_url1 varchar(128) DEFAULT NULL,
  thread_url2 varchar(128) DEFAULT NULL,
  `view` int(10) unsigned DEFAULT '0',
  is_update tinyint(1) DEFAULT '0',
  upddatetime datetime DEFAULT NULL,
  PRIMARY KEY (cat_id,thread_id,res_no,img_url1)
)

画像の取得

「おーぷん2ちゃんねる」にはお絵かき機能なるものがあるようで、トップページで最新の50件の画像を表示しています。それをヌク!
アクセスするのはトップページではなくて「http://open2ch.net/page/oekakis.cgi
トップページではframeで「http://open2ch.net/page/oekakis.cgi」を表示しているだけなので、直接見にいく。
あとは、カテゴリの取得と同じような感じで情報をヌいてDBに登録していく!
 
ファイル名は「get_img.php」とかで。utf-8で保存するのをお忘れなく!!
ちなみに、俺氏は業務でPHPを使ったことがないので、おかしいところとかあったら指摘もらえるとありがたいです_(_^_)_

<?php
function curl_get_contents( $url, $timeout = 30 ){
	$ch = curl_init();
	$result = "";
	curl_setopt( $ch, CURLOPT_URL, $url);
	curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt( $ch, CURLOPT_HTTPPROXYTUNNEL, true);
	curl_setopt( $ch, CURLOPT_HEADER, false);
	curl_setopt( $ch, CURLOPT_USERAGENT, 'Monazilla/1.00 (自分のドメイン/1.00)');
	curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout );
	$result = curl_exec($ch);
	curl_close($ch);
	return $result;
}
/*** ディレクトリの存在をチェック ***/
function chkDirectory($dirpath, $create_flg = true){
	$return = false;
	if(file_exists($dirpath)){
		$return = true;
	}
	if(!$return){
		if($create_flg){
			mkdir($dirpath, 0711);
			chmod($dirpath, 0711);
		}
		$return = true;
	}
return $return;
}
// 後で戻せるように設定を保持
$org_mb_enc = ini_get('mbstring.internal_encoding');
//mbString関数のエンコーディング変更
ini_set('mbstring.internal_encoding', 'utf-8');

$insImgCnt=0;
try {
	//PDOオブジェクトの作成
	$pdo = new PDO("mysql:host=ホスト名;dbname=DB名;charset=utf8;", "ユーザーID", "パスワード");
	//SELECTの準備
	$imgSelect = $pdo->prepare("select count(`thread_id`) from `thread_img` where `cat_id`=? and `thread_id`=? and `res_no`=?");
	//INSERTの準備
	$imgInsert = $pdo->prepare("insert into `thread_img` VALUES(?, ?, ?, ?, ?, ?, ?, 0, 0, ?)");
	
	//画像コンテンツ取得
	$imgHtml = curl_get_contents('http://open2ch.net/page/oekakis.cgi');
	//a,imgタグ以外の要素を削除
	$imgHtml = strip_tags($imgHtml, '<a><img>');
	//aタグ内のhrefとimg要素を取得
	preg_match_all("|<a target=_blank href=\"(.*?)\".*?>(.*?)</a>|mis",$imgHtml,$match);
	$url=$match[1];
	$text=$match[2];

	for($i=0; $i<count($url);$i++) {
		$edIndex=mb_strrpos($url[$i],'/');
		$thredUrl1=mb_substr($url[$i],0,$edIndex);
		//urlからカテゴリ、スレッドID、レス番号取得
		$url_array = parse_url($thredUrl1);
		$saba = $url_array['host'];
		$path_array = explode('/', $url_array['path']);
		$catId = $path_array[3];
		$threadId = $path_array[4];
		$resNo = str_replace('-', '', mb_substr($url[$i],$edIndex+1));
		//データ存在チェック(存在すればスキップ)
		$imgSelect->execute(array($catId, $threadId, $resNo));
		if($imgSelect->fetchColumn() > 0) {
			continue;
		}
		//自サイトのスレッドurlを作成
		$thredUrl2='http://自分のドメイン/'.$catId.'/thread.php?id='.$threadId.'&resno='.$resNo;
		//imgタグからsrc参照先取得
		preg_match('/http.*?(\.gif|\.png|\.jpg|\.jpeg$|\.bmp)/i', $text[$i], $imgUrl);
		$imgUrl1=$imgUrl[0];
		//画像保存用のディレクトリ作成
		$catDirpath = '/home/自分のドメイン/public_html/'.$catId;
		$imgDirpath = $catDirpath.'/img';
		if( chkDirectory($catDirpath) ) {
			if( chkDirectory($imgDirpath) ) {
				$imgUrl2=$imgDirpath.'/'.basename($imgUrl1);
				if(copy($imgUrl1, $imgUrl2)){
					$imgUrl2=str_replace('/home/自分のドメイン/public_html', 'http://自分のドメイン', $imgUrl2);
					//INSERT実行
					$imgInsert->execute(array($catId, $threadId, $resNo, $imgUrl1, $imgUrl2, $thredUrl1, $thredUrl2, date('Y-m-d H:i:s')));
					$insImgCnt++;
				}
			}
		}
	}	
	$pdo->query('OPTIMIZE TABLE `thread_img`');
} catch (PDOException $e) {
	$pdo = null;
	// 設定を戻す
	ini_set('mbstring.internal_encoding', $org_mb_enc);
	exit('データベースエラー'.$e->getMessage());
}
$pdo = null;
// 設定を戻す
ini_set('mbstring.internal_encoding', $org_mb_enc);
//スレッド内容取得処理
exec("nohup php -c '' 'get_thread.php' > /dev/null &");

?>

これで「http://open2ch.net/page/oekakis.cgi」から取得した内容を「thread_img」テーブルに保存できる!(はず)
実際に取得したら以下のような感じ
f:id:oresi:20150106182708p:plain
 
お次はスレッド情報をヌク!