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 相关文章推荐
php操作excel文件 基于phpexcel
Jul 02 PHP
PHP编码转换函数 自动转换字符集支持数组转换
Dec 16 PHP
ajax返回值中有回车换行、空格的解决方法分享
Oct 24 PHP
PHP分页详细讲解(有实例)
Oct 30 PHP
php的zip解压缩类pclzip使用示例
Mar 14 PHP
ThinkPHP惯例配置文件详解
Jul 14 PHP
php学习笔记之面向对象
Nov 08 PHP
ThinkPHP中使用ajax接收json数据的方法
Dec 18 PHP
php+mysqli使用预处理技术进行数据库查询的方法
Jan 28 PHP
php使用unset()删除数组中某个单元(键)的方法
Feb 17 PHP
php实现文件预览功能
May 23 PHP
对php 判断http还是https,以及获得当前url的方法详解
Jan 15 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
PHP 删除一个目录及目录下的所有文件的函数代码
2010/05/26 PHP
IE7提供XMLHttpRequest对象为兼容
2007/03/08 Javascript
JavaScript 笔记二 Array和Date对象方法
2010/05/22 Javascript
一个收集图片的bookmarlet(js 刷新页面中的图片)
2010/05/27 Javascript
基于Jquery的文字滚动跑马灯插件(一个页面多个滚动区)
2010/07/26 Javascript
js获取dom的高度和宽度(可见区域及部分等等)
2013/06/13 Javascript
PHP中CURL的几个经典应用实例
2015/01/23 Javascript
javascript bom是什么及bom和dom的区别
2015/11/26 Javascript
Bootstrap图片轮播组件使用实例解析
2016/06/30 Javascript
详解Nodejs mongoose
2018/06/10 NodeJs
swiper.js插件实现pc端文本上下滑动功能示例
2018/12/03 Javascript
配置node服务器并且链接微信公众号接口配置步骤详解
2019/06/21 Javascript
聊聊Vue中provide/inject的应用详解
2019/11/10 Javascript
使用js实现单链解决前端队列问题的方法
2020/02/03 Javascript
vue实现按钮切换图片
2021/01/20 Vue.js
[43:03]LGD vs Newbee 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
python 正则式使用心得
2009/05/07 Python
在Django中使用Sitemap的方法讲解
2015/07/22 Python
python变量不能以数字打头详解
2016/07/06 Python
python实现字符串连接的三种方法及其效率、适用场景详解
2017/01/13 Python
解决python3爬虫无法显示中文的问题
2018/04/12 Python
详解将Python程序(.py)转换为Windows可执行文件(.exe)
2019/07/19 Python
Python 中的 global 标识对变量作用域的影响
2019/08/12 Python
pycharm中import呈现灰色原因的解决方法
2020/03/04 Python
python批量处理多DNS多域名的nslookup解析实现
2020/06/28 Python
Python 解析库json及jsonpath pickle的实现
2020/08/17 Python
CSS3的一个简单导航栏实现
2015/08/03 HTML / CSS
世界上最大的汽车共享网站:Zipcar
2017/01/14 全球购物
中东最大的在线宠物店:Dubai Pet Food
2020/06/11 全球购物
中专毕业生求职简历的自我评价
2013/10/21 职场文书
七一党建活动方案
2014/01/28 职场文书
党的群众路线教育实践活动制度建设计划
2014/11/03 职场文书
2015年污水处理厂工作总结
2015/05/26 职场文书
《围炉夜话》110句人生箴言,精辟有内涵,引人深思
2019/10/23 职场文书
Python数据清洗工具之Numpy的基本操作
2021/04/22 Python
GPU服务器的多用户配置方法
2022/07/07 Servers