php抓图,php并发抓图怎么知道有没抓完呢

我有个程序,将图片抓回来;然后打包成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 - 获取所有相关的插座与卷曲的扩展名,这样就可以“选择”

今天研究一下,用这个方式的话。应该就不用表老记录图片数量啦。

表来记录图片数量啦

搞明白啦 谢谢大家。结贴 !

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值