深入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 相关文章推荐
Php做的端口嗅探器--可以指定网站和端口
Oct 09 PHP
PHP循环获取GET和POST值的代码
Apr 09 PHP
PHP中str_replace函数使用小结
Oct 11 PHP
php mssql 数据库分页SQL语句
Dec 16 PHP
mysql总结之explain
Feb 27 PHP
PHP自动生成后台导航网址的最佳方法
Aug 27 PHP
php加密算法之实现可逆加密算法和解密分享
Jan 21 PHP
php获取发送给用户的header信息的方法
Mar 16 PHP
使用PHP uniqid函数生成唯一ID
Nov 18 PHP
PHP实现活动人选抽奖功能
Apr 19 PHP
PHPExcel 修改已存在Excel的方法
May 03 PHP
详解php用static方法的原因
Sep 12 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
全国FM电台频率大全 - 22 重庆市
2020/03/11 无线电
3种平台下安装php4经验点滴
2006/10/09 PHP
用穿越火线快速入门php面向对象
2012/02/22 PHP
探讨各种PHP字符串函数的总结分析
2013/06/05 PHP
php中try catch捕获异常实例详解
2014/11/21 PHP
PHP获取youku视频真实flv文件地址的方法
2014/12/23 PHP
php获取字符串中各个字符出现次数的方法
2015/02/23 PHP
Laravel利用gulp如何构建前端资源详解
2018/06/03 PHP
jQuery)扩展jQuery系列之一 模拟alert,confirm(一)
2010/12/04 Javascript
能说明你的Javascript技术很烂的五个原因分析
2011/10/28 Javascript
javascript实现跳转菜单的具体方法
2013/07/05 Javascript
JavaScript显示当然日期和时间即年月日星期和时间
2013/10/29 Javascript
JS+CSS实现的蓝色table选项卡效果
2015/10/08 Javascript
JavaScript获取各大浏览器信息图示
2015/11/20 Javascript
基于JavaScript如何实现ajax调用后台定义的方法
2015/12/29 Javascript
jquery实现树形菜单完整代码
2015/12/29 Javascript
Jquery插件仿百度搜索关键字自动匹配功能
2016/05/11 Javascript
jquery.multiselect多选下拉框实现代码
2016/11/11 Javascript
webpack多页面开发实践
2017/12/18 Javascript
WebPack配置vue多页面的技巧
2018/05/15 Javascript
简单易扩展可控性强的Jquery转盘抽奖程序
2019/03/16 jQuery
微信sdk实现禁止微信分享(使用原生php实现)
2019/11/15 Javascript
解决echarts 一条柱状图显示两个值,类似进度条的问题
2020/07/20 Javascript
[13:38]2015国际邀请赛中国战队出征仪式
2015/05/29 DOTA
python获取文件真实链接的方法,针对于302返回码
2018/05/14 Python
使用Python自动化破解自定义字体混淆信息的方法实例
2019/02/13 Python
python使用Plotly绘图工具绘制柱状图
2019/04/01 Python
Python中psutil的介绍与用法
2019/05/02 Python
python sorted函数的小练习及解答
2019/09/18 Python
Python Map 函数的使用
2020/08/28 Python
校园餐饮创业计划书
2014/01/10 职场文书
党员干部2014全国两会学习心得体会
2014/03/10 职场文书
答谢酒会主持词
2015/07/02 职场文书
2015年“我们的节日·重阳节”活动总结
2015/07/29 职场文书
vue Element-ui表格实现树形结构表格
2021/06/07 Vue.js
nginx请求限制配置方法
2021/07/09 Servers