深入php数据采集的详解


Posted in PHP onJune 02, 2013

这里介绍两个php采集能用到的好工具。一个是Snoopy,一个是simple_html_dom。采集还有很多方式(其实本质就2-3种,其他的都是衍生的),php自带了几个方法也能直接进行采集。但是,出于把懒惰进行到底的精神。我们还是可以通过这两个工具,让采集变得更简单。

网上有不少介绍Snoopy的,下面是别人翻译的Snoopy的SDK
//////////////////////////////////////////////////////////////
Snoopy是一个php类,用来模拟浏览器的功能,可以获取网页内容,发送表单。
Snoopy的一些特点:
1抓取网页的内容 fetch
2抓取网页的文本内容 (去除HTML标签) fetchtext
3抓取网页的链接,表单 fetchlinks fetchform
4支持代理主机
5支持基本的用户名/密码验证
6支持设置 user_agent, referer(来路), cookies 和 header content(头文件)
7支持浏览器重定向,并能控制重定向深度
8能把网页中的链接扩展成高质量的url(默认)
9提交数据并且获取返回值
10支持跟踪HTML框架
11支持重定向的时候传递cookies
要求php4以上就可以了 由于本身是php一个类 无需扩支持 服务器不支持curl时候的最好选择,
类方法:
fetch($URI)
———?
这是为了抓取网页的内容而使用的方法。
$URI参数是被抓取网页的URL地址。
抓取的结果被存储在 $this->results 中。
如果你正在抓取的是一个框架,Snoopy将会将每个框架追踪后存入数组中,然后存入 $this->results。
fetchtext($URI)
—————
本方法类似于fetch(),唯一不同的就是本方法会去除HTML标签和其他的无关数据,只返回网页中的文字内容。
fetchform($URI)
—————
本方法类似于fetch(),唯一不同的就是本方法会去除HTML标签和其他的无关数据,只返回网页中表单内容(form)。
fetchlinks($URI)
—————-
本方法类似于fetch(),唯一不同的就是本方法会去除HTML标签和其他的无关数据,只返回网页中链接(link)。
默认情况下,相对链接将自动补全,转换成完整的URL。
submit($URI,$formvars)
———————-
本方法向$URL指定的链接地址发送确认表单。$formvars是一个存储表单参数的数组。
submittext($URI,$formvars)
————————?
本方法类似于submit(),唯一不同的就是本方法会去除HTML标签和其他的无关数据,只返回登陆后网页中的文字内容。
submitlinks($URI)
—————-
本方法类似于submit(),唯一不同的就是本方法会去除HTML标签和其他的无关数据,只返回网页中链接(link)。
默认情况下,相对链接将自动补全,转换成完整的URL。
类属性: (缺省值在括号里)
$host 连接的主机
$port 连接的端口
$proxy_host 使用的代理主机,如果有的话
$proxy_port 使用的代理主机端口,如果有的话
$agent 用户代理伪装 (Snoopy v0.1)
$referer 来路信息,如果有的话
$cookies cookies, 如果有的话
$rawheaders 其他的头信息, 如果有的话
$maxredirs 最大重定向次数, 0=不允许 (5)
$offsiteok whether or not to allow redirects off-site. (true)
$expandlinks 是否将链接都补全为完整地址 (true)
$user 认证用户名, 如果有的话
$pass 认证用户名, 如果有的话
$accept http 接受类型 (image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*)
$error 哪里报错, 如果有的话
$response_code 从服务器返回的响应代码
$headers 从服务器返回的头信息
$maxlength 最长返回数据长度
$read_timeout 读取操作超时 (requires PHP 4 Beta 4+)
设置为0为没有超时
$timed_out 如果一次读取操作超时了,本属性返回 true (requires PHP 4 Beta 4+)
$maxframes 允许追踪的框架最大数量
$status 抓取的http的状态
$temp_dir 网页服务器能够写入的临时文件目录 (/tmp)
$curl_path cURL binary 的目录, 如果没有cURL binary就设置为 false
以下是demo

include "Snoopy.class.php";
$snoopy = new Snoopy;
$snoopy->proxy_host = "www.7767.cn";
$snoopy->proxy_port = "8080";
$snoopy->agent = "(compatible; MSIE 4.01; MSN 2.5; AOL 4.0; Windows 98)";
$snoopy->referer = "http://www.7767.cn/";
$snoopy->cookies["SessionID"] = 238472834723489l;
$snoopy->cookies["favoriteColor"] = "RED";
$snoopy->rawheaders["Pragma"] = "no-cache";
$snoopy->maxredirs = 2;
 $snoopy->offsiteok = false;
$snoopy->expandlinks = false;
$snoopy->user = "joe";
 $snoopy->pass = "bloe";
if($snoopy->fetchtext("http://www.7767.cn"))
{
   echo "<PRE>".htmlspecialchars($snoopy->results)."</PRE>\n";
}
else
echo "error fetching document: ".$snoopy->error."\n";

//////////////////////////////////////////////////////////////
Snoopy的特点是“大”和“全”,一个fetch什么都采到了,可以作为采集的第一步。接下来就需要用simple_html_dom来细细的把想要的部分,扣出来。当然,如果你特别特别擅长正则,而且又钟爱正则,你也可以用正则去匹配抓取。

simple_html_dom其实是一个dom解析的过程。php内部也提供了一些解析的方法,但是这个simple_html_dom可以说做得比较专业,一个类,满足了很多你想要的功能。
////////////////////////////////////////////////////////////////
// 用一个URL或文件名,创建一个目标文档对象 ,也就是目标网页
$html = file_get_html ('http://www.7767.cn/' );
//$html = file_get_html ('test.htm' );
//用一个字符串作为一个目标网页。你可以通过Snoopy获取页面,然后再拿到这里来处理
$myhtml = str_get_html ('<html><body>Hello!</body></html>' );
// 找到所有的图片,返回的是数组
foreach($html->find ('img' ) as $element)
       echo $element->src . '<br>' ;
// 找到所有的链接
foreach($html->find ('a' ) as $element)
       echo $element->href . '<br>' ;

find方法很好用,通常它返回的是一个包含对象的数组。查找目标元素的时候可以通过class或者id,或者其他属性获取目标字符串。

//通过目标div的class属性,查找div,find方法中第二个参数是返回的那个数组中的第几个。从0开始是第一个
$target_div = $html->find ('div.targetclass',0 );
//查看结果是否是你想要的,直接echo就可以了
echo  $target_div;

//比较关键的一点是,这个采集对象创建完后,一定要销毁掉,否则php页面有可能会“卡”上30秒左右,这个取决于你服务器的那个时间限制。销毁的方法是:
$html->clear();
unset($html);
本人认为simple_html_dom比较优秀的地方就是,把采集控制得像JS一样容易。在下面提供的下载包中有英文的手册
simplehtmldom_1_11/simplehtmldom/manual/manual.htm

array$e->getAllAttributes () array$e->attr
string$e->getAttribute ( $name ) string$e->attribute
void$e->setAttribute ( $name, $value ) void$value = $e->attribute
bool$e->hasAttribute ( $name ) boolisset($e->attribute )
void$e->removeAttribute ( $name ) void$e->attribute = null
element$e->getElementById ( $id ) mixed$e->find ( "#$id", 0 )
mixed$e->getElementsById ( $id [,$index] ) mixed$e->find ( "#$id" [, int $index] )
element$e->getElementByTagName ($name ) mixed$e->find ( $name, 0 )
mixed$e->getElementsByTagName ( $name [, $index] ) mixed$e->find ( $name [, int $index] )
element$e->parentNode () element$e->parent ()
mixed$e->childNodes ( [$index] ) mixed$e->children ( [int $index] )
element$e->firstChild () element$e->first_child ()
element$e->lastChild () element$e->last_child ()
element$e->nextSibling () element$e->next_sibling ()
element$e->previousSibling () element$e->prev_sibling ()
PHP 相关文章推荐
一个可查询所有表的“通用”查询分页类
Oct 09 PHP
同时提取多条新闻中的文本一例
Oct 09 PHP
利用递归把多维数组转为一维数组的函数
Oct 09 PHP
利用PHP制作简单的内容采集器的代码
Nov 28 PHP
PHP网站安装程序制作的原理、步骤、注意事项和示例代码
Aug 01 PHP
php 学习资料零碎东西
Dec 04 PHP
PHP读取文件并可支持远程文件的代码分享
Oct 03 PHP
php 中的closure用法详解
Jun 12 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
Aug 30 PHP
PHP针对redis常用操作实例详解
Aug 17 PHP
laravel请求参数校验方法
Oct 10 PHP
PHP文件操作简单介绍及函数汇总
Dec 11 PHP
基于php下载文件的详解
Jun 02 #PHP
用PHP实现浏览器点击下载TXT文档的方法详解
Jun 02 #PHP
优化PHP代码技巧的小结
Jun 02 #PHP
PHP无限分类(树形类)的深入分析
Jun 02 #PHP
基于php无限分类的深入理解
Jun 02 #PHP
php curl的深入解析
Jun 02 #PHP
Window 7/XP 安装Apache 2.4与PHP 5.4 的过程详解
Jun 02 #PHP
You might like
PHP实现的功能是显示8条基色色带
2006/10/09 PHP
php中定时计划任务的实现原理
2013/01/08 PHP
PHP CodeBase:将时间显示为&quot;刚刚&quot;&quot;n分钟/小时前&quot;的方法详解
2013/06/06 PHP
TP5框架实现的数据库备份功能示例
2020/04/05 PHP
点击广告后才能获得下载地址
2006/10/26 Javascript
基于JQuery的Pager分页器实现代码
2010/07/17 Javascript
JavaScript Accessor实现说明
2010/12/06 Javascript
基于jQuery的星级评分插件
2011/08/12 Javascript
JS图片自动轮换效果实现思路附截图
2014/04/30 Javascript
JS实现带有3D立体感的银灰色竖排折叠菜单代码
2015/10/20 Javascript
jquery+css实现动感的图片切换效果
2015/11/25 Javascript
基于jquery实现动态竖向柱状条特效
2016/02/12 Javascript
JS实现自动轮播图效果(自适应屏幕宽度+手机触屏滑动)
2017/06/19 Javascript
vue.js组件vue-waterfall-easy实现瀑布流效果
2017/08/22 Javascript
angular中ui calendar的一些使用心得(推荐)
2017/11/03 Javascript
node.js之基础加密算法模块crypto详解
2018/09/11 Javascript
在Vue中获取组件声明时的name属性方法
2018/09/12 Javascript
Angular8路由守卫原理和使用方法
2019/08/29 Javascript
JS通过识别id、value值对checkbox设置选中状态
2020/02/19 Javascript
python清除字符串里非字母字符的方法
2015/07/02 Python
Python操作SQLite数据库的方法详解【导入,创建,游标,增删改查等】
2017/07/11 Python
Python iter()函数用法实例分析
2018/03/17 Python
windows下numpy下载与安装图文教程
2019/04/02 Python
Python实现带下标索引的遍历操作示例
2019/05/30 Python
基于Python实现剪切板实时监控方法解析
2019/09/11 Python
python 多维高斯分布数据生成方式
2019/12/09 Python
jupyter notebook tensorflow打印device信息实例
2020/04/20 Python
浅谈css3新单位vw、vh、vmin、vmax的使用详解
2017/12/01 HTML / CSS
大气污染防治方案
2014/05/19 职场文书
学习三严三实心得体会
2014/10/13 职场文书
2014年幼儿园教师工作总结
2014/11/08 职场文书
银行反洗钱宣传活动总结
2015/05/08 职场文书
迎新晚会主持词开场白
2015/05/28 职场文书
诚信教育主题班会
2015/08/13 职场文书
mysql查询的控制语句图文详解
2021/04/11 MySQL
python实现腾讯滑块验证码识别
2021/04/27 Python