[PHP采集]curl抓取远程图片下载到本地

2019-11-16 16:44 3298 次阅读 PHP成长
前段时间用了steam上的一个桌面壁纸软件上面的壁纸简直让我欲罢不能,但是需要19块钱购买,懂的都懂。想要壁纸的图片文件结果壁纸软件是编译过的,网上有的小伙伴就说截屏百度,我百度了下,结果不尽人意。最后无奈之下试试谷歌(这里不讲怎么上谷歌,方法千千万,以后有机会再写出来,主要是怕被和谐,大家都懂),谷歌确实搜到了原图,高清大图无码,惊喜万分,这里就不吐槽某搜索引擎了。打开某网站,里面有很多高清大图然而……
![](https://skapi-1253927675.cos.ap-guangzhou.myqcloud.com/blog/201911/7d412227e8a55bb57ef63f0263534476.png)
大概就是这种,加载几分钟,速度非常慢,而且一个页面所有图片都是一起加载,这就有点蛋疼了,为了找几张图片容易吗。于是乎就想,如果把先把页面抓取出来,不显示图片把链接提出来,然后再把图片下载下来,这样应该要好些,不过手动下载那肯定太慢了。再加上我有php基础,何不研究一番,不过网上已经有很多教程了,但并没有一篇文章全都是我需要的。所以在这里就当记个笔记。这里我是用的curl,用cli模式运行,也就是php命令行模式,nginx都不用安装
```php
public function curlGet($url,$timeout = 120)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);//设置抓取的url
curl_setopt($curl, CURLOPT_HEADER, false);//设置头文件的信息作为数据流输出
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);//重定向
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_TIMEOUT,(int)$timeout);//设置超时时间
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);//
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);//不检查ssl证书
curl_getinfo($curl,CURLINFO_HTTP_CODE);//这里应该是获取http状态code
$data = curl_exec($curl);//执行命令
curl_close($curl);//关闭URL请求
return $data;//返回获得的数据
}
```
这是封装过后的get请求,我用post试了下,好像目标网站post获取不到信息,有可能是我获取姿势不对,也有可能是他只能get访问,这个curl函数也是非常强大的,可以模拟多线程,并发。这里呢,我还是建议不要用多线程,因为别人网站是大家访问的,你这开个多线程,把别人网站搞挂了就不好了,毕竟人家也没收钱。肯定服务器配置也不是很高,带宽也不大。尽量不要影响其他人正常使用。这里curl可以抓取一个页面后返回的是html得到代码拿到代码后需要拿取里面有用的信息。大概就是这种<img>标签
![](https://skapi-1253927675.cos.ap-guangzhou.myqcloud.com/blog/201911/0a4d868b28bbff8a872efbd1ed8a1f50.png)
这里用正则匹配
```php
echo '开始抓取['.$title.']的图片链接……'.PHP_EOL;
$image_rst = $this->curlGet($title_url);
$image_content = mb_convert_encoding($image_rst, 'UTF-8','UTF-8,GBK,GB2312,BIG5');
preg_match_all('/<img src=".*?"/',$image_content,$image_arr);
echo '成功抓取到['.count($image_arr[0]).']张图片链接……';
```
这里先用curlGet抓取页面然后把编码转utf8,虽然我对正则不是很熟练,大概就这么就可以匹配到图片了,但是$image_arr[0]里面才是图片链接数组可以打印出来看下
![](https://skapi-1253927675.cos.ap-guangzhou.myqcloud.com/blog/201911/f162944c5b0f47387845cf11864312a0.png)
那么拿到这数组了,就可以用字符串函数提取图片链接了,可以存数据库,但是需要下载的话这就要再次请求图片链接了
```php
echo '正在下载第['.($image_count+1).']张图片';
$image_start = strpos($v,'"')+1;
$image_end = strrpos($v,'"');
$image_url = substr($v,$image_start,$image_end-$image_start);
$download_rst = $this->curlGet($image_url);
if (strlen($download_rst) <= 220){
echo '下载失败';
}else{
if (file_put_contents($img_path.DS.$filename,$download_rst,false)){
echo '下载成功';
$image_count++;
}
}
```
这里curlGet请求图片链接获取到的应该是图片文件内容,用file_put_contents这个函数可以写入到文件,如果没有文件就生成文件,这样就可以下载到本地了
![](https://skapi-1253927675.cos.ap-guangzhou.myqcloud.com/blog/201911/dbce50b2fd0a8bdbdb83d4a4516ae8ee.png)