V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
qiuai
V2EX  ›  PHP

求一个同时抓取多个文件的办法.

  •  
  •   qiuai · 2013-06-08 14:31:17 +08:00 · 4597 次点击
    这是一个创建于 4190 天前的主题,其中的信息可能已经有所发展或是发生改变。
    现在有5台服务器,每台服务器上有一个探针,每个探针执行时间约5秒.
    如果挨个抓,就需要25秒.
    有什么办法能够同时去抓这5台服务器的探针呢? 把时间缩短到5秒.
    第 1 条附言  ·  2013-06-08 19:35:34 +08:00
    已经成功实现了.用了 PHP - spider 框架 的 HttpClient...
    感谢大家的帮助...
    23 条回复    1970-01-01 08:00:00 +08:00
    tension
        1
    tension  
       2013-06-08 14:36:31 +08:00
    写缓存
    qiuai
        2
    qiuai  
    OP
       2013-06-08 14:40:13 +08:00
    @tension 每台服务器上都有缓存.但是是要激活才会有.总不能为了个不知道什么时候会看一次的信息列表去每分钟执行一次缓存吧...
    swulling
        3
    swulling  
       2013-06-08 14:41:46 +08:00
    并行抓啊,多线程
    likexian
        4
    likexian  
       2013-06-08 14:42:29 +08:00
    多线程,用python吧,相当简单
    qiuai
        5
    qiuai  
    OP
       2013-06-08 15:11:44 +08:00
    @swulling PHP有多线程的办法?
    @likexian =.=不会python.
    blacked
        6
    blacked  
       2013-06-08 15:14:40 +08:00
    PHP CURL 并发 就可以了
    txlty
        7
    txlty  
       2013-06-08 15:16:16 +08:00
    1. 连续5次调用自身文件,每次调用指向不同探针,然后汇总
    2. 用curl异步抓取。curl_multi_init()
    qiuai
        8
    qiuai  
    OP
       2013-06-08 15:35:23 +08:00
    lyjyiran
        9
    lyjyiran  
       2013-06-08 15:37:56 +08:00
    并行抓取不需要多线程, 用stream里的nonblock和select做就可以

    或者可以试试这个 https://github.com/hightman/pspider
    qiuai
        10
    qiuai  
    OP
       2013-06-08 15:44:53 +08:00
    @lyjyiran 谢谢~我看看~~
    txlty
        11
    txlty  
       2013-06-08 16:43:00 +08:00
    <?php
    $t=array();$ch=array();
    $t[]='http://www.baidu.com'; //探针1
    $t[]='http://www.sogou.com'; //探针2
    $t[]='http://www.yodao.com'; //探针3
    $t[]='http://www.baidu.com'; //探针4
    $t[]='http://www.sogou.com'; //探针5
    for($i=0;$i<5;$i++){
    $ch[$i] = curl_init();
    curl_setopt($ch[$i], CURLOPT_URL, $t[$i]);
    curl_setopt($ch[$i], CURLOPT_HEADER, 0);
    curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, 0);

    }
    $mh = curl_multi_init();
    for($i=0;$i<5;$i++){
    curl_multi_add_handle($mh,$ch[$i]);
    }
    $running=null;
    do {
    usleep(10000);
    $result.= curl_multi_exec($mh,$running);
    } while ($running > 0);
    echo $result;
    ?>
    alsotang
        12
    alsotang  
       2013-06-08 17:03:30 +08:00
    异步抓或者多线程啊。
    qiuai
        13
    qiuai  
    OP
       2013-06-08 18:18:26 +08:00
    @txlty 这个....一万次?
    @alsotang 就是不知道怎么实现...
    fmfsaisai
        14
    fmfsaisai  
       2013-06-08 18:22:01 +08:00
    @qiuai 忍不住吐个槽,人家好心连代码都帮你实现了,你好歹认真读一下人家的代码吧
    usleep(10000);你可以去看看手册usleep这个函数是干什么用的
    直接上来一句就“一万次”....真是让人感觉无力。。。
    qiuai
        15
    qiuai  
    OP
       2013-06-08 18:24:05 +08:00
    @fmfsaisai =.=sorry.我之前百度的时候看到了一段跟这个差不多的代码.介绍里说是执行了一万次什么的...我PHP只是入门...

    @txlty 对不起...我马上去测试一下...谢谢.
    darasion
        16
    darasion  
       2013-06-08 18:25:21 +08:00
    php 有多进程.

    比如:
    pcntl_fork();
    http://www.php.net/manual/en/function.pcntl-fork.php

    另外楼上各种办法基本都可以试试。
    qiuai
        17
    qiuai  
    OP
       2013-06-08 18:28:31 +08:00
    @darasion 嗯.好的...我正在测试 @txlty 的方法中
    fmfsaisai
        18
    fmfsaisai  
       2013-06-08 18:30:37 +08:00
    @qiuai 这段代码对于你的需求来说应该还是有点问题的,如果还没发现,建议可以修改一下usleep的数值,比如改成0;
    qiuai
        19
    qiuai  
    OP
       2013-06-08 18:31:39 +08:00
    @fmfsaisai 执行以后出现了一些多余的数字.-1-1-1-1-1-1-1-1-1-100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000-100-100000-100-10
    qiuai
        20
    qiuai  
    OP
       2013-06-08 18:33:06 +08:00
    @fmfsaisai 改成0也是会有很多不知道是什么意思的数字...
    fmfsaisai
        21
    fmfsaisai  
       2013-06-08 18:37:17 +08:00
    @qiuai
    建议你先读读官方手册,result返回的只是一个状态码
    http://php.net/manual/en/function.curl-multi-exec.php

    如果想要获取返回的结果,(在所有exec执行完毕以后)要用
    http://www.php.net/manual/en/function.curl-multi-getcontent.php

    参数就用代码里循环的那个$ch[$i]
    for($i=0;$i<5;$i++){
    echo curl_multi_getcontent($ch[$i]);
    }

    usleep改成0就是减少阻塞时间,对结果没有任何影响。
    7sj525bL0Wy7FOx9
        22
    7sj525bL0Wy7FOx9  
       2013-06-08 18:46:02 +08:00
    @qiuai 伸手党啊,多看看代码内容,自己测试下是哪里出的数字,再去看是哪个函数,再看看这个函数是什么用途,返回值等等,而不是等着别人回答啊亲,要自己多分析。
    qiuai
        23
    qiuai  
    OP
       2013-06-08 19:06:38 +08:00
    @fmfsaisai @LionXen 知道了.我先去研究研究...
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5940 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 904ms · UTC 01:59 · PVG 09:59 · LAX 17:59 · JFK 20:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.