PHP 正则匹配提取网页内容
如果要提取<div class="xxx" id="yyy">之间的网页内容,用 preg_match不用preg_match_all
如果要提取<div>里面的所有的 <li></li>标签中的内容,可以用preg_match_all
示例:提取IP地址的地理位置
需求分析:
浏览器打开: http://www.ip138.com/ips138.asp?ip=218.30.180.177
需提取结果:提取下图中的绿色字体部分
用浏览器的开发者工具分析,要提取绿色字体样式如下:
代码实现:
<?php function check_ip_ip138($ip='218.30.180.177') { $url = 'http://www.ip138.com/ips138.asp?ip=' . $ip; echo "<br><br> url : " . $url; $ch = curl_init(); $header = array(); array_push($header, 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36'); array_push($header, 'Referer:' . $url); array_push($header, 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'); array_push($header, 'upgrade-insecure-requests:1'); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 1); //0表示不输出Header,1表示输出 curl_setopt($ch, CURLOPT_NOBODY, 0); //0表示不输出Body,1表示输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); // $output = file_get_contents($url); // also is ok $output = mb_convert_encoding($output, "utf-8", "gbk"); // 提取 <ul> $pattern = '/<ul class="ul1">(.+?)<\/ul>/is'; preg_match($pattern, $output, $match); echo "<br><br>match: <br>"; var_dump($match); echo "<br><br>match[1]: <br>"; var_dump($match[1]); // 提取 <li> $pattern_2 = '/<li>(.+?)<\/li>/is'; preg_match_all($pattern_2, $match[1], $match_2); echo "<br><br>match_2: <br>"; var_dump($match_2); echo "<br><br>match_2[1]: <br>"; var_dump($match_2[1]); $match_2_values = ""; foreach ($match_2[1] as $key => $value) { // 提取绿色字体冒号(:)后的字体 $match_2_values = $match_2_values . explode(":", $value)[1] . "|"; } // 去掉末尾多余的一个"|" $match_2_values = substr($match_2_values, 0, -1); echo "<br><br>match_2_values: " . $match_2_values; } check_ip_ip138(); ?>
运行结果:
url : http://www.ip138.com/ips138.asp?ip=218.30.180.177 match: array (size=2) 0 => string '<ul class="ul1"><li>本站数据:北京市北京市 电信</li><li>参考数据1:北京北京 电信</li><li>参考数据2:中国 电信</li></ul>' (length=154) 1 => string '<li>本站数据:北京市北京市 电信</li><li>参考数据1:北京北京 电信</li><li>参考数据2:中国 电信</li>' (length=133) match[1]: <li>本站数据:北京市北京市 电信</li><li>参考数据1:北京北京 电信</li><li>参考数据2:中国 电信</li>' (length=133) match_2: array (size=2) 0 => array (size=3) 0 => string '<li>本站数据:北京市北京市 电信</li>' (length=50) 1 => string '<li>参考数据1:北京北京 电信</li>' (length=45) 2 => string '<li>参考数据2:中国 电信</li>' (length=38) 1 => array (size=3) 0 => string '本站数据:北京市北京市 电信' (length=41) 1 => string '参考数据1:北京北京 电信' (length=36) 2 => string '参考数据2:中国 电信' (length=29) match_2[1]: array (size=3) 0 => string '本站数据:北京市北京市 电信' (length=41) 1 => string '参考数据1:北京北京 电信' (length=36) 2 => string '参考数据2:中国 电信' (length=29) match_2_values: 北京市北京市 电信|北京北京 电信|中国 电信
上图可见,提取的绿色字体如下:
match_2_values: 北京市北京市 电信|北京北京 电信|中国 电信
正确提取绿色字体成功!
总结:
上述示例中,既用到了preg_match,也用到了preg_match_all,区别是:
preg_match,用于提取单个特定元素,例如:<ul class="ul1">,<div id="yyy">等
preg_match_all,用于提取多个类似元素,例如:<li>,<td>等
并且,preg_match 和 preg_match_all 提取出的数组元素,第一个元素(下标为0)是完全匹配(包含<ul>或<li>),第二个(下标为1)才是里面内容匹配,细心的可能发现了,代码实现里,用的都是第二个元素(下标为1),例如:$match[1] 和 $match_2[1],感兴趣的可以自己用浏览器开发者工具进行调试。
下面给出我调试时的分析结果:
参考推荐:
PHP 获取网页标题(title)、描述(description)、关键字(keywords)等meta信息
版权所有: 本文系米扑博客原创、转载、摘录,或修订后发表,最后更新于 2019-01-03 19:35:59
侵权处理: 本个人博客,不盈利,若侵犯了您的作品权,请联系博主删除,莫恶意,索钱财,感谢!
转载注明: PHP 正则匹配提取网页内容 (米扑博客)