PHP版的jQuery
个人认为,对于Web前端程序员和跟HTML和CSS打交道的人来说,jQuery是有史以来最伟大的发明。jQuery的出现使Web程序员的开发效率突飞猛进,不亚于工业革命给人类生产力带来的提升。
但问题在在于,只有前端程序员可以利用jQuery的强力,他们可以用它分析HTML,根据CCS类,HTML属性,CSS规则等各种选择器来查 询、获取、操作HTML里的任何一个元素。而作为后端(服务端)程序员来说,他们同样需要分析HTML内容,从HTML中提取符合要求的HTML片段、获 取某个符合条件的属性值等。
遇到这种情况,后端程序员通常的做法就是用正则表达式、或用XML解析器。这些做法非常的笨拙,不方便,效率低下。所以,对于在服务器端解析HTML,每个后端程序员都极力避免。
我是一个PHP程序员,最近就遇到了这样的一个任务,需要在服务器端解析HTML,将里面的标题名称和链接提取出来。最初我想开发一个小程序逐行分 析HTML,捕捉关键字,或用正则表达式。但简单分析了一下,这样做实在不可取。因为我也是个Web程序员,经常使用jQuery解析HTML页面上的内 容。如果这个任务放到浏览器端执行,太简单了,只需要一句代码:jQuery('.title').each(...);
,如何能在服务器端也能像jQuery那样进行HTML DOM查询呢?
实际上,在服务器端有不少具有jQuery功能的PHP程序库。在网上稍微做了点功夫,就搜到了10几个声称都能解析HTML的PHP工具。但经过试验,大部分都多少有这样或那样的缺陷,而且都有一个通病,就是中文乱码问题。最终,我选用了一个叫做phpQuery的工具包。
实际上,使用phpQuery这个PHP程序库也是很不情愿的,因为这个程序已经很多年没人维护更新了。但比起其它几个类似功能程序库,例如Zend_Dom、QueryPath、SimpleHtmlDom,它算是好的。
phpQuery的接口很丰富,但很简单。一个基本的用法是这样的:
$list = phpQuery::newDocumentFileHTML('http://www.webhek.com')->find('h2.title a');
foreach($list as $e) {
$title = $e->nodeValue; $url = $e->getAttribute('href');
}
上面的find()
方法返回的对象是PHP官方扩展库中的DOM对象,也就是说,phpQuery是一个基于PHP原生的DOM对象的HTML/XML解析器,这样做的好处是,效率很高。相反,像SimpleHtmlDom这样也是分析HTML/XML的程序库,但没有基于PHP原生DOM对象,当分析大数据量时,很容易产生性能问题,所以不推荐使用。
之前说了,所有的这样类似jQuery的能分析HTML DOM的PHP程序库都一个相同的通病:遇到中文会有乱码。我在使用phpQuery的过程中也遇到了这个问题。
首先PHP中的中文本身就是个问题,而PHP的DOM对 象处理中文的方式也是有争议的。官方文档是说,这个DOM扩展包使用的是UTF-8编码,当遇到 ISO-8859-1 编码的文本时,使用 utf8_encode() 和 utf8_decode() 编码和解码,遇到其它编码时,使用Iconv函数进行转码。但现实情况比这要复杂的多。网上有很多意见认为在遇到DOM乱码时,在HTML代码里的<title>
标记前加入<meta charset="utf-8">
就行了。但这种方法有时候也不灵。
我在解决phpQuery的中文乱码问题也是反复尝试才最后搞定的,没有任何理论依据。就像是有个程序员的笑话:这段代码不好用,我不知道为什么。这段代码好用,我也不知道为什么。:(
首先我是在台式机上开发测试的,是Window7,这种环境下会出现两种情况,一种情况是HTML的字符集是GBK/gb2312,一种情况是字符集是UTF-8。奇怪的是,两个同样是gb2312字符集的不同页面,用phpQuery解析后,一个会有乱码,一个没有乱码。同样,两个同样是UTF-8字符集的不同页面,也会出现这种情况。所有,对我来说,没有规律可言。我只能说,这两种方法能解决phpQuery使用过程中出现的乱码,但何时使用哪种?我不知道,你只能两个都试一下,会有一个好用。
所以,有乱码出现时,首先使用第一种方案:
//仍然使用上面的代码例子:
$list = phpQuery::newDocumentFileHTML('http://www.webhek.com')->find('h2.title a');
foreach($list as $e) {
$title = $e->nodeValue; //进行GBK转码
$title = iconv("UTF-8","GBK", $title);
}
如果不行,使用第二种方案:
//仍然使用上面的代码例子://指定GBK字符集参数
$list = phpQuery::newDocumentFileHTML('http://www.webhek.com','GBK')->find('h2.title a');
foreach($list as $e) {
$title = $e->nodeValue;
}
第一种方案中要使用iconv函数进行转码,第二种方案中不需要iconv转码,但需要在newDocumentFileHTML方法上提供“GBK字符集”。
还有一点很重要,在使用iconv函数转码是,一定要使用GBK,而不是使用gb2312,如果使用gb2312,iconv函数会很容易发生非法字符的报错,使得转码失败。
我以为有了这两种方案护航后,乱码问题再不会出现。可是,你要知道,做程序员很容易的心脏病的。当我把这些代码部署到linux服务器上时,乱码依旧。抓狂。
没办法,程序员的生活就是这样。经过调试,发现,在linux服务器上,采用第二种方案的部分网页仍然正常,但使用第一种方案时,需要去掉iconv函数转码。
下辈子一定不要做程序员。
- mysql启动后随即关闭问题解决(ibdata1文件损坏导致)
- webvirtmgr-重命名kvm虚拟机的名称
- Lucene 2.0最基本的入门代码
- 网站每日PV/IP统计/总带宽/URL统计脚本分享(依据网站访问日志)
- 查看服务器系统资源(cpu,内容)利用率前几位的进程的方法
- 腾讯云平台部总经理陈磊:大数据背后的技术支撑
- DataSet与Xml相互转化
- SqlTransaction事务使用示例
- nginx的web缓存服务环境部署记录
- nginx反向代理+缓存开启+url重写+负载均衡(带健康探测)的部署记录
- [转自blueidea]像table一样布局div Ⅰ
- 如何对动态创建控件进行验证以及在Ajax环境中的使用
- 升级个人网站框架组件IBatisNet+Castle
- 如何在多线程中调用winform窗体控件
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- WordPress 站点地址被恶意篡改的防护方案讨论
- 握草,你竟然在代码里下毒!
- MySQL 练习题和答案,以及运行结果截图
- 给你一个优秀的Django工程模板
- 纯css实现选项卡功能
- linux每日一练文件专题之常用文件命令(附昨日答案)
- 搞懂JavaScript全局变量与局部变量,看这篇文章就够了
- Day3-linux用户管理
- rbind的坑?
- 全文检索工具Lucene入门教程
- 数据库技术:数据库连接池,Commons DbUtils,批处理,元数据
- elasticsearch-快速入门
- 数据库技术:JDBC,预处理对象,事务控制
- elasticsearch-DSL高级查询语法
- 数据库技术:XML