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 GD绘制24小时柱状图
Jun 28 PHP
PHP 读取文件内容代码(txt,js等)
Dec 06 PHP
apache mysql php 源码编译使用方法
May 03 PHP
php在文件指定行中写入代码的方法
May 23 PHP
php实现快速排序法函数代码
Aug 27 PHP
php计算当前程序执行时间示例
Apr 24 PHP
Codeigniter注册登录代码示例
Jun 12 PHP
php判断用户是否关注微信公众号
Jul 22 PHP
Zend Framework入门教程之Zend_Registry组件用法详解
Dec 09 PHP
利用php-cli和任务计划实现刷新token功能的方法
May 03 PHP
php实现JWT(json web token)鉴权实例详解
Nov 05 PHP
PHP命令行与定时任务
Apr 01 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计算两个路径的相对路径
2013/06/14 PHP
php中利用str_pad函数生成数字递增形式的产品编号
2013/09/30 PHP
深入研究PHP中的preg_replace和代码执行
2018/08/15 PHP
PHP时间类完整代码实例
2021/02/26 PHP
Js 本页面传值实现代码
2009/05/17 Javascript
JavaScript中使用replace结合正则实现replaceAll的效果
2010/06/04 Javascript
利用JQuery的load函数动态加载其它页面的内容的实现代码
2010/12/14 Javascript
JavaScript 面向对象与原型
2015/04/10 Javascript
微信小程序 Tab页切换更新数据
2017/01/05 Javascript
详解JS获取HTML DOM元素的8种方法
2017/06/17 Javascript
对Vue- 动态元素属性及v-bind和v-model的区别详解
2018/08/27 Javascript
JavaScript ES6常用基础知识总结
2019/02/09 Javascript
在Vue项目中用fullcalendar制作日程表的示例代码
2019/08/04 Javascript
[41:20]2014 DOTA2华西杯精英邀请赛 5 24 NewBee VS DK
2014/05/26 DOTA
在GitHub Pages上使用Pelican搭建博客的教程
2015/04/25 Python
连接Python程序与MySQL的教程
2015/04/29 Python
python3制作捧腹网段子页爬虫
2017/02/12 Python
初学python的操作难点总结(新手必看篇)
2017/08/03 Python
python3+PyQt5使用数据库窗口视图
2018/04/24 Python
opencv python 图像去噪的实现方法
2018/08/31 Python
Python实例方法、类方法、静态方法的区别与作用详解
2019/03/25 Python
对python中的装包与解包实例详解
2019/08/24 Python
结合OpenCV与TensorFlow进行人脸识别的实现
2019/10/10 Python
Pytorch自己加载单通道图片用作数据集训练的实例
2020/01/18 Python
Spring @Enable模块驱动原理及使用实例
2020/06/23 Python
requests在python中发送请求的实例讲解
2021/02/17 Python
HTML5之web workers_动力节点Java学院整理
2017/07/17 HTML / CSS
简历中个人求职的自我评价模板
2013/11/29 职场文书
《陶罐和铁罐》教学反思
2014/02/19 职场文书
安全生产管理合理化建议书
2014/03/12 职场文书
企业党支部工作总结2015
2015/05/21 职场文书
电影圆明园观后感
2015/06/03 职场文书
军训结束新闻稿
2015/07/17 职场文书
幼儿园迎新生欢迎词
2015/09/30 职场文书
2015年度个人工作总结报告
2015/10/24 职场文书
使用Python通过企业微信应用给企业成员发消息
2022/04/18 Python