设为首页 收藏本站
查看: 839|回复: 0

[经验分享] PHP使用DOMDocument采集

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-3-12 08:27:24 | 显示全部楼层 |阅读模式
采集是很多公司都做最的一件事,能够快速的获取别人辛苦得来的数据,虽为不道义,但无法禁止!

PHP采集一般方式有:
  • 正则采集。

  • 使用DOM对象采集。
  • 使用字符串函数提取。


这里只说下DOM对象采集的一些问题:

PHP有DOM对象专门用来处理HTML或XML文件,非常方便。
1
2
3
$dom = new DOMDocument('1.0','GBK');//创建DOM对象
@$dom->loadHTMLFile($url);//加载对应的URL地址HTML内容
$xpath=new DOMXPath($dom);//创建DOMXPath对象



DOMXPath对象是一个支持 XPath 路径表达式,http://www.w3school.com.cn/xpath/

XPath 路径表达式类似 JQuery选择器一样,可以方便的找到对应的节点然后提取内容,当然 XPath 的选择方式要远比 JQuery 多。而且还支持很多种函数处理。

注意
1
@$dom->loadHTMLFile($url);//加载对应的URL地址HTML内容



这句代码前面最好加上 @ 符号,因为在加载解析HTML内容时,或多或少会出现错误,如:在HTML页面内一些 & 符号要转义成 & ,html实体符号必须以 ;结束等等 才能顺利解析。而这类要求在采集过程中是不可能的。

采集过程中最让人麻烦的是中文字符处理,使用正则采集时,中文字符加在正则内虽然方便但容易出错,正则中写入中文必须保证被采集的字符集与当前系统代码字符集是相同的,否则匹配很容易失败。
使用DOMDocument解析HTML内容,也容易出现中文问题,一般是乱码,其主要原因是HTML结构不标准,
出现乱码都是字符集的问题,一般在HTML的head标签要指定字符集
<meta http-equiv=Content-Type content="text/html;charset=gb2312">
当这个标签不存在时,DOMDocument在解析时就会以默认的方式去解析这个HTML内容,导致中文编码错误。

所以在使用DOMDocument采集时不要直接使用
1
@$dom->loadHTMLFile($url);//加载对应的URL地址HTML内容



方式直接加载HTML,这样只要所采集的HTML内容没有包含字符集的指定,整个HTML内容解析后中文就不能用。
最好使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ch = curl_init($url);//创建连接
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);//输出内容
curl_setopt($ch, CURLOPT_TIMEOUT, 10);//设置超时时间
$html =  curl_exec($ch);//执行连接,获取内容
if($err=curl_error($ch)){//判断是否出错
   die($err);
}else{
    //判断是否存在这个标签
   if(!stripos('"Content-Type"', $html)&&!stripos('content="text/html;', $html)){
       $meta='<head><meta http-equiv="Content-Type" content="text/html; charset=GBK" />';
       $html=str_replace('<head>', $meta, $html);
   }
}
curl_close($ch);
$dom = new DOMDocument('1.0','GBK');//创建DOM对象
@$dom->loadHTML($html);//加载对应的URL地址HTML内容
$xpath=new DOMXPath($dom);//创建DOMXPath对象



对应所采集的页面字符集,必须核对好。
DOMXPath有两个函数用来操作内部节点:
query,和evaluate
query:取出给定的XPath表达式节点列表,只要表达式合法,返回DOMNodeList对象,否则返回false。
evaluate:取出给定XPath表达式节点列表,只要表达式合法并且有匹配的节点返回DOMNodeList对象,否则返回false。

两个函数都是提取节点,只是返回值上有些区别。
DOMNodeList 对象有一个函数和一个属性:
/* 属性,节点列表个数 */
readonly publicint $length ;
/* 方法获取第几个节点 */
DOMNode DOMNodelist::item ( int $index )

使用item函数获取的节点 DOMElement 对象 ,
可以使用 getAttribute 获取节点属性值,也可以使用 nodeValue 属性获取节点内容。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-45841-1-1.html 上篇帖子: PHP下载远程文件及获取文件内容 下篇帖子: php 安装pdo和pdo_mysql 扩展
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表