一直以来使用php解析html文档树都是一个难题。Simple HTML DOM parser 很好地解决了这个问题。可以通过这个php类来解析html文档,对其中的html元素进行操作 (PHP5+以上版本)。
解析器不仅仅只是帮助我们验证html文档;更能解析不符合W3C标准的html文档。它使用了类似jQuery的元素选择器,通过元素的id,class,tag等等来查找定位;同时还提供添加、删除、修改文档树的功能。和jq一样的操作还是很方便的。
有三种方式调用这个类:
从url中加载html文档
从字符串中加载html文档
从文件中加载html文档
01 |
<?php |
02 |
//
新建一个Dom实例 |
03 |
$html = new simple_html_dom(); |
04 |
05 |
//
从url中加载 |
06 |
$html->load_file(‘http://www.xxx.com‘); |
07 |
08 |
//
从字符串中加载 |
09 |
$html->load(‘<html><body>从字符串中加载html文档演示</body></html>‘); |
10 |
11 |
//从文件中加载 |
12 |
$html->load_file(‘path/file/test.html‘); |
13 |
?> |
查找html元素
可以使用find函数来查找html文档中的元素。返回的结果是一个包含了对象的数组。我们使用HTML DOM解析类中的函数来访问这些对象,下面给出几个示例
01 |
<?php |
02 |
03 |
//查找html文档中的超链接元素 |
04 |
$a = $html->find(‘a‘); |
05 |
06 |
//查找文档中第(N)个超链接,如果没有找到则返回空数组. |
07 |
$a = $html->find(‘a‘,
0); |
08 |
09 |
//
查找id为main的div元素 |
10 |
$main = $html->find(‘div[id=main]‘,0); |
11 |
12 |
//
查找所有包含有id属性的div元素 |
13 |
$divs = $html->find(‘div[id]‘); |
14 |
15 |
//
查找所有包含有id属性的元素 |
16 |
$divs = $html->find(‘[id]‘); |
17 |
?> |
01 |
<?php |
02 |
//
查找id=‘#container‘的元素 |
03 |
$ret = $html->find(‘#container‘); |
04 |
05 |
//
找到所有class=foo的元素 |
06 |
$ret = $html->find(‘.foo‘); |
07 |
08 |
//
查找多个html标签 |
09 |
$ret = $html->find(‘a,
img‘); |
10 |
11 |
//
还可以这样用 |
12 |
$ret = $html->find(‘a[title],
img[title]‘); |
13 |
?> |
01 |
<?php |
02 |
//
返回父元素 |
03 |
$e->parent; |
04 |
05 |
//
返回子元素数组 |
06 |
$e->children; |
07 |
08 |
//
通过索引号返回指定子元素 |
09 |
$e->children(0); |
10 |
11 |
//
返回第一个资源速 |
12 |
$e->first_child
(); |
13 |
14 |
//
返回最后一个子元素 |
15 |
$e->last
_child (); |
16 |
17 |
//
返回上一个相邻元素 |
18 |
$e->prev_sibling
(); |
19 |
20 |
//返回下一个相邻元素 |
21 |
$e->next_sibling
(); |
22 |
?> |
元素属性操作
使用简单的正则表达式来操作属性选择器。
[attribute] – 选择包含某属性的html元素
[attribute=value] – 选择所有指定值属性的html元素
[attribute!=value]- 选择所有非指定值属性的html元素
[attribute^=value] -选择所有指定值开头属性的html元素
[attribute$=value] 选择所有指定值结尾属性的html元素
[attribute*=value] -选择所有包含指定值属性的html元素
如何避免解析器消耗过多内存
有时候可能Simple HTML DOM解析器消耗内存过多。如果php脚本占用内存太多,会导致网站停止响应等一系列严重的问题。解决的方法也很简单,在解析器加载html文档并使用完成后,记得清理掉这个对象就可以了。
1 |
<?php |
2 |
$html->clear(); |
3 |
?> |
下面看看微博热词抓取的源码示例
01 |
<?php |
02 |
03 |
header(‘Content-Type:text/html;charset=gbk‘); |
04 |
include "simple_html_dom.php"; |
05 |
06 |
class Tmemcache
{ |
07 |
08 |
protected $memcache; |
09 |
10 |
function __construct($cluster)
{ |
11 |
$this->memcache
= new Memcache; |
12 |
foreach ($cluster[‘memcached‘] as $server)
{ |
13 |
$this->memcache->addServer($server[‘host‘], $server[‘port‘]); |
14 |
} |
15 |
} |
16 |
17 |
function fetch($cache_key)
{ |
18 |
return $this->memcache->get($cache_key); |
19 |
} |
20 |
21 |
function store($cache_key, $val, $expire =
7200) { |
22 |
$this->memcache->set($cache_key, $val,
MEMCACHE_COMPRESSED, $expire); |
23 |
} |
24 |
25 |
function flush()
{ |
26 |
$this->memcache->flush(); |
27 |
} |
28 |
29 |
function delete($cache_key, $timeout =
0) { |
30 |
$this->memcache->delete($cache_key, $timeout); |
31 |
} |
32 |
33 |
} |
34 |
35 |
function unicode_hex_2_gbk($name)
{ |
36 |
$a =
json_decode(‘{"a":"‘ . $name . ‘"}‘); |
37 |
if (isset($a)
&& is_object($a))
{ |
38 |
return iconv(‘UTF-8‘, ‘GBK//IGNORE‘, $a->a); |
39 |
return $a->a; |
40 |
} |
41 |
return null; |
42 |
} |
43 |
44 |
function curl_fetch($url, $time =
3) { |
45 |
$ch =
curl_init(); |
46 |
curl_setopt($ch,
CURLOPT_URL, $url); |
47 |
curl_setopt($ch,
CURLOPT_TIMEOUT, $time); |
48 |
curl_setopt($ch,
CURLOPT_RETURNTRANSFER, 1); |
49 |
50 |
$data =
curl_exec($ch); |
51 |
$errno =
curl_errno($ch); |
52 |
53 |
if ($errno >
0) { |
54 |
$err = "[CURL]
url:{$url} ; errno:{$errno} ; info:" .
curl_error($ch)
. ";"; |
55 |
echo $err; |
56 |
$data =
false; |
57 |
} |
58 |
59 |
curl_close($ch); |
60 |
return $data; |
61 |
} |
62 |
63 |
$cluster["memcached"]
= array( |
64 |
array("host" => "10.11.1.1", "port" =>
11211), |
65 |
); |
66 |
//$memcache
= new Tmemcache($cluster); |
67 |
$url = "http://s.weibo.com/top/summary?cate=total&key=event"; |
68 |
$cache_key =
md5("weibo" . $url); |
69 |
//$str
= $memcache->fetch($cache_key); |
70 |
//if
(!isset($_GET["nocache"]) && !empty($str)) { |
71 |
//
echo $str; |
72 |
//
exit; |
73 |
//} |
74 |
75 |
$content =
curl_fetch($url); |
76 |
if ($content ===
false) |
77 |
exit; |
78 |
79 |
$html =
str_get_html($content); |
80 |
$a = $html->find(‘script‘,
8); |
81 |
//测试 |
82 |
$a = str_replace(array(‘\\"‘, ‘\\/‘,
"\\n",
"\\t"),
array(‘"‘, ‘/‘, "", ""), $a); |
83 |
$pos = strpos($a, ‘<div
class="hot_ranklist">‘); |
84 |
$a = substr($a, $pos); |
85 |
//////// |
86 |
//echo
"<xmp>"; |
87 |
//echo
($a); |
88 |
//echo
"</xmp>"; |
89 |
$html =
str_get_html($a); |
90 |
$arr = array(); |
91 |
foreach ($html->find(‘table[id=event]‘,
0)->find(‘.rank_content‘) as $element)
{ |
92 |
$arr[]
= unicode_hex_2_gbk($element->find("a",
0)->plaintext); |
93 |
} |
94 |
$html->clear(); |
95 |
$str =
implode(",", $arr); |
96 |
//if
(!isset($_GET["nocache"])) |
97 |
//
$memcache->store($cache_key, $str, 3600); |
98 |
echo $str; |