一、开源代码的问题

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. Bootstrap的介绍和响应式媒体查询

    Bootstrap的介绍 凡是使用过Bootstrap的开发者,都不在乎做这么两件事情:复制and粘贴.哈哈~,是的使用Bootstrap非常简单,但是在复制粘贴之前,需要先对Bootstrap的用法 ...

  2. jquery内容补充

    jquery除了咱们上面讲解的常用知识点之外,还有jquery 插件.jqueryUI知识点 jqueryUI 官网: https://jqueryui.com/ jqueryUI 中文网: http ...

  3. T-SQL 总结

    SP0_AddLinkedServer.sql [创建Linked SQL Server ] USE [master] GO ) drop procedure dbo.SP_Temp_AddLinke ...

  4. Thymeleaf系列五 迭代,if,switch语法

      1. 概述 这里介绍thymeleaf的编程语法,本节主要包括如下内容 迭代语法:th:each; iteration status 条件语法:th:if; th:unless switch语法: ...

  5. Numpy的ndarry:一种多维数组对象

    Numpy的ndarry:一种多维数组对象 Numpy最重要的一个特点就是其N维数组对象(即ndarry),该对象是一个快速而灵活的大数据集容器.你可以利用这种数组对整块数据执行一些数学运算,其语法跟 ...

  6. SQL Server数据库partition by 与ROW_NUMBER()函数使用详解[转]

    关于SQL的partition by 字段的一些用法心得 先看例子: if object_id('TESTDB') is not null drop table TESTDB create table ...

  7. JS判断不能为空实例代码

    JS判断不能为空实例代码.分享在此. 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" " ...

  8. plsql 中文乱码

    plsql 中文乱码, 中文还是用ZHS16GBK insert into tt(id,name) values('2','张三'); select * from nls_database_param ...

  9. 智能指针--C++

    智能指针(一):STL auto_ptr实现原理 智能指针实际上是一个类(class),里面封装了一个指针.它的用处是啥呢? 指针与内存 说到指针自然涉及到内存.我们如果是在堆栈(stack)中分配了 ...

  10. jsp生成好看的验证码

    这是一个Servlet,名字是ImageServlet package a; import java.awt.Color; import java.awt.Font; import java.awt. ...