php 获取网页标题(并解决编码问题)

作者: 杨圣亮 分类: php开发 发布时间: 2016-11-01 20:57:36

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

4条评论
  • 北漂鱼

    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;
    }
    }
    }
    }
    ?>

    1. fedkey

      2017年11月8日 下午8:24

      代码有错误。

  • 以马内利

    2017年5月27日 下午5:32

    万分感谢,终于找到可以使用的了谢谢!

    1. fedkey

      2017年5月28日 下午8:13

      客气了

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

  −  1  =  4

微信