php 获取网页标题(并解决编码问题)
用python做过爬虫,爬虫最让人头痛的问题主要有:网页编码、抓取效率、源站反爬策略,网页千千万,不同地区的网站使用的编码有时会不一样,当然了,即使同一个网站,也有可能使用了 gbk和utf-8两种或多于两种的编码,这完全取决于网页制作者的喜好,有时制作人员采用的编辑器,一个疏忽也会导致编码问题。
闲暇中,恰好手边没什么事,博客也该更新一下了,使用php获取网页的标题[title]部分,注意是title部分,这涉及到编码获取、编码转换及正则的使用。当然,这只是一个简单的方法,获取https协议的网页中会遇到麻烦。
下面的代码肯定是经不起网站的反爬策略,也不能用它完成一些高难度任务——比如处理coockies、验证、表单提交、文件上传等。要高度定制爬虫,更好的解决方案是使用 php 的cURL库,cURL 是一种功能强大的库,支持很多不同的协议、选项,能提供 URL 请求相关的各种细节信息,后话,暂且不讨论。
本文的目的只是讲述了一个获取网页标题的流程:访问URL->获取网页内容->使用正则提取标题->编码检测与转换->显示结果.
版本1 文件:class.Html.php:
<?php /** * User: jinaYang * blog: yangshengliang.com * Date: 2016/11/1 * Time: 18:53 */ namespace php\spider; class Html { public function getTitle() { $url = "http://jd.com"; $f = file_get_contents($url); preg_match('/<title>(?<title>.*?)<\/title>/si', $f, $title); //获取title的正则表达式 $encode = mb_detect_encoding($title['title'], array('GB2312','GBK','UTF-8', 'CP936')); //得到字符串编码 $file_charset = iconv_get_encoding()['internal_encoding']; //当前文件编码 if ( $encode != 'CP936' && $encode != $file_charset ) { return iconv($encode, $file_charset, $title['title']); } return $title['title']; } } $title = new Html(); echo $title ->getTitle(); ?>
得到结果,已经达到目的:
京东(JD.COM)-综合网购首选-正品低价、品质保障、配送及时、轻松购物!
美中不足:虽然得到了正确的结果,但是每次抓取一个网页的标题,都需要更改源代码。能不能再智能化一点?答案是肯定的,采用get方法,传入相应的 url值作为getTitle()的参数。需要采集某网页的标题时,直接在地址栏修改url地址就可以了。
版本2 文件:class.Html.php
<?php /** * User: jinaYang * blog: yangshengliang.com * Date: 2016/11/1 * Time: 18:53 */ namespace php\spider; header("Content-type:text/html;charset=utf-8"); class Html { public function getTitle($url) { $f = file_get_contents($url); preg_match('/<title>(?<title>.*?)<\/title>/si', $f, $title); $encode = mb_detect_encoding($title['title'], array('GB2312','GBK','UTF-8', 'CP936')); //得到字符串编码 $file_charset = iconv_get_encoding()['internal_encoding']; //当前文件编码 if ( $encode != 'CP936' && $encode != $file_charset) { return iconv($encode, $file_charset, $title['title']); } return $title['title']; } } $title = new Html(); echo $title ->getTitle($_GET['url']); ?>
使用方法:浏览器运行 class.Html.php?url=网页url
更多阅读
北漂鱼
2017年11月7日 上午9:56
为何我运行不出来,我也有以一种,比较简单的,不过只能读取http的对于加密的HTTPS就无法获取:
<?php
header('Content-Type:text/html;charset=utf-8');
$titrul="http://www.beipy.com";
//判断是否是加密协议
if(preg_match("/^(https:\/\/).*$/",$titrul)){
//返回提示
//去除字符串的前5个字符,
$mr="http".substr($titrul,5);
echo $mr;//打印显示url链接
$arr = file($mr);
if($arr){
foreach($arr as $a){
if(strchr($a,"”)){
$a = str_ireplace(“”,””,$a);
$a = str_ireplace(“”,””,$a);
echo $a;
break;
}
}
}
}
else{
// echo “链接错误”;
$arr = file($titrul);
if($arr){
foreach($arr as $a){
if(strchr($a,””)){
$a = str_ireplace(“”,””,$a);
$a = str_ireplace(“”,””,$a);
echo $a;
break;
}
}
}
}
?>
fedkey
2017年11月8日 下午8:24
代码有错误。
以马内利
2017年5月27日 下午5:32
万分感谢,终于找到可以使用的了谢谢!
fedkey
2017年5月28日 下午8:13
客气了