画像掲示板中の画像をPHPを使用して一括で保存するコードを教えてください。


掲示板中に複数の画像が掲載されています。
画像のサムネイルをクリックすると直接画像を表示するのではなく、その画像を原寸大表示しているhtmlへ転送します。

1:掲示板のアドレス例:a.bbb.com/thread/dfg.html
2:画像のサムネイルをクリックしたとき表示されるページのアドレス例:a.bbb.com/thread/picture/jy3hfa.html
3:画像ファイルそのもののアドレス例:h.bbb.com/y23fcd.8i2jpg?7c2(最後の/以下は?や.も含む文字列)

1のページにあるリンクのうち、URLに"picture"を含むものは2のページのみです。(トップページや1のページには含まれない。)
href="./thread/picture/jy3hfa.html"という形式になっています。

2のページ中のリンクのうち、URLに"h.bbb.com"を含むのは3の画像ファイルのみです。(画像ファイル本体のみサブドメインが異なる)

すべての画像ファイルをフォルダに一括保存するPHPのコードを教えてください。
よろしくお願いします。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2012/09/09 20:54:10
  • 終了:2012/09/10 20:27:13

ベストアンサー

id:Cherenkov No.1

Cherenkov回答回数1502ベストアンサー獲得回数4922012/09/10 09:13:13

ポイント200pt

うーん。一応動いてると思います。
urlをコマンドラインで渡すとかフォームからとか変える余地あるけど取り敢えず。

<?php
function p($msg) {  
	echo $msg.PHP_EOL;  
}
function pr($var) {
	echo '<pre>'; print_r($var); echo '</pre>';
}

set_time_limit(0);

//mb_convert_encodingの第3引数をautoで使う場合に必要。
mb_language("Japanese");

$urls = array('http://imgb1.ziyu.net/bbs/nendoro2/index.cgi');

$pUrl = parse_url($urls[0]);
$baseUrl = $pUrl['scheme'] . '://' . $pUrl['host'];

preg_match('/\/bbs\/([^\/]+)/', $pUrl['path'], $siteId);
$siteId = $siteId[1];
$baseBBSUrl = "$baseUrl/bbs/$siteId";

$newUrls = getPageUrls($urls[0]);
$urls += $newUrls;

foreach ($urls as $url) {
	$html = mb_convert_encoding(file_get_contents($url), 'UTF-8', 'auto');
	preg_match_all('/href="(\/view\/.+?)"/im', $html, $imgPaths);
	$imgPaths = $imgPaths[1];
	foreach ($imgPaths as $path) {
		$imgUrl = getImgUrl($baseUrl . $path);
		saveImg($imgUrl);
	}
	//sleep(3);
}
p('complete!');

function getPageUrls($url) {
	$html = mb_convert_encoding(file_get_contents($url), 'UTF-8', 'auto');
	preg_match_all('/\[<a href="(index\.cgi\?page=\d+)/im', $html, $urls);
	$urls = $urls[1];
	$urls = array_map(function($path) {
		global $baseBBSUrl;
		return $baseBBSUrl . '/' . $path;
	}, $urls);
	return $urls;
}
function getImgUrl($url) {
	global $baseUrl;
	$html = mb_convert_encoding(file_get_contents($url), 'UTF-8', 'auto');
	preg_match("/<img src='(.+?)'/im", $html, $imgUrl);
	return $baseUrl . $imgUrl[1];
}
function saveImg($url) {
	$fileName = basename($url);
	$data = file_get_contents($url);
	$imgDir = './download/';
	if (file_exists($imgDir) || mkdir($imgDir)) {
		if ($data && file_put_contents($imgDir . $fileName, $data)) {
			p('success!');
		} else {
			p('retry!');
			saveImg($url);
		}
	}
}
id:Cherenkov

動作テストは適当に見つけた、画像の少ない http://imgb1.ziyu.net/bbs/lelouch/index.cgi を使った。

2012/09/10 09:21:39
id:Cherenkov

saveImg関数だけretryするようにしてるけど他のfile_get_contentsするところもやったほうがよさげ

2012/09/10 09:34:18
  • id:Cherenkov
    javascriptを使ってサムネイルのリンクを画像に直リンして、適当なダウンローダを使って保存する方法じゃだめですか?
    PHPでやるにしても実験用に目的の画像掲示板のURLなり同等の画像掲示板を示してもらわないと厳しいですよ。
  • id:holoholobird
    >Cherenkovさん
    コメントありがとうございます。
    同等ではありませんが、似たような掲示板ですと以下が挙げられます。
    http://imgb1.ziyu.net/bbs/nendoro2/index.cgi
    適当なサムネイルをクリックするとページが表示されると思います。
    これが質問文の2に該当します。

    たとえば
    imgb1.ziyu.net/view/nendoro2/1347175059.jpg.html
    このページの中央にある画像を保存したいのなら
    imgb1.ziyu.net/ZxrDYWeha/nendoro2/1347175059.jpg
    を保存すればいいことになります。

    私が保存したいページも同じように中央に画像が表示されますが、
    URLの扱いが少々異なります。(画像とページのサブドメインが異なる)

    たとえば、
    a.bbb.com/thread/picture/jy3hfa.html
    の中央にある画像を保存したいなら、
    h.bbb.com/y23fcd.8i2jpg?7c2
    を保存することになります。
  • id:windofjuly
    うぃんど 2012/09/09 21:51:43
    1. file_get_contents で thread/dfg.html を読み込み
    2. preg_match_all で thread/picture/.*\.html を抜き出し
    3. matchesでループ開始
    4.   file_get_contents で 画像表示用のページを読み込み
    5.   preg_match_all で h.bbb.com/.* のURLを抜き出し
    6.   matchesでループ開始
    7.     file_get_contents で 画像読み込み
    8.     file_put_contents で ローカルに書き込み
    9.   ループここまで
    10.ループここまで
        
    文字にするとこれだけのこと(phpで書いてもあまり変わらないけど)
    holoholobird さんなら簡単に出来る話なのに、
    質問にしているという理由がイマイチわからず、
    何を要点にした回答をすれば良いのか判らない。

    例えば file_get_contents で取得できなかったというような理由があれば、
    cURL 使ってみてといったような回答もできるのだけど…

    例えば、今回限りの話ならWebsite Explorerで構造しらべて、
    画像ファイルだけダウンローダに登録してダウンロードしてとか…
    http://www.vector.co.jp/soft/win95/net/se247055.html

    単にめんどくさかっただけなら、上の文字列をphpに直しますが…

    とりあえず返信待ち……今日はもう落ちます。
  • id:holoholobird
    >windofjulyさん
    コード自体は私も似たアルゴリズムで記述したのですが、
    エラー発生の連続で正常に動作しませんでした。

    エラーの度に原因を探してデバッグを行ったのですが、
    トライアンドエラーの繰り返しで2日間頑張っても達成できなかったので、
    正常に動くコードを作成してもらおうと思った次第です。

    http://imgb1.ziyu.net/bbs/nendoro2/index.cgi
    まず正常に動作するコードがあれば改編で何とかなると思うので、
    上記のようなサイトの画像を取得することができる、
    PHPの完成コードを教えてください。

    >website explorer
    website explorerも試しましたが、なぜか403エラーになります。
    フリーソフトでは真っ先にweboxを使用してみたのですが、
    条件設定に正規表現が使えませんでした。
    サブドメイン部分に正規表現を使うことができれば解決できたんですが……
  • id:windofjuly
    うぃんど 2012/09/10 11:10:17
    >403エラー

    コメントで例に挙げたcURLで、
    リファラ送信してやると取得できそうな感じですね。

    回答ついてますので、そちらの確認後に対応を考えます。
  • id:holoholobird
    どうやら無事にできました。
    お答えいただいたみなさん、ありがとうございました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません