Как получить изображения, используя file_get_contents в качестве массива - PullRequest
0 голосов
/ 19 апреля 2019

У меня следующая проблема с получением изображений в виде массива. В этом коде я пытаюсь проверить, существуют ли изображения для поиска 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;

  }

}

1 Ответ

0 голосов
/ 20 апреля 2019
$html = file_get_contents('https://www.everypixel.com/search?q='.$get_search.'&is_id=1&st=free');

, если только сервер www.everypixel.com не находится в той же локальной сети (в этом случае издержки сжатия могут быть медленнее, чем их передача в простом виде), curl с CURLOPT_ENCODING должен делать это быстрее, чем file_get_contents, и даже если он находится на то же самое значение lan, 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);

DOMDocument с getElementsByTagName ("img") и getAttribute ("src") должен быть быстрее, чем использование вашего регулярного выражения, поэтому сделайте это вместо:

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

и, возможно, самая медленная часть всего вашего кода, @getimagesize($match) внутри цикла, потенциально содержащего более 1000 URL-адресов, каждый вызов getimagesize () с URL-адресом заставляет php загружать изображение, и он использует метод file_get_contents, означающий, что он страдает из той же Content-Length проблемы, которая замедляет работу file_get_contents. Кроме того, все изображения загружаются последовательно, загрузка их параллельно должна быть намного быстрее, что можно сделать с помощью curl_multi api, но это сложная задача, и я могу написать пример для вас, но я могу указать вам на пример: https://stackoverflow.com/a/54717579/1067003

...