深入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 相关文章推荐
Dedecms V3.1 生成HTML速度的优化办法
Mar 18 PHP
php下判断数组中是否存在相同的值array_unique
Mar 25 PHP
PHP中其实也可以用方法链
Nov 10 PHP
一个PHP并发访问实例代码
Sep 06 PHP
THINKPHP内容分页代码分享
Jan 14 PHP
php中使用url传递数组的方法
Feb 11 PHP
php中执行系统命令的方法
Mar 21 PHP
一个简单安全的PHP验证码类、PHP验证码
Sep 24 PHP
php判断是否连接上网络的方法实例详解
Dec 14 PHP
解决出现SoapFault (looks like we got no XML document)的问题
Jun 24 PHP
php图片裁剪函数
Oct 31 PHP
php和vue配合使用技巧和方法
May 09 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的$_FILES的临时储存文件与回收机制实测过程
2013/07/12 PHP
PHP中怎样保持SESSION不过期 原理及方案介绍
2013/08/08 PHP
php设置页面超时时间解决方法
2015/09/22 PHP
HR vs ForZe BO3 第一场 2.13
2021/03/10 DOTA
javascript 鼠标拖动图标技术
2010/02/07 Javascript
jquery中的 $(&quot;#jb51&quot;)与document.getElementById(&quot;jb51&quot;) 的区别
2011/07/26 Javascript
javaScript实现浮点数转十六进制字符
2013/10/29 Javascript
实现checkbox全选、反选、取消JavaScript小脚本异常
2014/04/10 Javascript
jQuery+CSS实现一个侧滑导航菜单代码
2016/05/09 Javascript
JavaScript 总结几个提高性能知识点(推荐)
2017/02/20 Javascript
原生JS中slice()方法和splice()区别
2017/03/06 Javascript
详解angular用$sce服务来过滤HTML标签
2017/04/11 Javascript
文本溢出插件jquery.dotdotdot.js使用方法详解
2017/06/22 jQuery
Node.js使用Koa搭建 基础项目
2018/01/08 Javascript
bootstrap中selectpicker下拉框使用方法实例
2018/03/22 Javascript
Vue 配合eiement动态路由,权限验证的方法
2018/09/26 Javascript
详解Vue-cli3.X使用px2rem遇到的问题
2019/08/09 Javascript
Vue常用的全选/反选的示例代码
2020/02/19 Javascript
基于vue-cli3+typescript的tsx开发模板搭建过程分享
2020/02/28 Javascript
python继承和抽象类的实现方法
2015/01/14 Python
python中pygame针对游戏窗口的显示方法实例分析(附源码)
2015/11/11 Python
Python编程中使用Pillow来处理图像的基础教程
2015/11/20 Python
python读取图片的方式,以及将图片以三维数组的形式输出方法
2019/07/03 Python
Django 实现admin后台显示图片缩略图的例子
2019/07/28 Python
使用python图形模块turtle库绘制樱花、玫瑰、圣诞树代码实例
2020/03/16 Python
Keras自定义IOU方式
2020/06/10 Python
python爬虫数据保存到mongoDB的实例方法
2020/07/28 Python
python读取xml文件方法解析
2020/08/04 Python
python 怎样进行内存管理
2020/11/10 Python
用CSS3实现无限循环的无缝滚动的实例代码
2017/07/04 HTML / CSS
HTML5通用接口详解
2016/06/12 HTML / CSS
New Balance加拿大官方网站:运动鞋和健身服装
2018/11/19 全球购物
商场经理竞聘演讲稿
2014/01/01 职场文书
研究生毕业自我鉴定范文
2014/03/27 职场文书
企业三严三实学习心得体会
2014/10/13 职场文书
幼儿园毕业典礼家长致辞
2015/07/29 职场文书