php抓取网站图片并保存本地服务器实例

 更新时间:2016年11月25日 15:40  点击:1776
本例子是使用了file_get_contents()函数来抓取图片内容然后再使用fopen保存到本地服务器了,然后再进行地址url替换这样就实现了一个完整的页面采集功能并保存地址到本地的做法了,下面来看看例子。

首先举个例子吧。 代码如下:

 代码如下 复制代码

<?php
$text=file_get_contents("http://www.111cn.net");
//取得所有img标签,并储存至二维阵列match

preg_match_all('/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg]))[\'|\"].*?[\/]?>/', $text, $match);

//打印出match
$houzhui = "./tp/".time().rand(10000,50000).".".png;
$yuanname =  getImage($match[1][2],$houzhui,tp);

//下载图片方法

function getImage($url,$filename='',$type=0){
if($url==''){return false;}
if($filename==''){
$ext=strrchr($url,'.');
if($ext!='.gif' && $ext!='.jpg'){return false;}
$filename=time().$ext;
}
//文件保存路径
if($type){
$ch=curl_init();
$timeout=5;
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
$img=curl_exec($ch);
curl_close($ch);
}else{
ob_start();
readfile($url);
$img=ob_get_contents();
ob_end_clean();
}
$size=strlen($img);
//文件大小
$fp2=@fopen($filename,'a');
fwrite($fp2,$img);
fclose($fp2);
return $filename;
}
?>

案例分析,核心代码如下

 代码如下 复制代码

$text=file_get_contents("http://www.111cn.net");

//取得所有img标签,并储存至二维阵列match

preg_match_all('/<[img|IMG].*?src=[\'|\"](.*?(?:[\.gif|\.jpg]))[\'|\"].*?[\/]?>/', $text, $match);

 这个正则就是直接获取所有图片不管是http或直接是/aa/aa.gif文件都会自动抓保存到地址了,不过这个会有一些问题图片地址未进行补全了,如我们一个 /a/a/a.gif这样我们是找不到图片的,必须是http://www.111cn.net /a/a/a.gif 这样才可以下载到了,所以我们有必要进行两个处理方法一个是在原基本上处理

 代码如下 复制代码

//文件保存路径
if($type){
$ch=curl_init();
$timeout=5;
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
$img=curl_exec($ch);
curl_close($ch);

上面的$url参数进行地址补全,如我采集的是http://www.111cn.net那么地址自动补全为绝对路径了,另一种办法就是使用修改正则表达式

 代码如下 复制代码

preg_match_all("/(src|SRC)=[\"|'| ]{0,}(http:\/\/(.*)\.(gif|jpg|jpeg|png))/isU",$body,$img_array); 

这样就只获取以http开头的图片文件了哦。

php_sapi_name函数是一个可以返回php所运行的web服务器环境的字符串,下面我们来看两个关于php_sapi_name函数测试出php运行环境的例子。


代码:

<?php
    echo php_sapi_name();
?>

在apache环境下面输出的结果是“apache2handler”;

在cgi模式下输出的结果是“cgi-fcgi”

要是在命令行模式下面运行的话,那么输出的结果是:”cli”

如果在nginx中运行就是 nginx字符了。

不管是文件还是图片批量上传我们第一个是在html中做name=userfile[]这种数组变量,在php接受中我们做for ($_i=0; $_i<$_cont; $_i++)遍历这样就可以实现文件批量上传了,下面我来看一个实例

例子

 代码如下 复制代码

<?php
session_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>PHP文件批量上传</title>
<style>
* {margin:0; padding:0; list-style:none;}
.content {width:400px; height:auto; margin:0 auto; margin-top:60px; padding-bottom:30px; background:#ffd3b6; border:dashed 1px #f90}
.content h1 { width:400px; height: 30px; line-height:30px; text-align:center; font-family:"微软雅黑"; font-size:14px; color:#000}
.content .error {width:300px; height:auto; line-height:30px; text-align:center; margin:0 auto; color:#f00}
.content .con {width:340px; height:auto; margin:0 auto; font-size:12px;}
.content #file { width:280px; height:20px; border:solid 1px #ccc; background:#fff; margin:10px 0px 6px 0; font-size:12px;}
.content #send { width:60px; height:22px; border:solid 1px #ccc; background:#fff; font-size:12px; margin-top:10px;}
</style>
<script type="text/javascript" src="js/jquery.js"></script>
<script>
$(document).ready(function() {
$('#cont').val($('.file #file').size());
$('#send').eq(0).click(function() {
var filesize=$('.file #file').size();
$('.file').append("<input type='file' name='userfile[]' id='file'/>");
$('#cont').val(filesize+1);
});
});
</script>
</head>
<body>
<div>
<h1>PHP文件批量上传</h1>
<div>
<div>
<?php
if ($_GET['up']==up) {
//防止重复提交
if ($_SESSION['file']==$_GET['irand']) {
$_cont=intval($_POST['cont']);   //将file框总数接收并转换成整型
$_size=20000;                    //设置限制文件大小
$_dir='pdir/';                   //文件保存目录
function size($_size) {
//判断文件大小是否大于1024bit 如果大于,则将大小取值为KB,以此类推
if ($_size>1024*1024) {
return round($_size/1024/1024,2).' MB';
}else if ($_size>1024) {
$_size=$_size/1024;
return ceil($_size).'KB';
}else {
return $_size.' bit';
}
}
//设置上传图片的类型,设置图片上传大小
$_upfiles = array('image/jpeg','image/pjpeg','image/png','image/x-png','image/gif');
//利用for循环上传文件
for ($_i=0; $_i<$_cont; $_i++) {
if (is_array($_upfiles)) {
if (!in_array($_FILES['userfile']['type'][$_i],$_upfiles)) {
exit('请上传格式为:jpg,png,gif的文件<br /><a href="pupload.php">返回</a>');
}
}
//判断文件大小
if ($_FILES['userfile']['size'][$_i]>$_size) {
exit('上传文件不能超过:'.size($_size));
}
//检测文件是否已经上传
if ($_FILES['userfile']['error'][$_i]>0) {
switch ($_FILES['userfile']['error'][1]) {
case 1: echo '上传的文件超过了 php.ini 中 upload_max_filesize 选项限制的值';
break;
case 2: echo '上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值';
break;
case 3: echo '文件只有部分被上传';
break;
case 4: echo '没有文件被上传';
break;
case 6: echo '找不到临时文件夹';
break;
case 7: echo '文件写入失败';
break;
}
exit;
}
//获取文件扩展名
if (!is_dir($_dir)) {
mkdir($_dir,0700);
}
//生成随笔数
$_rand=mt_rand(0,100000);
//获取文件扩展名
$_n=explode('.',$_FILES['userfile']['name'][$_i]);  //将文件名分割
$_file_len=count($_n);         //返回数组长度
//确保获取的扩展名是最后一个.后面的
$_name=$_dir.time().'_'.$_rand.'.'.$_n[$_file_len-1];
//移动文件到指定的目录
if (is_uploaded_file($_FILES['userfile']['tmp_name'][$_i])) {
if (!@move_uploaded_file($_FILES['userfile']['tmp_name'][$_i],$_name)) {
exit('文件移动失败');
}else {
echo '文件上传成功<br />';
echo '文件路径:'.$_name.'<br />';
echo '文件大小:'.size(filesize($_name));
echo '<br /><a href="pupload.php">返回继续上传</a>';
}
}else {
exit('上传的临时文件不存在,无法将文件移动到指定文件夹');
}
}
//销毁session变量,有几种方法
//第一种,销毁所有session变量:session_destroy();
//第二种:销毁单个如:$_SESSION['file']=''
session_destroy();
exit;

}else {
exit('您已经提交过了,不能重复提交<br /><a href="pupload.php">返回</a>');
}
}
?>
</div>
<?php $_irand=mt_rand(0,1000000); $_SESSION['file']=$_irand; ?>
<form action="?up=up&irand=<?php echo $_irand; ?>" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="1000000" />
<input type="hidden" name="cont" value="" id="cont" />
<div>
<input type="file" name="userfile[]" id="file"/>
<input type="file" name="userfile[]" id="file"/>
<input type="file" name="userfile[]" id="file"/>
<input type="file" name="userfile[]" id="file"/>
</div>
<br />
<input type="button" name="send" value=" 添加一个 " id="send"/>
<input type="submit" name="send" value=" 点击上传 " id="send"/>
</form>
</div>
</div>
</body>

核心原理分析

在多文件上传中我们前台最重要的是

 代码如下 复制代码

<input type="file" name="userfile[]" id="file"/>
<input type="file" name="userfile[]" id="file"/>
<input type="file" name="userfile[]" id="file"/>
<input type="file" name="userfile[]" id="file"/>

这几行代码有细节的朋友会发现name="userfile[]"了,这个是以数组存储了,这样我们如果使用js也可以这样增加<input type="file" name="userfile[]" id="file"/>就可以了,那么在php是如何获取的呢

在多文件上传中php处理是一个关键

 代码如下 复制代码

for ($_i=0; $_i<$_cont; $_i++) {
if (is_uploaded_file($_FILES['userfile']['tmp_name'][$_i])) {
if (!@move_uploaded_file($_FILES['userfile']['tmp_name'][$_i],$_name)) {
exit('文件移动失败');
}else {
echo '文件上传成功<br />';
echo '文件路径:'.$_name.'<br />';
echo '文件大小:'.size(filesize($_name));
echo '<br /><a href="pupload.php">返回继续上传</a>';
}
}

这里显示很简单我们会看到有一个for,for就是遍历数组,遍历userfile[]数组,然后再由$_FILES['userfile']['tmp_name'][$_i]来获取不同文件图片再进行上传即可,注意[$_i]就是你的多文件上传项了,只是保存在了数组中。

我们在很多社区网站在登录口都有一个下次自动登录选项,如果我们选中了,下次进入网站就会自动登录了,那么下次自动登录是如何实现的呢?下面一聚教程小编就来与大家一起参考参考吧。

你会发现, 只要登录的时候勾选上这个框框(ps: 你的提示文字最好使用label+for), 即使你关闭浏览器再重新打开还是"已经登录的状态", 可能你也知道, 大多网站都是用session记录标识, 因为使用cookie记录不太安全, 可以被伪造, 那么session关闭浏览器会清空, 那还乍的记录标识呢? 嘎嘎, 接着往下看
session+cookie验证登录
大概的思路是在登录成功后, 记录session标识, 并根据相关参数写入cookie, 当然不会包含重要信息, 每次用户刷新页面, 会进行session判定, 如果没有, 则进行cookie判定, 如果正确则查库并写入session,大概伪代码是这样的:
每个页面初始化
开启session;

if(session存在){
    //已经登录
} else {
    if(指定cookie存在){
        //解密cookie
        if(匹配成功){
            //查询数据库
            if(有这个用户){
                //写入session, 这里是否还用更新cookie信息你说了算
            } else {
                //假的也想进我的站?
            }
        } else {
            //小样, 还想伪造 cookie? 嘎嘎
        }
    } else {
        //这里认为没有登录
    }
}

//这里已经知道用户登录的状态了
登录页面埋点
开启session;

if(各种表单验证通过){
    //写入session, 并提取uid,uname等不敏感信息再加自己的密钥生成唯一的token码, 用base64方式写入cookie, 这里为了让重启浏览器或者session过期后使用
}
但是你有没有发现, 如果为一个正常的用户, 在没有登录状态下, 上面初始化代码会在每个页面进行判定, 感觉不太帅, 且可能被别人伪造cookie, 如果站内涉及到$方面的事就更不好了, 于是改之:
session分权限等级方式
我们设置session标识, 0为未登录, 1为已登录, 2为cookie方式登录(这样就可以针对这样的用户进行再次验证), 然后我们需要改我们的伪代码.
页面初始化
开启session;

if(session存在){
    if(session > 0){
        //如果>0则说明已登录
    } else {
        //这里说明没有登录, 这个状态码是cookie验证没通过时留下的
    }
} else {
    //这里验证session不存在, 但可能cookie存在, 所以需要验证
    if(cookie存在){
        //这里进行解密
        if(成功){
            //查数据库
            if(成功){
                //session = 2, 为啥=2? 因为打上标识说明这次的登录方式是使用cookie验证登录的, 以方便在进行安全操作的时候再次验证
            } else {
                // session = 0
            }
        } else {
            //session = 0
        }
    } else {
        //cookie不存在的话视为没有登录, 这里把session标识 = 0, 以方便下次验证
    }
}
登录页面埋点
开启session;

if(各种表单验证通过){
    // session = 1, 打上标识说明是正常登录方式, 并生成token存入cookie以便下次使用
}
重要操作时再次验证, 比如: 交易等
开启session;

if(session===2){
    //弹出登录层 或者 跳转到登录页面再次验证, 是不是觉得跟taobao.com很像, 嘎嘎
}
致此验证完比, 当然实际使用哪种方式对token进行加密视项目情况而定, 但建议别使用敏感信息, 因为cookie你懂的...
你可能会想到这些问题
问: 清空cookie后这种方式就不行了?
答: 是的, 目前再主流的站, 只要你把缓存清空, 这里缓存包括任何, 比如 cookie, localStorage, sessionStorage, userDB, Web SQL, IndexdDB等, 你再重启浏览器, 我就不信你还是登录状态...(ps: 什么, 真的还是? 请留言反馈给我, 谢谢)
问: 这样岂不是知道cookie就可以直接登录?
答: 理论上是的, 只要用户知道你的加密方式, 写入个cookie理论是ok的, 但重要的地方建议登录再次验证, 当然只能说你点被...
问: 我复制某人的cookie岂不是就直接登录了?
答: 理论上还真是, 这可能就涉及到注入,攻击啥的了, 那如果这样的话, 要不是把浏览器相关信息+系统相关信息也加密到token里啊, 解密的时候再进行浏览器判断... 感觉好复杂啊...

下面整理了两个可以在一个字符串中任意位置插入一段字符串了,有两个函数一个是在指定位置,一个是在任意位置了都非常的不错,希望对各位会带来帮助哦。

原理也非常的简单我们只要指定位置然后遍历字符再判断位置然后把字符分开再把新字符push 进入再组成新的字符即可。

例子

 代码如下 复制代码

$str='字符串';

$AllNum = mb_strlen($str,'gbk').'<br>';
echo $AllNum;
$array=array();
$i=0;
$num=10;
for ($i;$i<$AllNum/66;$i++){
 
 $start=66*$i;
 
 $array[$i] = mb_substr($str,$start,66,'GB2312').'-----';//每66个字后面添加一个‘--------’
}
foreach ($array as $a)
{
 echo $a;
}

例子2

 代码如下 复制代码

<?php
//插入一段字符串
function str_insert($str, $i, $substr)
{
for($j=0; $j<$i; $j++){
$startstr .= $str[$j];
}
for ($j=$i; $j<strlen($str); $j++){
$laststr .= $str[$j];
}
$str = ($startstr . $substr . $laststr);
return $str;
}
?>

[!--infotagslink--]

相关文章

  • 使用PHP+JavaScript将HTML页面转换为图片的实例分享

    这篇文章主要介绍了使用PHP+JavaScript将HTML元素转换为图片的实例分享,文后结果的截图只能体现出替换的字体,也不能说将静态页面转为图片可以加快加载,只是这种做法比较interesting XD需要的朋友可以参考下...2016-04-19
  • C#从数据库读取图片并保存的两种方法

    这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
  • Photoshop古装美女图片转为工笔画效果制作教程

    今天小编在这里就来给各位Photoshop的这一款软件的使用者们来说说把古装美女图片转为细腻的工笔画效果的制作教程,各位想知道方法的使用者们,那么下面就快来跟着小编一...2016-09-14
  • Python 图片转数组,二进制互转操作

    这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
  • php抓取网站图片并保存的实现方法

    php如何实现抓取网页图片,相较于手动的粘贴复制,使用小程序要方便快捷多了,喜欢编程的人总会喜欢制作一些简单有用的小软件,最近就参考了网上一个php抓取图片代码,封装了一个php远程抓取图片的类,测试了一下,效果还不错分享...2015-10-30
  • jquery左右滚动焦点图banner图片鼠标经过显示上下页按钮

    jquery左右滚动焦点图banner图片鼠标经过显示上下页按钮...2013-10-13
  • 利用JS实现点击按钮后图片自动切换的简单方法

    下面小编就为大家带来一篇利用JS实现点击按钮后图片自动切换的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-10-25
  • Photoshop枪战电影海报图片制作教程

    Photoshop的这一款软件小编相信很多的人都已经是使用过了吧,那么今天小编在这里就给大家带来了用Photoshop软件制作枪战电影海报的教程,想知道制作步骤的玩家们,那么下面...2016-09-14
  • js实现上传图片及时预览

    这篇文章主要为大家详细介绍了js实现上传图片及时预览的相关资料,具有一定的参考价值,感兴趣的朋友可以参考一下...2016-05-09
  • 分享一段php获取linux服务器状态的代码

    简单的php获取linux服务器状态的代码,不多说-直接上函数:复制代码 代码如下:function get_used_status(){ $fp = popen('top -b -n 2 | grep -E "^(Cpu|Mem|Tasks)"',"r");//获取某一时刻系统cpu和内存使用情况 $rs =...2014-05-31
  • python opencv通过4坐标剪裁图片

    图片剪裁是常用的方法,那么如何通过4坐标剪裁图片,本文就详细的来介绍一下,感兴趣的小伙伴们可以参考一下...2021-06-04
  • 使用PHP下载CSS文件中的图片的代码

    共享一段使用PHP下载CSS文件中的图片的代码 复制代码 代码如下: <?php //note 设置PHP超时时间 set_time_limit(0); //note 取得样式文件内容 $styleFileContent = file_get_contents('images/style.css'); //not...2013-10-04
  • Springboot+TCP监听服务器搭建过程图解

    这篇文章主要介绍了Springboot+TCP监听服务器搭建过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-10-28
  • PHP swfupload图片上传的实例代码

    PHP代码如下:复制代码 代码如下:if (isset($_FILES["Filedata"]) || !is_uploaded_file($_FILES["Filedata"]["tmp_name"]) || $_FILES["Filedata"]["error"] != 0) { $upload_file = $_FILES['Filedata']; $fil...2013-10-04
  • 微信小程序如何获取图片宽度与高度

    这篇文章主要给大家介绍了关于微信小程序如何获取图片宽度与高度的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-10
  • C#中图片旋转和翻转(RotateFlipType)用法分析

    这篇文章主要介绍了C#中图片旋转和翻转(RotateFlipType)用法,实例分析了C#图片旋转及翻转Image.RotateFlip方法属性的常用设置技巧,需要的朋友可以参考下...2020-06-25
  • 服务器 UDP端口占用几千个的解决办法

    前一段时间使用NetStat命令查看服务器端口时,发现服务器udp端口开放了好多,最少在1000个以上,当时事情比较多,没有管它,今天终于有点时间,仔细检查了一下,排除了这个问题. ...2016-01-27
  • ps怎么制作图片阴影效果

    ps软件是现在很多人比较喜欢的,有着非常不错的使用效果,这次文章就给大家介绍下ps怎么制作图片阴影效果,还不知道制作方法的赶紧来看看。 ps图片阴影效果怎么做方法/...2017-07-06
  • OpenCV如何去除图片中的阴影的实现

    这篇文章主要介绍了OpenCV如何去除图片中的阴影的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-29
  • C#将图片和字节流互相转换并显示到页面上

    本文主要介绍用C#实现图片转换成字节流,字节流转换成图片,并根据图片路径返回图片的字节流,有需要的朋友可以参考下...2020-06-25