4

私はhttp://pinterest.comのようないくつかの機能をシミュレートしています add a pin

幅と高さが200以上のURLからすべての画像をより速く取得するにはどうすればよいですか? pinterest.comプロセス全体をほぼ 10 秒で終了しますが、48.64 秒必要です。

require dirname(__FILE__) . '/simple_html_dom.php';
$url = 'http://www.huffingtonpost.com/';
$html = file_get_html($url);
if($html->find('img')){
    foreach($html->find('img') as $element) {
        $size = @getimagesize($element->src);
        if($size[0]>=200&&$size[1]>=200){
            echo $element;
        }
    }
}// cost 48.64 seconds
4

4 に答える 4

10

詳細については、 http://php.net/manual/en/function.curl-multi-init.phpを参照し curlてください。このようにして、ロードがはるかに高速になり、速度に影響を与える可能性のあるすべての帯域幅の問題が回避されます.parallelcurl_multi_init

イメージをローカルで直接実行するのではなく、ローカルの一時ディレクトリに保存します。これは、イメージを実行getimagesize()するよりもはるかに高速です。http://

これが役立つことを願っています

編集 1

ノート***

A. すべての画像がで始まるわけではありませんhttp

B. すべての画像が有効であるとは限らない

C.temp画像を保存する必要があるフォルダーを作成する

概念実証

require 'simple_html_dom.php';
$url = 'http://www.huffingtonpost.com';
$html = file_get_html ( $url );
$nodes = array ();
$start = microtime ();
$res = array ();

if ($html->find ( 'img' )) {
    foreach ( $html->find ( 'img' ) as $element ) {
        if (startsWith ( $element->src, "/" )) {
            $element->src = $url . $element->src;
        }
        if (! startsWith ( $element->src, "http" )) {
            $element->src = $url . "/" . $element->src;
        }
        $nodes [] = $element->src;
    }
}

echo "<pre>";
print_r ( imageDownload ( $nodes, 200, 200 ) );
echo "<h1>", microtime () - $start, "</h1>";

function imageDownload($nodes, $maxHeight = 0, $maxWidth = 0) {

    $mh = curl_multi_init ();
    $curl_array = array ();
    foreach ( $nodes as $i => $url ) {
        $curl_array [$i] = curl_init ( $url );
        curl_setopt ( $curl_array [$i], CURLOPT_RETURNTRANSFER, true );
        curl_setopt ( $curl_array [$i], CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)' );
        curl_setopt ( $curl_array [$i], CURLOPT_CONNECTTIMEOUT, 5 );
        curl_setopt ( $curl_array [$i], CURLOPT_TIMEOUT, 15 );
        curl_multi_add_handle ( $mh, $curl_array [$i] );
    }
    $running = NULL;
    do {
        usleep ( 10000 );
        curl_multi_exec ( $mh, $running );
    } while ( $running > 0 );

    $res = array ();
    foreach ( $nodes as $i => $url ) {
        $curlErrorCode = curl_errno ( $curl_array [$i] );

        if ($curlErrorCode === 0) {
            $info = curl_getinfo ( $curl_array [$i] );
            $ext = getExtention ( $info ['content_type'] );
            if ($info ['content_type'] !== null) {
                $temp = "temp/img" . md5 ( mt_rand () ) . $ext;
                touch ( $temp );
                $imageContent = curl_multi_getcontent ( $curl_array [$i] );
                file_put_contents ( $temp, $imageContent );
                if ($maxHeight == 0 || $maxWidth == 0) {
                    $res [] = $temp;
                } else {
                    $size = getimagesize ( $temp );
                    if ($size [1] >= $maxHeight && $size [0] >= $maxWidth) {
                        $res [] = $temp;
                    } else {
                        unlink ( $temp );
                    }
                }
            }
        }
        curl_multi_remove_handle ( $mh, $curl_array [$i] );
        curl_close ( $curl_array [$i] );

    }

    curl_multi_close ( $mh );
    return $res;
}

function getExtention($type) {
    $type = strtolower ( $type );
    switch ($type) {
        case "image/gif" :
            return ".gif";
            break;
        case "image/png" :
            return ".png";
            break;

        case "image/jpeg" :
            return ".jpg";
            break;

        default :
            return ".img";
            break;
    }
}

function startsWith($str, $prefix) {
    $temp = substr ( $str, 0, strlen ( $prefix ) );
    $temp = strtolower ( $temp );
    $prefix = strtolower ( $prefix );
    return ($temp == $prefix);
}

出力

Array
(
    [0] => temp/img8cdd64d686ee6b925e8706fa35968da4.gif
    [1] => temp/img5811155f8862cd0c3e2746881df9cd9f.gif
    [2] => temp/imga597bf04873859a69373804dc2e2c27e.jpg
    [3] => temp/img0914451e7e5a6f4c883ad7845569029e.jpg
    [4] => temp/imgb1c8c4fa88d0847c99c6f4aa17a0a457.jpg
    [5] => temp/img36e5da68a30df7934a26911f65230819.jpg
    [6] => temp/img068c1aa705296b38f2ec689e5b3172b9.png
    [7] => temp/imgfbeca2410b9a9fb5c08ef88dacd46895.png
)
0.076347

ありがとう :)

于 2012-04-05T21:58:08.593 に答える
2

getimagesize() は、最初に画像ファイル全体をダウンロードしてから、分析を行います。通常、タイプ/解像度の詳細を取得するには、ファイルの最初の数百バイトだけが必要です。さらに、画像ごとに個別の http リクエストを使用します。

適切に最適化されたシステムでは、部分取得リクエストを使用して画像の最初のチャンクのみを取得し、http キープアライブを利用して TCP 接続のオーバーヘッドを最小限に抑えます。

于 2012-04-05T21:05:16.833 に答える
2

参照

imagecreatefromstringimagesxおよびを使用imagesyします。これは 30 秒で実行する必要があります。getimagesize() より少し速い

function ranger($url){
    $headers = array( "Range: bytes=0-32768" );
    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    return curl_exec($curl);
    curl_close($curl);
}
require dirname(__FILE__) . '/simple_html_dom.php';
$url = 'http://www.huffingtonpost.com/';
$html = file_get_html($url);
if($html->find('img')){
    foreach($html->find('img') as $element) {
        $raw = ranger($element->src);
        $im = @imagecreatefromstring($raw);
        $width = @imagesx($im);
        $height = @imagesy($im);
        if($width>=200&&$height>=200){
            echo $element;
        }
    }
}
于 2012-04-05T22:57:51.007 に答える
1

そして、htmlから幅と高さを読み取るのはどうですか? 一部の画像にはこの属性がないことはわかっていますが、この属性が 200px 未満の画像はスキップできるかもしれません。

それはただのアイデアですが、あなたには使えないかもしれません。

于 2012-04-05T21:22:27.747 に答える