Php sayfaları çok kazımak için en hızlı yolu nedir?

3 Cevap php

Ben birkaç siteleri kazıma ve kullanıcıya aranabilir bir şekilde kendi bilgi endeksleme dayanan bir veri toplayıcı var.

Ben her gün, bir sayfa çok sayıda kazımak gerekiyor, ve ben uzun bir süre (kazıyıcı temelde 7/24 çalışan) için hızlı sırayla idam zaman oldukça yavaş basit kıvırmak istekleri, kullanarak sorunların rastladım.

Basit bir süre döngü içinde bir çok kıvırmak isteği Koşu oldukça yavaş. Ben daha hızlı çalışan bir arka plan işlemi, bireysel kıvırmak isteklerini yaparak bunu hızlandırdı, ama er ya da geç yavaş istekleri sunucu çökmesini biter, hangi yığılmaya başlar.

Veri kazıma daha verimli bir yolu var mı? belki komut satırı kıvırmak?

3 Cevap

Eğer I / O ağında bekleyen çoğu zaman harcama olacak çünkü sayfaların çok sayıda ile, çok iş parçacıklı bir yaklaşım çeşit gerekir

Ben PHP parçacığı ile oynanan son kez bir seçenek tüm bu harika, ama belki de bu değişmiş değil. N iş birimlerinin içine yükünü bölmek ve her 1 iş biriminin aldığı senaryonun K örneğini çalıştırın: PHP ile sopa gerekiyorsa, o bir çok proses yaklaşımı gitmek zorunda olacak demektir.

Sağlam ve iyi iplik uygulamaları sağlamak Diller başka bir seçenek vardır. Ben yakut ve C konuları ile iyi deneyimler yaşadım ve Java Konuları de çok olgun ve güvenilir gibi görünüyor.

Kim bilir - belki PHP Konuları I (~ 4 yıl önce) onlarla oynadı son kez bu yana gelişmiş ve bir göz değer var.

Benim deneyim parçacığı sabit bir sayı ile bir curl_multi isteği çalışan en hızlı yolu, size bu yüzden bazı iyileştirmeler önerebilirsiniz kullandığınız kod payı olabilir mi? This answer dişli bir yaklaşımla curl_multi oldukça iyi bir uygulama vardır, burada çoğaltılmış kodu:

// -- create all the individual cURL handles and set their options
$curl_handles = array();
foreach ($urls as $url) {
    $curl_handles[$url] = curl_init();
    curl_setopt($curl_handles[$url], CURLOPT_URL, $url);
    // set other curl options here
}

// -- start going through the cURL handles and running them
$curl_multi_handle = curl_multi_init();

$i = 0; // count where we are in the list so we can break up the runs into smaller blocks
$block = array(); // to accumulate the curl_handles for each group we'll run simultaneously

foreach ($curl_handles as $a_curl_handle) {
    $i++; // increment the position-counter

    // add the handle to the curl_multi_handle and to our tracking "block"
    curl_multi_add_handle($curl_multi_handle, $a_curl_handle);
    $block[] = $a_curl_handle;

    // -- check to see if we've got a "full block" to run or if we're at the end of out list of handles
    if (($i % BLOCK_SIZE == 0) or ($i == count($curl_handles))) {
        // -- run the block

        $running = NULL;
        do {
            // track the previous loop's number of handles still running so we can tell if it changes
            $running_before = $running;

            // run the block or check on the running block and get the number of sites still running in $running
            curl_multi_exec($curl_multi_handle, $running);

            // if the number of sites still running changed, print out a message with the number of sites that are still running.
            if ($running != $running_before) {
                echo("Waiting for $running sites to finish...\n");
            }
        } while ($running > 0);

        // -- once the number still running is 0, curl_multi_ is done, so check the results
        foreach ($block as $handle) {
            // HTTP response code
            $code = curl_getinfo($handle,  CURLINFO_HTTP_CODE);

            // cURL error number
            $curl_errno = curl_errno($handle);

            // cURL error message
            $curl_error = curl_error($handle);

            // output if there was an error
            if ($curl_error) {
                echo("    *** cURL error: ($curl_errno) $curl_error\n");
            }

            // remove the (used) handle from the curl_multi_handle
            curl_multi_remove_handle($curl_multi_handle, $handle);
        }

        // reset the block to empty, since we've run its curl_handles
        $block = array();
    }
}

// close the curl_multi_handle once we're done
curl_multi_close($curl_multi_handle);

Hüner yavaş istekleri tamamlanıncaya kadar tüm süreç askıda olacağını yaparsanız, bir kerede çok fazla URL yüklemeyin etmektir. Ben size bant genişliği varsa, bir BLOCK_SIZE 8 veya daha kullanmanızı öneririz.

Eğer tek kıvırmak isteklerini çalıştırmak istiyorsanız gibi PHP linux altında arka plan işlemlerini başlatabilirsiniz:

proc_close ( proc_open ("php -q yourscript.php parameter1 parameter2 & 2> /dev/null 1> /dev/null", array(), $dummy ));

Eğer PHP Script sql LİMİTİ gibi url kullanmak ne hakkında bazı bilgiler vermek için parametreleri kullanabilirsiniz.

Sen aynı anda çalışan işlemlerin aranan bir sayıda tutmak veya zamanında bitmedi süreçleri öldürmek için bir yerde onların PID'lere kaydederek çalışan süreçleri takip edebilirsiniz.