将图像作为数组获取时出现以下问题。在这段代码中,我试图检查搜索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;
}
}
$html = file_get_contents('https://www.everypixel.com/search?q='.$get_search.'&is_id=1&st=free');
除非www.everypixel.com服务器位于同一个LAN上(在这种情况下,压缩开销可能比在普通模式下传输速度慢),curl与CURLOPT_ENCODING应该比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方法意味着它遭受相同的Content-Length
问题这使得file_get_contents变慢。此外,所有图像都是按顺序下载的,并行下载它们应该快得多,可以用curl_multi api完成,但这样做是一项复杂的任务,我可以为你写一个例子,但我可以指出你一个例子:https://stackoverflow.com/a/54717579/1067003