PHP采集类Snoopy抓取图片实例


Posted in PHP onJune 19, 2014

用了两天php的Snoopy这个类,发现很好用。获取请求网页里面的所有链接,直接使用fetchlinks就可以,获取所有文本信息使用fetchtext(其内部还是使用正则表达式在进行处理),还有其它较多的功能,如模拟提交表单等。

使用方法:

先下载Snoopy类,下载地址:http://sourceforge.net/projects/snoopy/
先实例化一个对象,然后调用相应的方法即可获取抓取的网页信息

include 'snoopy/Snoopy.class.php';

    

$snoopy = new Snoopy();

    

$sourceURL = "https://3water.com";

$snoopy->fetchlinks($sourceURL);

    

$a = $snoopy->results;

它并没有提供获取网页中所有图片地址的方法,自己有个需求是要获取一个页面中所有文章列表中图片地址。然后自己就写了一个,主要还是正则那里匹配重要。

//匹配图片的正则表达式

 $reTag = "/<img[^s]+src="(http://[^"]+).(jpg|png|gif|jpeg)"[^/]*/>/i";

因为需求比较特殊,只需要抓取写死htp://开头的图片(外站的图片可能使得了防盗链,想先抓取到本地)

1.抓取指定网页,并筛选出预期的所有文章地址;

2.循环抓取第一步中的文章地址,然后使用匹配图片的正则表达式进行匹配,获取页面中所有符合规则的图片地址;

3.根据图片后缀和ID(这里只有gif、jpg)保存图片---如果此图片文件存在,先将其删除再保存。

<meta http-equiv='content-type' content='text/html;charset=utf-8'>

<?php

    include 'snoopy/Snoopy.class.php';

    

    $snoopy = new Snoopy();

    

    $sourceURL = "http://xxxxx";

    $snoopy->fetchlinks($sourceURL);

    

    $a = $snoopy->results;

    $re = "/d+.html$/";

    

    //过滤获取指定的文件地址请求

    foreach ($a as $tmp) {

        if (preg_match($re, $tmp)) {

            getImgURL($tmp);

        }

    }

    

    function getImgURL($siteName) {

        $snoopy = new Snoopy();

        $snoopy->fetch($siteName);

        

        $fileContent = $snoopy->results;

        

        //匹配图片的正则表达式

        $reTag = "/<img[^s]+src="(http://[^"]+).(jpg|png|gif|jpeg)"[^/]*/>/i";

        

        if (preg_match($reTag, $fileContent)) {

            $ret = preg_match_all($reTag, $fileContent, $matchResult);

            

            for ($i = 0, $len = count($matchResult[1]); $i < $len; ++$i) {

                saveImgURL($matchResult[1][$i], $matchResult[2][$i]);

            }

        }

    }

    

    function saveImgURL($name, $suffix) {

        $url = $name.".".$suffix;

        

        echo "请求的图片地址:".$url."<br/>";

        

        $imgSavePath = "E:/xxx/style/images/";

        $imgId = preg_replace("/^.+/(d+)$/", "\1", $name);

        if ($suffix == "gif") {

            $imgSavePath .= "emotion";

        } else {

            $imgSavePath .= "topic";

        }

        $imgSavePath .= ("/".$imgId.".".$suffix);

        

        if (is_file($imgSavePath)) {

            unlink($imgSavePath);

            echo "<p style='color:#f00;'>文件".$imgSavePath."已存在,将被删除</p>";

        }

        

        $imgFile = file_get_contents($url);

        $flag = file_put_contents($imgSavePath, $imgFile);

        

        if ($flag) {

            echo "<p>文件".$imgSavePath."保存成功</p>";

        }

    }

?>

在使用php抓取网页:内容、图片、链接的时候,我觉得最重要的还是正则(根据抓取的内容和指定的规则获取想要的数据),思路其实都比较简单,用到的方法也并不多,也就那几个(而且抓取内容还是直接调用别人写好的类中的方法就可以了)

但之前想过的是php似乎并没有实现如下的方法,比如一个文件中有N行(N很大),需要将其中符合规则的行内容进行替换,如第3行是aaa需要转成bbbbb。一般的需要修改文件时的常见做法:

1.一次读取整个文件(或是逐行读取),然后使用临时文件进行保存最终转换后的结果,再替换原始文件

2.逐行读取,使用fseek控制文件指针的位置,然后fwrite写入

方案1在文件较大时,一次读取不可取(逐行读取,然后写入临时文件再替换原始文件效率感觉也不高),方案2则在被替换的字符串长度小于等于目标值时没问题,但超过了则会有问题,它会“越界”,将下一行的数据也打乱了(不能像JavaScript中有“选区”的概念,使用新的内容进行替换)。

下面是使用方案2做试验的代码:

<?php

$mode = "r+";

$filename = "d:/file.txt";

$fp = fopen($filename, $mode);

if ($fp) {

 $i = 1;

 while (!feof($fp)) {

    $str = fgets($fp);

    echo $str;

    if ($i == 1) {

      $len = strlen($str);

      fseek($fp, -$len, SEEK_CUR);//指针向前移动

      fwrite($fp, "123");

    }

    i++;

  }

  fclose($fp);

}

?>

先读取一行,此时文件指针其实是指到下一行开头,使用fseek将文件指针回移到上一行起始位置,然后使用fwrite进行替换操作,正因为是替换操作,在不指定长度的情况下,它把影响到下一行的数据,而我想要的是只想针对这一行进行操作,例如删除这一行或是整行只替换为一个1,上面的例子达不到要求,或许是我还没有找到合适的方法…

PHP 相关文章推荐
一个显示天气预报的程序
Oct 09 PHP
我的论坛源代码(十)
Oct 09 PHP
理解PHP5中static和const关键字的区别
Mar 19 PHP
DOM基础及php读取xml内容操作的方法
Jan 23 PHP
PHP中字符安全过滤函数使用小结
Feb 25 PHP
PHP Yii框架之表单验证规则大全
Nov 16 PHP
高质量PHP代码的50个实用技巧必备(下)
Jan 22 PHP
关于PHP 如何用 curl 读取 HTTP chunked 数据
Feb 26 PHP
PHP实现的下载远程文件类定义与用法示例
Jul 05 PHP
PHP调用其他文件中的类
Apr 02 PHP
php curl简单采集图片生成base64编码(并附curl函数参数说明)
Feb 15 PHP
PHP实现创建以太坊钱包转账等功能
Apr 21 PHP
PHP基于GD库的缩略图生成代码(支持jpg,gif,png格式)
Jun 19 #PHP
PHP mkdir()无写权限的问题解决方法
Jun 19 #PHP
PHP获取文件的MD5值并判断是否被修改的例子
Jun 19 #PHP
PHP中strlen()和mb_strlen()的区别浅析
Jun 19 #PHP
php对包含html标签的字符串进行截取的函数分享
Jun 19 #PHP
php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
Jun 19 #PHP
PHP base64编码后解码乱码的解决办法
Jun 19 #PHP
You might like
[EPIC] Larva vs Flash ZvT @ Crossing Field [2017-10-09]
2020/03/17 星际争霸
PHP中文件缓存转内存缓存的方法
2011/12/06 PHP
PHP stripos()函数及注意事项的分析
2013/06/08 PHP
php密码生成类实例
2014/09/24 PHP
PHP 5.3和PHP 5.4出现FastCGI Error解决方法
2015/02/12 PHP
PHP如何通过传引用的思想实现无限分类(代码简单)
2015/10/13 PHP
jQuery下扩展插件和拓展函数的写法(匿名函数使用的典型例子)
2010/10/20 Javascript
使用jquery动态加载javascript以减少服务器压力
2012/10/29 Javascript
使用JavaScript 实现各种跨域的方法
2013/05/08 Javascript
网页收藏夹显示ICO图标(代码少)
2015/08/04 Javascript
深入分析jsonp协议原理
2015/09/26 Javascript
JavaScript实现的简单烟花特效代码
2015/10/20 Javascript
JavaScript类型系统之正则表达式
2016/01/05 Javascript
JavaScript如何实现组合列表框中元素移动效果
2016/03/01 Javascript
jQuery插件HighCharts绘制2D圆环图效果示例【附demo源码下载】
2017/03/09 Javascript
NodeJs测试框架Mocha的安装与使用
2017/03/28 NodeJs
JavaScript初学者必看“new”
2017/06/12 Javascript
使用Bootstrap + Vue.js实现表格的动态展示、新增和删除功能
2017/11/27 Javascript
JS实现简单获取最近7天和最近3天日期的方法
2018/04/18 Javascript
node.js中TCP Socket多进程间的消息推送示例详解
2018/07/10 Javascript
JavaScript函数式编程(Functional Programming)高阶函数(Higher order functions)用法分析
2019/05/22 Javascript
javascrpt密码强度校验函数详解
2020/03/18 Javascript
Python Socket编程入门教程
2014/07/11 Python
详解Python中 __get__和__getattr__和__getattribute__的区别
2016/06/16 Python
Python使用PDFMiner解析PDF代码实例
2017/03/27 Python
同时安装Python2 &amp; Python3 cmd下版本自由选择的方法
2017/12/09 Python
unittest+coverage单元测试代码覆盖操作实例详解
2018/04/04 Python
Python多线程多进程实例对比解析
2020/03/12 Python
Python3 filecmp模块测试比较文件原理解析
2020/03/23 Python
解析python 类方法、对象方法、静态方法
2020/08/15 Python
HTML5中Canvas与SVG的画图原理比较
2013/01/16 HTML / CSS
总裁办公室主任职责
2014/01/02 职场文书
商场父亲节活动方案
2014/08/27 职场文书
民事撤诉申请书范本
2015/05/18 职场文书
MySQL8.0.24版本Release Note的一些改进点
2021/04/22 MySQL
游戏《东方异文石:爱亚利亚黎明》正式版发布
2022/04/03 其他游戏