之前做微信登录开发时候,发现微信头像图片没有后缀名,传统的图片抓取方式不奏效,需要特殊的抓取处理。所以,后来将各种情况结合起来,封装成一个类,分享出来。

创建项目

作为演示,我们在www根目录创建项目grabimg,创建一个类GrabImage.php和一个index.php。

编写类代码

我们定义一个和文件名相同的类:GrabImage

class GrabImage{}

属性

接下来定义几个需要使用的属性。

1、首先定义一个需要抓取的图片地址:$img_url

2、再定义一个$file_name用来存储文件的名称,但是不携带拓展名,因为可能涉及到拓展名更换,所以这里拆开定义

3、紧接着就是拓展名$extension

4、然后我们定义一个$file_dir,该属性的作用是,远程图片抓取到本地后所存储的目录,一般相对于PHP入口文件所在的位置作为起始。但是该路径一般不保存到数据库。

5、最后我们定义一个savedir,顾名思义,该路径是用来直接保存的数据库的目录。这里说明下,我们不直接存储文件保存路径到数据库,一般是为了之后如果系统迁移,方便更换路径做准备。我们这里的save_dir,顾名思义,该路径是用来直接保存的数据库的目录。这里说明下,我们不直接存储文件保存路径到数据库,一般是为了之后如果系统迁移,方便更换路径做准备。我们这里的saved​ir,顾名思义,该路径是用来直接保存的数据库的目录。这里说明下,我们不直接存储文件保存路径到数据库,一般是为了之后如果系统迁移,方便更换路径做准备。我们这里的save_dir一般为日期 + 文件名,如果需要使用时候取出,在前方拼上所需要的路径。

方法

属性弄完了,接下来我们正式开始抓取工作。

首先我们定义一个对外开放的方法getInstances用来获取一些数据,比如抓取图片地址,和本地保存路径。同时将其放入属性中。

public function getInstances($img_url , $base_dir){$this->img_url = $img_url;$this->save_dir = date("Ym").'/'.date("d").'/'; // 比如:201610/19/$this->file_dir = $base_dir.'/'.$this->save_dir.'/'; // 比如:./uploads/image/2016/10/19/}

图片保存路径拼接完成,下面我们要注意一个问题,目录是否存在。日期在一天天走,但是目录并不会自动创建。所以,在保存图片之前,首先需要检查一下,如果当前目录不存在我们需要即时创建。

我们创建设置目录方法setDir。属性我们设置了private,安全

/*** 检查图片需要保持的目录是否存在* 如果不存在,则立即创建一个目录* @return bool*/private function setDir(){if(!file_exists($this->file_dir)){mkdir($this->file_dir,0777,TRUE);}$this->file_name = uniqid().rand(10000,99999);// 文件名,这里只是演示,实际项目中请使用自己的唯一文件名生成方法return true;

接下来就是抓取核心代码

第一步,解决一个问题,我们需要抓取的图片可能没有后缀名。按照传统的抓取方法,先抓取图片,然后截取后缀名的方案不可行。

我们必须通过其它方法来获得图片类型。办法就是从文件流信息中获取文件头信息,从而判断文件mime信息,就可以知道文件后缀名。

为了方便,先定义一个mime和文件拓展名映射。

$mimes=array('image/bmp'=>'bmp','image/gif'=>'gif','image/jpeg'=>'jpg','image/png'=>'png','image/x-icon'=>'ico');

这样,当我获取了类型是image/gif的时候,我就可以知道是.gif图片了。

利用php函数get_headers,获取文件流头信息。当其值不为false时候我们将其赋值给变量$headers

取出Content-Type的值即为mime的值。

if(($headers=get_headers($this->img_url, 1))!==false){// 获取响应的类型$type=$headers['Content-Type'];}

使用上面我们定义的映射表,我们可以很轻松的获取后缀名。

$this->extension=$mimes[$type];

当然上面获取的$type,可能不存在我们的映射表中,说明这种类型文件并不是我们想要的,直接抛弃就好了,不用管它。

下面的步骤就和传统抓取文件一样。

$file_path = $this->file_dir.$this->file_name.".".$this->extension;// 获取数据并保存$contents=file_get_contents($this->img_url);if(file_put_contents($file_path , $contents)){// 这里返回出去的值是直接保存到数据库的路径 + 文件名,形如:201610/19/57feefd7e2a7aY5p7LsPqaI-lY1BF.jpgreturn $this->save_dir.$this->file_name.".".$this->extension;}

首先获取本地保图片存完整路径$file_path,接下来使用file_get_contents抓取数据,然后使用file_put_contents保存到刚刚的文件路径。

最后我们返回一个可以直接保存到数据库中的路径,而不是文件存储路径。

该抓取方法完整版是:

private function getRemoteImg(){// mime 和 扩展名 的映射$mimes=array('image/bmp'=>'bmp','image/gif'=>'gif','image/jpeg'=>'jpg','image/png'=>'png','image/x-icon'=>'ico');// 获取响应头if(($headers=get_headers($this->img_url, 1))!==false){// 获取响应的类型$type=$headers['Content-Type'];// 如果符合我们要的类型if(isset($mimes[$type])){$this->extension=$mimes[$type];$file_path = $this->file_dir.$this->file_name.".".$this->extension;// 获取数据并保存$contents=file_get_contents($this->img_url);if(file_put_contents($file_path , $contents)){// 这里返回出去的值是直接保存到数据库的路径 + 文件名,形如:201610/19/57feefd7e2a7aY5p7LsPqaI-lY1BF.jpgreturn $this->save_dir.$this->file_name.".".$this->extension;}}}return false;}

最后,为了简单,我们想在其他地方只要调用其中一个方法就可以完成抓取。所以,我们将抓取动作直接放入到getInstances中,在配置完路径后,直接抓取,所以,在初始化配置方法getInstances里新增代码。

if($this->setDir()){return $this->getRemoteImg();}else{return false;}

测试

我们去刚刚创建的index.php文件内试试。

<?phprequire_once 'GrabImage.php';$object = new GrabImage();$img_url = "http://www.bidianer.com/img/icon_mugs.jpg"; // 需要抓取的远程图片$base_dir = "./uploads/image"; // 本地保存的路径echo $object->getInstances($img_url , $base_dir);?>


完整代码

<?php/*** 抓取远程图片到本地,可以抓取不带有后缀的图片* @author YanYing <yanyinghq@163.com>* @link bidianer.com*/class GrabImage{/*** @var string 需要抓取的远程图片的地址* 例如:http://www.bidianer.com/img/icon_mugs.jpg* 有一些远程文件路径可能不带拓展名* 形如:http://www.xxx.com/img/icon_mugs/q/0*/private $img_url;/*** @var string 需要保存的文件名称* 抓取到本地的文件名会重新生成名称* 但是,不带拓展名* 例如:57feefd7e2a7aY5p7LsPqaI-lY1BF*/private $file_name;/*** @var string 文件的拓展名* 这里直接使用远程图片拓展名* 对于没有拓展名的远程图片,会从文件流中获取* 例如:.jpg*/private $extension;/*** @var string 文件保存在本地的目录* 这里的路径是PHP保存文件的路径* 一般相对于入口文件保存的路径* 比如:./uploads/image/201610/19/* 但是该路径一般不直接存储到数据库*/private $file_dir;/*** @var string 数据库保存的文件目录* 这个路径是直接保存到数据库的图片路径* 一般直接保存日期 + 文件名,需要使用的时候拼上前面路径* 这样做的目的是为了迁移系统时候方便更换路径* 例如:201610/19/*/private $save_dir;/*** @param string $img_url 需要抓取的图片地址* @param string $base_dir 本地保存的路径,比如:./uploads/image,最后不带斜杠"/"* @return bool|int*/public function getInstances($img_url , $base_dir){$this->img_url = $img_url;$this->save_dir = date("Ym").'/'.date("d").'/'; // 比如:201610/19/$this->file_dir = $base_dir.'/'.$this->save_dir.'/'; // 比如:./uploads/image/2016/10/19/return $this->start();}/*** 开始抓取图片*/private function start(){if($this->setDir()){return $this->getRemoteImg();}else{return false;}}/*** 检查图片需要保持的目录是否存在* 如果不存在,则立即创建一个目录* @return bool*/private function setDir(){if(!file_exists($this->file_dir)){mkdir($this->file_dir,0777,TRUE);}$this->file_name = uniqid().rand(10000,99999);// 文件名,这里只是演示,实际项目中请使用自己的唯一文件名生成方法return true;}/*** 抓取远程图片核心方法,可以同时抓取有后缀名的图片和没有后缀名的图片** @return bool|int*/private function getRemoteImg(){// mime 和 扩展名 的映射$mimes=array('image/bmp'=>'bmp','image/gif'=>'gif','image/jpeg'=>'jpg','image/png'=>'png','image/x-icon'=>'ico');// 获取响应头if(($headers=get_headers($this->img_url, 1))!==false){// 获取响应的类型$type=$headers['Content-Type'];// 如果符合我们要的类型if(isset($mimes[$type])){$this->extension=$mimes[$type];$file_path = $this->file_dir.$this->file_name.".".$this->extension;// 获取数据并保存$contents=file_get_contents($this->img_url);if(file_put_contents($file_path , $contents)){// 这里返回出去的值是直接保存到数据库的路径 + 文件名,形如:201610/19/57feefd7e2a7aY5p7LsPqaI-lY1BF.jpgreturn $this->save_dir.$this->file_name.".".$this->extension;}}}return false;}}

本文参考地址:https://www.php.cn/php-weizijiaocheng-434333.html

PHP抓取远程图片教程(包含不带后缀图片)相关推荐

  1. php图片截取后缀,PHP抓取远程图片(含不带后缀的)教程详解

    一.创建项目 作为演示,我们在www根目录创建项目grabimg,创建一个类GrabImage.php和一个index.php. 二.编写类代码 我们定义一个和文件名相同的类:GrabImage cl ...

  2. 百度UEditor编辑器关闭抓取远程图片功能(默认开启)

    2019独角兽企业重金招聘Python工程师标准>>> 这个坑娘的功能,开始时居然不知道如何触发,以为有个按钮,点击一下触发,翻阅了文档,没有发现,然后再网络上看到原来是复制粘贴非白 ...

  3. ueditor抓取远程图片php版,Ueditor百度编辑器远程抓取图片的开启与关闭

    前言 这几天一直被百度编辑器自动抓取远程图片的功能困扰.因为这个功能吧,总是时灵时不灵的.有时候会抓取远程图片,有时候又不会抓取远程图片.相信各位都有遇到过.本人对编辑器没有太多的了解,下面如果有讲错 ...

  4. php 模拟客户端访问,PHP通过伪造和模拟客户端COOKIE登陆来采集抓取远程网址

    平时开发中经常会遇到抓取某个页面内容,但是有时候某些页面需要登陆才能访问,最常见的就是论坛,这时候我们需要来使用curl模拟登陆. 以下讨论的是和伪造模拟客户端COOKIE登陆采集抓取远程网址相关的P ...

  5. php 抓取远程内容,php抓取远程网页内容简单示例

    本教程用php实现像asp里xmlhttp的功能一样,抓取远程网页内容. php有好多函数可以打开远程url读取内容.但采集推荐大家用fsockopen函数, 我们先来看一下fsockopen函数的语 ...

  6. #.NET分别以GET和POST方式抓取远程页面

    代码 引入命名空间 using System.IO; using System.Net; using System.Text; using System.Text.RegularExpressions ...

  7. gitlab 分支操作笔记\新建远程分支\抓取远程分支\复制远程\删除分支

    密码重新输入 git config --global http.emptyAuth true 1.不复制远程,直接新建远程分支.(非正规操作) git init //初始化 git remote ad ...

  8. 远程控制篇:抓取远程屏幕图像

    远程控制篇:抓取远程屏幕图像 {抓屏幕图像,保存为内存流--BMP流,压缩BMP流,JPG流,以及使用流} {在网络中传送BMP流和JPG流的速度没测试过} {BMP流的压缩是无损压缩} { 全局变量 ...

  9. 抓取app数据教程–fiddler抓包数据截取-薄荷app为例

    转载请注明出处:抓取app数据教程–fiddler抓包数据截取-薄荷app为例 准备工具 1.手机(安装有想要抓取数据app的iphone或者android) 2.fiddler抓包工具 安装fidd ...

最新文章

  1. TLU-Net:表面缺陷自动检测的深度学习方法
  2. windows10+Python3-如何安装numpy和matplotlib包
  3. Oculus软件完全支持三传感器室内跟踪
  4. PHP获取当前毫秒时间戳
  5. caxa电子图板2018中文版
  6. 高精度乘以低精度板子
  7. 那些年,我们追过的java8
  8. 用Python编写小工具下载OSM路网数据
  9. linux命令--VI命令详解(一)
  10. nodejs TCP server和TCP client如何进行数据交互
  11. 安卓APP_ 控件(7)——Toolbar栏目样式
  12. 【51单片机快速入门指南】4.4.1:python串口接收磁力计数据并进行最小二乘法椭球拟合
  13. 2021年五一杯数学建模A题(疫苗生产调度问题)详细分析
  14. service XXX does not support chkconfig(service报错)
  15. 计算机技术在农机上的应用,计算机视觉技术在农机自动化上的应用与优势分析.pdf...
  16. mysql ascii ord_MySQL ORD()函数使用实例介绍
  17. 数论 (大数,小费马定理,欧拉定理,威尔逊定理,快速数论变换(NNT)模版)...
  18. java 处理clob_java读取clob字段的几种方法
  19. 酷派大神9976A刷机
  20. MAC本地修改mysql数据库密码

热门文章

  1. Eclipse的switch workspace 选项中删除多余的workspace
  2. 解决校园内网“哆点软件”登录时出现“http://www.msftconnecttest.com/redirect 找不到应用程序”问题
  3. 集合的remove()和removeAll()的区别
  4. 项目监控过程的工作及作用
  5. Linux下设备树dts内容(详细)总结及示例解析
  6. 高斯分布 正态分布的推导
  7. iphone设置闹钟音乐_如何在iPhone上更改闹钟声音
  8. Vue项目快速输出到小程序、H5
  9. Garter最新中国超融合厂商格局权威报告对SmartX、深信服等提供专业点评
  10. 视频教程-SAP S4 HANA FICO COPC 产品成本计划-ERP