深入php数据采集的详解

这里介绍两个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 )

bool
isset($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 ()

时间: 2013-05-31

基于PHP的简单采集数据入库程序【续篇】

在上篇文章中,我们已经采集新闻信息页的列表数据,接下来要做的操作就是从数据库中读取所需要采集的URL,进行页面抓取就行 新建一个content表 不过需要注意的一点是,不能再采用采集URL这种id递增的方法去采集,因为数据表中可能出现id断续,比如id=9,id=11,当采集到id=10的时候,URL是空白的,这样可能会导致采集到了空字段. 这里用到的一个技巧是数据库的查询语句,在我们采集完第一条数据的时候,判断数据库里是否还有大于此id的id编号,若有,读取一条,查询信息重复上面的工作. 具体

php采集文章中的图片获取替换到本地(实现代码)

复制代码 代码如下: /** * 获取替换文章中的图片路径 * @param string $xstr 内容 * @param string $keyword 创建照片的文件名 * @param string $oriweb 网址 * @return string *  */function replaceimg($xstr,$keyword, $oriweb){ //保存路径    $d = date('Ymd', time());    $dirslsitss = '/var/www/web

php实现的一个很好用HTML解析器类可用于采集数据

复制代码 代码如下: <?php    $oldSetting = libxml_use_internal_errors( true );    libxml_clear_errors();   /**  *   * -+-----------------------------------  * |PHP5 Framework - 2011  * |Web Site: www.iblue.cc  * |E-mail: mejinke@gmail.com  * |Date: 2012-10-12

PHP实现采集中国天气网未来7天天气

前言 我们在写一个Web程序的时候,总会想着把自己的网站更美观一些,功能能更多一些,有时候写一些小的工具或者加上小的插件会让我们的站点更加完善.比如万年历功能,比如我们现在要讲的天气预报功能. 当然我们没法利用专业的卫星接受数据,所以我们的天气数据来自现有的天气预报网站.利用天气预报网站提供的数据服务,我们可以写一个PHP爬虫,然后动态采集我们所需要的数据,并且在目标站点更新数据的时候,我们的程序也能做到同步更新,自动地获取数据. 下面就介绍一下如何编写一个简单的PHP数据采集程序(PHP爬虫)

一个基于phpQuery的php通用采集类分享

一.采集类源码 复制代码 代码如下: <?php  /**  *通用列表采集类  *版本V1.3  *作者:JAE  */    require_once '../phpQuery/phpQuery/phpQuery.php';    class QueryList{ private $pageURL;         private $regArr = array();         public $jsonArr = array();         private $regRange; 

PHP使用CURL_MULTI实现多线程采集的例子

这两天有一客户定制了一个免登录发布模块,因为在模块中需要涉及到很多图片下载的问题,考虑到性能问题,所以特别写了一个CURL_MULTI远程采集网页的函数,以方便以后使用,估计以后都不会使用原来的单线程curl函数去foreach了,其性能对比很明显的.同样获取我的博客的十个不同网页,curl_multi:4.5246081352234,file_get_contents:33.001797914505,将近8倍的效率,可想而知,如果在附件更多的情况下,性能差异就越明显了,希望对您有所帮助! 复制

基于PHP的简单采集数据入库程序

说到采集,无非就是远程获取信息->提取所需内容->分类存储->读取->展示 也算是简单"小偷程序"的加强版吧 下面是对应核心代码(别拿去做坏事哦^_^) 所要采集的内容是某游戏网站上的公告,如下图: 可先利用file_get_contents和简单正则获取基本页面信息 整理下基本信息,采集入库: <?php include_once("conn.php"); if($_GET['id']<=8&&$_GET['id

解析php利用正则表达式解决采集内容排版的问题

做采集经常遇到的问题是内容排版问题,用了一些时间写了个用正则替换html标签和样式的函数,共享下. 复制代码 代码如下: /** * 格式化内容 * @param string $content 内容最好统一用utf-8编码 * @return string * !本函数需要开启tidy扩展 */function removeFormat($content) { $replaces = array (   "/<font.*?>/i" => '',   "/

php使用curl模拟登录后采集页面的例子

今天接到的功课是从一个网站获取商品库存,但是这个网站需要登录,我用fsockopen传递了整个header头都没用,只能求助于curl了.附带说一下curl模块的开启办法:(1)从php目录下拷贝:libeay32.dll,ssleay32.dll 到windows目录下.(2)打开php.ini,查找"extension_dir = xxxxx",确认后面的文件目录内有php_curl.dll文件.(3)同样是php.ini,查找"extension=php_curl.dl

PHP远程采集图片详细教程

当我们需要采集网络上的某个网页内容时,如果目标网站上的图片做了防盗链的话,我们直接采集过来的图片在自己网站上是不可用的.那么我们使用程序将目标网站上的图片下载到我们网站服务器上,然后就可调用图片了. 本文将使用PHP实现采集远程图片功能.基本流程: 1.获取目标网站图片地址. 2.读取图片内容. 3.创建要保存图片的路径并命名图片名称. 4.写入图片内容. 5.完成. 我们通过写几个函数来实现这一过程. 函数make_dir()建立目录.判断要保存的图片文件目录是否存在,如果不存在则创建目录,并

PHP采集静态页面并把页面css,img,js保存的方法

本文实例讲述了PHP采集静态页面并把页面css,img,js保存的方法.分享给大家供大家参考.具体分析如下: 这是一个可以获取网页的html代码以及css,js,font和img资源的小工具,主要用来快速获取模板,如果你来不及设计UI或者看到不错的模板,则可以使用这个工具来抓取网页和提取资源文件,提取的内容会按相对路径来保存资源,因此你不必担心资源文件的错误url导入. 首页 index.php,代码如下: 复制代码 代码如下: <!DOCTYPE html> <html> <

yii2 页面底部加载css和js的技巧

一般来说,网页内部的js文件或代码,都是放置在网页底部</body>的前面,这是因为网页自上而下加载,用户在访问我们页面的时候尽量不要因为加载js展现过长时间的空白页面,停留时间过长就白白流失了用户量. yii2中是集成了jQuery的,而且jQuery文件是加载在页面底部的,因此,如果我们的js代码段不在页面底部加载,就很大可能会发生$未定义的友好提示. 我这废话一大堆得毛病确实需要去挂个号看看了... 先来看看js代码段怎么处理 <?php $this->registerJs(

Ajax 动态载入html页面后不能执行其中的js快速解决方法

事件背景 有一个公用页面需要在多个页面调用,其中涉及到部分js已经写在了公用页面中,通过ajax加载该页面后无法执行其中的js. 解决思路 1. 采用附加一个iframe的方法去执行js,为我等代码洁癖者所不齿. 2. 使用document.write输出代码,我等简洁主义者所不愿. 3. 最简单的方法是把js放到需要调用的父页面,那想这样的公用页面,每个地方调用都要写入一次,代码冗余. 4. eval是个解决方法,虽然低效. 5. 复杂的解决方法:正则匹配出加载页面中的所有js,为这些js创建

ThinkPHP模版中导入CSS和JS文件的方法

本文实例讲述了ThinkPHP模版中导入CSS和JS文件的方法.分享给大家供大家参考.具体方法如下: 常用方法 1. css使用link 2. js使用src 用tp自己的导入标签import 导入Public文件夹下面的Js目录中的test.js文件,import标签可以省略type属性,默认就是js的文件 复制代码 代码如下: <import type='js' file='Js.test'> <import type='css' file='Css.test'> 不在Publ

php实现压缩多个CSS与JS文件的方法

本文实例讲述了php实现压缩多个CSS与JS文件的方法.分享给大家供大家参考.具体实现方法如下: 1. 压缩css 复制代码 代码如下: <?php    header('Content-type: text/css');    ob_start("compress");    function compress($buffer) {        /* remove comments */        $buffer = preg_replace('!/\*[^*]*\*+(

Yii2框架加载css和js文件的方法分析

本文实例讲述了Yii2框架加载css和js文件的方法.分享给大家供大家参考,具体如下: 1.第一步是要把我们的css.js文件放到web目录下 2.第二步修改assets/AppAsset.php文件 <?php /** * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * @license http://www.yiiframework.com/license/ */ na

jQuery单页面文字搜索插件jquery.fullsearch.js的使用方法

jquery.fullsearch.js一款基于Bootstrap的单页面文字搜索jQuery插件.通过搜索关键字,插件会在下拉列表中高亮列出关键字和所在的各个段落,用户点击相应的搜索下拉列表项即可跳转到相应的地方. jquery.fullsearch.js使用方法 使用该文字搜索插件需要在页面中引入Bootstrap相关文件,以及jQuery和jquery.full-search.js文件,为了实现瞄点跳转,还需要引入anchor.js文件. <link href="css/bootst

如何采集静态文章系统

目前网站基本上都生成静态的了,对于那些技术不是很高深的小偷来说,去偷一个文件名是以时间加随机数来命名的文章系统,有点困难,而目前的大多数静态的系统都是以这样的方式命名的,这个不像有asp?id=1 to asp?id=100这样好这个命名是没规律的,那么,这种文章系统怎么样采呢,以下就以自已的站www.asp315.com这例来写一篇关于采集静态文章系统的教程吧!  首先,我们打开www.asp315.com你会发现教程很多,我们随便点一个进去吧,就点JSP教程吧,里面还分了子类,这个不管我们就

用Nodejs搭建服务器访问html、css、JS等静态资源文件

为了测一个附近门店的功能,需要配置一下服务器进行测试.本来打算用apache的,后来想自己是做前端的,好久没有用过Nodejs了何不用所学的知识自己配一下呢,说动手就手. 第一步,俗话说的好,工欲善其事,必先利其器.既然要用node+express配置服务器,如果电脑上没有的话自然要先安装这两个大宝贝啦. 1.安装node.到Node官网下载安装即可,直接下一步下一步就完成了. 2.npm初始化项目.打开终端,输入npm init -y即可.注意:如果不输入-y要自己写一些配置,写了-y会默认直

jQuery在页面加载时动态修改图片尺寸的方法

本文实例讲述了jQuery在页面加载时动态修改图片尺寸的方法.分享给大家供大家参考.具体如下: $(window).bind("load", function() { // IMAGE RESIZE $('#product_cat_list img').each(function() { var maxWidth = 120; var maxHeight = 120; var ratio = 0; var width = $(this).width(); var height = $(