一、开源代码的问题

在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. Java 判断是否包含指定的子串 contains()

    Java 手册 contains public boolean contains(CharSequence s) 当且仅当此字符串包含指定的 char 值序列时,返回 true. 参数: s - 要搜 ...

  2. [html] charset

    UTF-8是全球通用的,GB2312一般是简体中文,GBK在他的范围上扩展了繁体中文,适合香港台湾. 页面透明效果 CSS: opacity:0.1;filter: Alpha(Opacity=10, ...

  3. Chrome JS断点调试技巧

    Chrome调试折腾记_(2)JS断点调试技巧 技巧一:格式化压缩代码 技巧二:快速跳转到某个断点的位置 技巧三:查看断点内部的作用范围[很实用] 技巧4:监听事件断点 技巧5:DOM及 XHR监听跳 ...

  4. solr精确查询,查询关键字分词后,指定满足匹配所有

    一.solr查询,查询配置了查询分词器的字段,默认会对查询关键字做分词处理 1.如查询关键字F1501ZY000011,使用solr7自带的中文分词器,默认会分词为:f,1501,zy,000011 ...

  5. 好记性不如烂笔头--linux学习笔记9练手写个shell脚本

    #!/bin/bash #auto make install httpd #by authors baker95935 #httpd define path variable H_FILES=http ...

  6. 3.Ehcache中储存缓存的方式

    转自:https://www.cnblogs.com/crazylqy/p/4238148.html 目录 1     堆内存(MemoryStore) 1.1     指定可用内存 1.2      ...

  7. django框架 input 文本框 单选框 多选框 上传文件 等数据传输后台的程序 request.getlist接收多个结果 obj.chunks 用于文件传输 enctype="multipart/form-data文件传输必备表头

    在上一个博客中,我们学习了如果创建django,这里我们主要讲如何把数据传给后台 在url文件中, 从app01中导入views, 以及创建url(r'^login/', views.login) f ...

  8. zookeeper 分布式计数器

    分布式计数器的思路是:指定一个Zookeeper数据节点作为计数器,多个应用实例在分布式锁的控制下,通过更新该数据节点的内容来实现计数功能. Curator中封装了实现,例如 DistributedA ...

  9. 迷你MVVM框架 avalonjs 学习教程6、插入移除处理

    ms-if是属于流程绑定的一种,如果表达式为真值那么就将当前元素输出页面,不是就将它移出DOM树.它的效果与上一章节的ms-visible效果看起来相似的,但它会影响到:empty伪类,并能更节约性能 ...

  10. 10G个64bit整数,找出中位数

    [10G个64bit整数,找出中位数] 题目:在一个文件中有10G个64bit整数,乱序排列,要求找出中位数.内存限制为2G. 解法:内存限制为2G表面上是限制,实际上是一种提示,在提示我们如何利用2 ...