0

我想向同一域上的不同页面发送约 50 个请求,然后,我使用 DOM 对象来获取文章的 url。

问题是这个数量的请求需要超过 30 秒。

for ($i = 1; $i < 51; $i++)
{
    $url = 'http://example.com/page/'.$i.'/';             

    $client = new Zend_Http_Client($url);
    $response = $client->request();
    $dom = new Zend_Dom_Query($response); // without this two lines, execution is also too long
    $results = $dom->query('li');         //
}

有什么办法可以加快这个速度吗?

4

2 回答 2

1

我想不出加快速度的方法,但是如果您担心的话,可以增加 PHP 中的超时限制:

for($i=1; $i<51; $i++) {
  set_time_limit(30);    //This restarts the timer to 30 seconds starting now
  //Do long things here
}
于 2013-07-03T12:37:44.250 回答
1

这是设计上的一般问题 - 而不是代码本身。如果您正在执行超过 50 个项目的 for 循环,每个项目都打开一个对远程 uri 的请求,那么事情会变得非常慢,因为每个请求都等到来自远程 uri 的响应。例如:完成一个请求大约需要 0.6 秒,将其乘以 50,您将获得 30 秒的执行时间!

另一个问题是大多数网络服务器将每个客户端的(打开的)连接限制为特定数量。因此,即使您能够同时执行 50 个请求(您目前还没有),事情也不会显着加快。

在我的选择中,只有一个解决方案(没有任何深入的更改):更改每次执行的请求数量。从例如每个(脚本)调用仅 5 到 10 个块制作块,并通过外部调用触发它们(例如,通过 cron 运行它们)。

Todo:构建一个包装函数,该函数能够将其当前运行的状态(“我上次运行时确实请求了 1-10,所以现在我必须调用 11-20)到文件或数据库中并通过以下方式触发此函数一个cron。

用于更好声明的示例代码(未经测试);

[...]

private static $_chunks = 10; //amout of calls per run

public function cronAction() {

    $lastrun = //here get last run parameter saved from local file or database

    $this->crawl($lastrun);

}

private function crawl($lastrun) {

    $limit = $this->_chunks + $lastrun;

    for ($i = $lastrun; $i < limit; $i++)
    {
        [...] //do stuff here
    }

    //here set $lastrun parameter to new value inside local file / database

}

[...]
于 2013-07-04T09:40:44.670 回答