一、开源代码的问题

PHP爬虫(2中介绍了开源工程Sunra.PhpSimple.HtmlDomParser。在实际工作中发现一个问题,例如http://www.163.com的网页数据怎么也抓取不下来。

$url = "http://www.163.com";
$content = Http::request($url);
$dom = str_get_html($content);//dom返回值为false

检查simple_html_dom.php代码发现,

 if (empty($str) || strlen($str) > MAX_FILE_SIZE)
{
$dom->clear();
return false;
}

要判断加载字符串的长度。此处可以将MAX_FILE_SIZE修改更大一些,或者去除这个判断。

二、字符编码

网页抓取必然要处理网页内容,网页内容的编码有很多种,常见的UTF-8,GBK,GB2312等。通常处理的过程,首先判断字符编码,再转化成统一编码。

判断编码的代码,

function ws_mb_detect_encoding ($string, $enc=null, $ret=null) {       

        static $enclist = array( 

            'UTF-8', 'GBK', 'GB2312', 'GB18030'

        );
$result = false;
foreach ($enclist as $item) {
//$sample = iconv($item, $item, $string);
$sample = mb_convert_encoding($string,$item, $item);
if (md5($sample) == md5($string)) {
if ($ret === NULL) { $result = $item; } else { $result = true; }
break;
}
}
return $result;
}

转化成UTF-8编码

$html = mb_convert_encoding($html,"UTF-8",$enc);
//enc是ws_mb_detect_encoding返回值

下面的代码,是从一个导航页面,抓取全部链接,找到链接文档的title信息

<?php
Vendor('Sunra.PhpSimple.HtmlDomParser');
$url = "http://hao.360.cn/";
$html = file_get_html($url);
$links = $html->find('a');
$num = 0;
$array = array();
foreach ($links as $l) {
if(strpos($l->href,"http")===0)
{
$url = $l->href;
$pattern = "/(http|https):\/\/\S+?\//";//查找http,https开头
$ret = preg_match($pattern, $url,$m);
$url =$ret?$m[0]:$url;
if(!array_search($url, $array))
{
$array[] = $url;
}
if(count($array)>30)
{
break;
}
}
}
foreach ($array as $url) {
$html = false;
$num = 0;
while($html==false && $num<3)
{
$num++;
$html = \Home\Wsn\Http::request($url);
}
if($html == false)
{
echo "无法获取网页数据<br>";continue;
}
$enc = ws_mb_detect_encoding($html);
echo $enc."<br>";
if($enc==false)
{
echo "编码错误<br>";continue;
}
elseif($enc!='UTF-8')
{
$html = mb_convert_encoding($html,"UTF-8",$enc);
}
$dom = str_get_html($html);
$title = $dom->find('title',0);
if($title){
echo "标题".$title->innertext."<br>";
}
else{
echo "没找到标题<br>";
}
echo "<hr>";
}
?>

附录

封装好的HTTP类如下,喜欢的同学可以拿去直接使用。

<?php
  public static function request($url, $params = array(), $method = 'GET', $multi = false, $extheaders = array()) {
if (!function_exists('curl_init')) exit('Need to open the curl extension');
$method = strtoupper($method);
$ci = curl_init(); curl_setopt($ci, CURLOPT_USERAGENT, 'PHP-SDK OAuth2.0');
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($ci, CURLOPT_TIMEOUT, 3);
curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ci, CURLOPT_HEADER, false); $headers = (array)$extheaders;
switch ($method) {
case 'POST':
curl_setopt($ci, CURLOPT_POST, TRUE);
if (!empty($params)) {
if ($multi) {
foreach ($multi as $key => $file) {
$params[$key] = '@' . $file;
}
curl_setopt($ci, CURLOPT_POSTFIELDS, $params);
$headers[] = 'Expect: ';
} else {
curl_setopt($ci, CURLOPT_POSTFIELDS, http_build_query($params));
}
}
break;
case 'DELETE':
$method == 'DELETE' && curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
break;
case 'GET':
if (!empty($params)) {
$url = $url . (strpos($url, '?') ? '&' : '?')
. (is_array($params) ? http_build_query($params) : $params);
}
break;
}
curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($ci, CURLOPT_URL, $url); if ($headers) {
curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
} $response = curl_exec($ci);
curl_close($ci);
return $response;
}
?>

PHP爬虫(3)PHP DOM开源代码里的大坑和字符编码的更多相关文章

  1. halo的工作目录,有一个是在代码里配置的,硬编码了

    在HaloProperties.java中: /** * Work directory. */private String workDir = HaloConst.USER_HOME + " ...

  2. CWMP开源代码研究2——easycwmp安装和学习

    声明:本文是对开源程序代码学习和研究,严禁用于商业目的. 如有任何问题,欢迎和我交流.(企鹅号:408797506) 本文所有笔记和代码可以到csdn下载:http://download.csdn.n ...

  3. 使用SftpDrive+SourceInsight阅读开源代码

    在虚拟机环境下使用Linux编写和阅读代码,我之前一直是通过Xshell利用ssh登录至虚拟机从而在命令行下使用vim来进行的.目前有阅读开源代码的需要,虽然vim+ctags+cscope可以完成这 ...

  4. MIUI6&7桌面角标开源代码简介

    MIUI6&7桌面角标开源代码简介 MIUI6&7上重新设计了桌面app图标的角标显示,基本规则如下: 一.基本介绍 1.默认的情况 当app 向通知栏发送了一条通知 (通知不带进度条 ...

  5. C++开源代码项目汇总

    Google的C++开源代码项目 v8  -  V8 JavaScript EngineV8 是 Google 的开源 JavaScript 引擎.V8 采用 C++ 编写,可在谷歌浏览器(来自 Go ...

  6. [置顶] Java开源代码研究总结

          由于工作中的需要,最近在研究SNMP协议和利用snmp4j和snmp4j.agent(   http://www.snmp4j.org/ ),实现snmp的南向和北向功能. 结合以前看过的 ...

  7. Facebook在代码里下毒,百度身受重伤。。。

    白首相知犹按剑     前两天看到有朋友分享说,WordPress停用了react.今天,在逛知乎时看到了另一个问题别细看这图,我赌你看不懂... 嗯...用人话来说就是百度内部要求他们的程序猿不要再 ...

  8. 最大开源代码sourceforge 简介 及视音频方面常用的开源代码

    所有的音视频凯源代码在这里:http://sourceforge.net/directory/audio-video/os:windows/,你可以下载分析,视频不懂请发邮件给我,帮你分析. 0.视频 ...

  9. Google的C++开源代码项

    转:http://blog.csdn.net/wenrenhua08/article/details/40040903 v8  -  V8 JavaScript EngineV8 是 Google 的 ...

随机推荐

  1. C++ 构造函数_拷贝构造函数

    拷贝构造函数

  2. 面试总结之Database

    什么是数据库事务? 数据库事务_百度百科 https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BA%8B%E5%8A%A1/9744 ...

  3. UI“三重天”之Selenium(一)

    关注一下UI自动化,记一记笔记. UI自动化的优缺点: 关于UI自动化的优缺点想来大家都有了解,优点:解放人力(并不是完全解放),用机器(涵盖工具.脚本等)代替人工完成测试工作,将测试用例转化为脚本实 ...

  4. 如何在Solr中实现多core查询

    基于solr或者elasticsearch提供的多核,多索引,多shard等查询能力,一般都是由lucene提供的多索引查询的功能演化而来的,这个功能在单机版的lucene里面确实没有发挥多大的威力, ...

  5. canvas绘制曲线

    canvas绘制曲线 方法 quadraticCurveTo(cp1x, cp1y, x, y) 只有一个控制点的贝塞尔曲线(其实就是控制点分别与起始点和结束点连线的公切线) bezierCurveT ...

  6. Selenium2+python自动化63-简易项目搭建

    前言 到unittest这里基本上可以搭建一个简易的项目框架了,我们可以用一条run_main.py脚本去控制执行所有的用例,并生成报告,发送邮件一系列的动作 一.新建工程 1.打开pycharm左上 ...

  7. MySQL GTID (三)

    五.如何跳过一个GTID 环境见系列一 5.1 创建表,模拟数据 #主机上 create table t_test (id int primary key ,name varchar(10)); in ...

  8. docker国内registry

    cat /etc/docker/daemon.json {"registry-mirrors": ["http://4d6b2eb7.m.daocloud.io" ...

  9. 44. Wildcard Matching (String; DP, Back-Track)

    Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. ...

  10. qemu模拟器下编译运行基于riscv指令集的Linux操作系统

      基本原理: 在物理服务器Ubuntu14.04上安装qemu模拟器,模拟器中运行基于riscv指令集编译的linux镜像文件. 用到的工具包括: riscv-qemu(模拟器,可以模拟运行risc ...