php並發抓圖怎麼知道有沒抓完呢

來源:互聯網
上載者:User
我有個程式,將圖片抓回來;然後打包成zip。
當前用的是單線程,由於實在太慢。所以想用多線程並發抓。
但這樣做的話,我不知道什麼時候可以打包zip。
大俠們給點建議吧


回複討論(解決方案)

抓回來了才會寫盤
你在程式中維護一個目標列表,當列表中的檔案都存在了,就可以打包了

多線程同步問題,訊號量同步。

怎麼抓圖的,能否分享

多線程同步問題,訊號量同步。

這位仁兄,可否解釋更清楚一點呢。

抓回來了才會寫盤
你在程式中維護一個目標列表,當列表中的檔案都存在了,就可以打包了

版主 這個方法我想過。覺得挺麻煩的。因為我這邊有幾百個專題進行迴圈,一個專題內容有七八張圖片。
每次通過正則擷取內容中的圖片地址,抓取到伺服器;再壓圖大小。

如果需要記錄,那應該是一次迴圈並發多個進程。然後執行完了再進入下個迴圈。

怎麼抓圖的,能否分享

抓圖不難
最簡單的就是file_get_contents

你難道不記錄哪個圖片是哪個專題的嗎?

你難道不記錄哪個圖片是哪個專題的嗎?

沒有關聯圖片記錄表
因為內容可能經常要更新,目前增加無太大的意義。

為每一個專題建立一個檔案夾,每次用正則匹配的時候,就統計一下有幾張圖片,然後把這個資料寫入到檔案夾下的一個專用檔案中,如.number等!

另寫一個打包程式,不停的掃描這些檔案夾下的檔案,並與特殊檔案中的檔案個數進行比較,如果檔案個數相等就直接打包,並刪除檔案夾!

PV操作。。你要維持一個訊號量。簡單的說是一個變數。如果程式運行之前你就知道要抓取多少檔案,那麼這個值在一開始就是確定的,比如說你知道要抓取5張圖片,那麼這個變數的值就是5,每個子進程完成一張圖片抓取動作這個變數就減一,最終為0時表示全抓完了。

如果一開始不知道要抓多少圖片,那麼這個訊號量需要動態維護了,且要加入其他訊號量來控制進程間的同步。比如有可能該訊號量為0,但實際上還有進程在分析是否還有圖片要進行抓取,而因為該訊號量為0,程式直接退出。這樣的情況也要考慮。

另外,你怎麼用的多線程?PHP不支援多線程的。

apache有多執行緒元件
也可是用iframe實現吧

另外,你怎麼用的多線程?PHP不支援多線程的。

php 5.+ 之後的curl是支援多線程的,你是每下載一個就要打包一次?

為每一個專題建立一個檔案夾,每次用正則匹配的時候,就統計一下有幾張圖片,然後把這個資料寫入到檔案夾下的一個專用檔案中,如.number等!

另寫一個打包程式,不停的掃描這些檔案夾下的檔案,並與特殊檔案中的檔案個數進行比較,如果檔案個數相等就直接打包,並刪除檔案夾!

這個方法挺好的。不過可能用表會更好點,因為可以記更多東西。比如已觸發抓取的圖片,抓取的狀態;完成的時間等。

我簡單描述下這邊的情況
由於軟體那邊的一個專題app,有這樣一個功能。
使用者需要可以下載離線包瀏覽專題。

和軟體那邊約定好的格式為zip

zip內結構為
檔案夾(專題id)對應多個專題圖片 一個專題首頁
而多個專題就會產生多個檔案夾,檔案夾名為專題id。

我現在的工作是要將這些專題組建檔案夾資料,然後再打包為zip。提供給軟體那邊下載。
專題圖片是由專題內容中正則匹配圖片地址,再抓回來的。
現在出現的問題,由於幾百個專題。一個專題內容有八九張圖片;
造成抓取速度狠慢。

或者我需要一個表,記錄每次迴圈正則匹配的圖片數;每次抓取成功或失敗都去減少這個量。
然後在程式中while查詢這個數量,直到為零的時候就進入下一個專題。

另外,你怎麼用的多線程?PHP不支援多線程的。

有辦法的 可以用fsockopen觸發抓圖程式的連結。 不需等待該連結返回,程式會繼續跑。

抓取宜使用 curl,技術簡單且效率高
curl 可直接將抓取的資料寫入檔案
curl_multi 可同時掛載多個 curl
curl_getinfo 可擷取相關的工作資訊(如果需要的話)

判定 curl_multi 各成員結束,就判定了抓取結束
這也符合你不打算儲存進度資訊的初衷

抓取宜使用 curl,技術簡單且效率高
curl 可直接將抓取的資料寫入檔案
curl_multi 可同時掛載多個 curl
curl_getinfo 可擷取相關的工作資訊(如果需要的話)

判定 curl_multi 各成員結束,就判定了抓取結束
這也符合你不打算儲存進度資訊的初衷

版主 我可以加多個表選項組,不過這個表應該怎樣設計好呢。
一個包關聯多個專題,多個包可以並發進行產生zip操作。
我想過這樣的表結構

proc的結構
id 圖片地址 包id 執行狀態(1為已抓取) 專題id

一開始清空 proc 當前產生 包id的記錄數
迴圈專題的時候
匹配了圖片地址 一張為一條記錄插入這張表。
抓取成功或失敗則更新執行的狀態
最後有個迴圈
直到查詢這張表的某個包,某個專題的圖片執行狀態為1的記錄數等於正則匹配的圖片數則進入下一個專題迴圈。

我不確定有沒描述清楚,這個產生過程還有其它的一些操作;剛開始我只抽了關鍵的一些來描述。

版主 我proc表的設計合理不。

版主大哥 我在等你回複呢

我已經按這個想法寫好程式 下午測試

你測試了,發現不足就改進
發現不能解決的問題就提問

修正了一下午 用fsockopen 來觸發一個抓取圖片的指令碼。如果不fgets就觸發不了。本地試是可以的。搞不清楚什麼原因。

後來網上搜了個

**  * curl 多線程  *   * @param array $array 並行網址  * @param int $timeout 逾時時間 * @return array  */  function curl_http($array,$timeout){ $res = array(); $mh = curl_multi_init();  //建立多個curl語柄$startime = getmicrotime(); foreach($array as $k=>$url){ $conn[$k]=curl_init($url);        curl_setopt($conn[$k], CURLOPT_TIMEOUT, $timeout); //設定逾時時間        curl_setopt($conn[$k], CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');        curl_setopt($conn[$k], CURLOPT_MAXREDIRS, 7);   //HTTp定向層級        curl_setopt($conn[$k], CURLOPT_HEADER, 0);   //這裡不要header,加塊效率        curl_setopt($conn[$k], CURLOPT_FOLLOWLOCATION, 1); // 302 redirect        curl_setopt($conn[$k],CURLOPT_RETURNTRANSFER,1);        curl_multi_add_handle ($mh,$conn[$k]); }do {$mrc = curl_multi_exec($mh,$active);//當無資料,active=true} while ($mrc == CURLM_CALL_MULTI_PERFORM);//當正在接受資料時while ($active and $mrc == CURLM_OK) {//當無資料時或請求暫停時,active=trueif (curl_multi_select($mh) != -1) {do {$mrc = curl_multi_exec($mh, $active);} while ($mrc == CURLM_CALL_MULTI_PERFORM);}} foreach ($array as $k => $url) {  curl_error($conn[$k]);  //$res[$k]=curl_multi_getcontent($conn[$k]);//獲得返回資訊  $header[$k] = curl_getinfo($conn[$k]);//返回頭資訊  curl_close($conn[$k]);//關閉語柄  curl_multi_remove_handle($mh, $conn[$k]);   //釋放資源  }curl_multi_close($mh);$endtime = getmicrotime();$diff_time = $endtime - $startime;return array('diff_time'=>$diff_time,'return'=>$res,'header'=>$header);  } //計算目前時間 function getmicrotime() {    list($usec, $sec) = explode(" ",microtime());    return ((float)$usec + (float)$sec);}


測試過還行。不過不知道為啥本地測試的話,file_get_contents比這個更快。

while ($active and $mrc == CURLM_OK) {        //當無資料時或請求暫停時,active=true        if (curl_multi_select($mh) != -1) {            do {                $mrc = curl_multi_exec($mh, $active);            } while ($mrc == CURLM_CALL_MULTI_PERFORM);        }    }


另外 不大理解這句的作用。 上面已經觸發了連結。
這段是用來檢測什麼時候完成的嗎 ?

            do {                $mrc = curl_multi_exec($mh, $active);            } while ($mrc == CURLM_CALL_MULTI_PERFORM);


這段和上面的重複

你用了 curl_multi_select 函數,卻又不知道他是幹什麼的,....

手冊說
curl_multi_select -- Get all the sockets associated with the cURL extension, which can then be "selected"
google說
curl_multi_select - 擷取所有相關的插座與捲曲的副檔名,這樣就可以“選擇”

今天研究一下,用這個方式的話。應該就不用表老記錄圖片數量啦。

表來記錄圖片數量啦

搞明白啦 謝謝大家。結貼 !

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.