【问题标题】:How to get images using file_get_contents as array如何使用 file_get_contents 作为数组获取图像
【发布时间】:2019-09-09 23:59:54
【问题描述】:

将图像作为数组获取时遇到以下问题。 在这段代码中,我试图检查搜索图像是否存在 Test 1 - 如果存在,则显示,如果不存在,则尝试使用 Test 2 就是这样。当前的代码可以做到,但速度非常慢。

这个if (sizeof($matches[1]) > 3) { 因为这个3 有时会在被抓取的网站上包含广告,所以这是我安全的跳过它的方法。

我的问题是如何加快下面的代码以更快地获得if (sizeof($matches[1]) > 3) {?我相信这会让代码变得很慢,因为这个数组可能包含多达 1000 张图片

$get_search = 'Test 1';

$html = file_get_contents('https://www.everypixel.com/search?q='.$get_search.'&is_id=1&st=free');
preg_match_all('|<img.*?src=[\'"](.*?)[\'"].*?>|i', $html, $matches);

if (sizeof($matches[1]) > 3) {
  $ch_foreach = 1;
}

if ($ch_foreach == 0) {

    $get_search = 'Test 2';

  $html = file_get_contents('https://www.everypixel.com/search?q='.$get_search.'&is_id=1&st=free');
  preg_match_all('|<img.*?src=[\'"](.*?)[\'"].*?>|i', $html, $matches);

  if (sizeof($matches[1]) > 3) {
     $ch_foreach = 1;
  }

}

foreach ($matches[1] as $match) if ($tmp++ < 20) {

  if (@getimagesize($match)) {

    // display image
    echo $match;

  }

}

【问题讨论】:

  • 你错了,这里检查数组的大小不是性能问题,$ch_foreach = 1; 也不是性能问题。这段代码可能比较慢的部分是 HTTP 获取和正则表达式执行。要优化 http 获取,切换到 curl 并使用 CURLOPT_ENCODING(甚至更快,使用更新守护进程实现本地缓存),并优化 html 解析,切换到使用 DOMDocument 和 DOMXPath 解析,而不是使用正则表达式解析。

标签: php curl file-get-contents


【解决方案1】:
$html = file_get_contents('https://www.everypixel.com/search?q='.$get_search.'&is_id=1&st=free');

除非 www.everypixel.com 服务器在同一个 LAN 上(在这种情况下,压缩开销可能比直接传输它要慢),使用 CURLOPT_ENCODING 的 curl 应该比 file_get_contents 更快,即使它在相同的局域网,curl 应该比 file_get_contents 快,因为 file_get_contents 一直读取直到服务器关闭连接,但 curl 一直读取直到读取 Content-Length 字节,这比等待服务器关闭套接字要快,所以改为这样做:

$ch=curl_init('https://www.everypixel.com/search?q='.$get_search.'&is_id=1&st=free');
curl_setopt_array($ch,array(CURLOPT_ENCODING=>'',CURLOPT_RETURNTRANSFER=>1));
$html=curl_exec($ch);

关于你的正则表达式:

preg_match_all('|<img.*?src=[\'"](.*?)[\'"].*?>|i', $html, $matches);

带有 getElementsByTagName("img") 和 getAttribute("src") 的 DOMDocument 应该比使用正则表达式更快,所以改为这样做:

$domd=@DOMDocument::loadHTML($html);
$urls=[];
foreach($domd->getElementsByTagName("img") as $img){
    $url=$img->getAttribute("src");
    if(!empty($url)){
        $urls[]=$url;
    }
}

可能是整个代码中最慢的部分,@getimagesize($match) 在一个可能包含超过 1000 个 url 的循环中,每次使用 url 调用 getimagesize() 都会使 php 下载图像,并且它使用 file_get_contents 方法,这意味着它会受到影响来自使 file_get_contents 变慢的同一 Content-Length 问题。此外,所有图像都是按顺序下载的,并行下载它们应该更快,这可以使用 curl_multi api 完成,但这样做是一项复杂的任务,我 cba 为你写了一个例子,但我可以指出你一个例子:https://stackoverflow.com/a/54717579/1067003

【讨论】:

    猜你喜欢
    • 2012-09-16
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多