PHP爬虫(3)PHP DOM开源代码里的大坑和字符编码
一、开源代码的问题
在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开源代码里的大坑和字符编码的更多相关文章
- halo的工作目录,有一个是在代码里配置的,硬编码了
在HaloProperties.java中: /** * Work directory. */private String workDir = HaloConst.USER_HOME + " ...
- CWMP开源代码研究2——easycwmp安装和学习
声明:本文是对开源程序代码学习和研究,严禁用于商业目的. 如有任何问题,欢迎和我交流.(企鹅号:408797506) 本文所有笔记和代码可以到csdn下载:http://download.csdn.n ...
- 使用SftpDrive+SourceInsight阅读开源代码
在虚拟机环境下使用Linux编写和阅读代码,我之前一直是通过Xshell利用ssh登录至虚拟机从而在命令行下使用vim来进行的.目前有阅读开源代码的需要,虽然vim+ctags+cscope可以完成这 ...
- MIUI6&7桌面角标开源代码简介
MIUI6&7桌面角标开源代码简介 MIUI6&7上重新设计了桌面app图标的角标显示,基本规则如下: 一.基本介绍 1.默认的情况 当app 向通知栏发送了一条通知 (通知不带进度条 ...
- C++开源代码项目汇总
Google的C++开源代码项目 v8 - V8 JavaScript EngineV8 是 Google 的开源 JavaScript 引擎.V8 采用 C++ 编写,可在谷歌浏览器(来自 Go ...
- [置顶] Java开源代码研究总结
由于工作中的需要,最近在研究SNMP协议和利用snmp4j和snmp4j.agent( http://www.snmp4j.org/ ),实现snmp的南向和北向功能. 结合以前看过的 ...
- Facebook在代码里下毒,百度身受重伤。。。
白首相知犹按剑 前两天看到有朋友分享说,WordPress停用了react.今天,在逛知乎时看到了另一个问题别细看这图,我赌你看不懂... 嗯...用人话来说就是百度内部要求他们的程序猿不要再 ...
- 最大开源代码sourceforge 简介 及视音频方面常用的开源代码
所有的音视频凯源代码在这里:http://sourceforge.net/directory/audio-video/os:windows/,你可以下载分析,视频不懂请发邮件给我,帮你分析. 0.视频 ...
- Google的C++开源代码项
转:http://blog.csdn.net/wenrenhua08/article/details/40040903 v8 - V8 JavaScript EngineV8 是 Google 的 ...
随机推荐
- cmd,amd,umd 模块写法
mark一篇感觉写的不错的cmd/amd/umd的模块写法 原文:https://github.com/banricho/webLog/issues/12 umd通用写法: // jQuery 2.2 ...
- Loadrunner11在新建Microsoft Word 报告时提示指定的转换无效
HP Loadrunner11中文教程的学习基本已经结束,最后困扰我的就是这个在创建Microsoft Word 报告时不停的提示“指定的转换无效”的问题.在网上搜索了好长时间,好多朋友回答说没有生成 ...
- springcloud(八) Hystrix监控
一.Feign项目Hystrix自带的监控 在feign项目pom.xml 添加: <!-- 1,使用 Hystrix的模块 hystrix-metrics-event-stream,就可将这些 ...
- Python web框架——Tornado
Tornado是一个Python Web框架和异步网络库,最初由FriendFeed开发.通过使用非阻塞网络I / O,Tornado可以扩展到数万个开放连接,使其成为需要长时间连接每个用户的长轮询, ...
- Request模块(八)
Requests: 让 HTTP 服务人类 虽然Python的标准库中 urllib2 模块已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests 自称 “ ...
- myeclipse通过数据表生成jpa或hibernate实体
1. 创建数据库连接 2. 选择表 3. 生成 hibernate mapping 4. 生产jpa
- C语言链表实现
#define _CRT_SECURE_NO_WARNINGS #include "stdio.h" #include "stdlib.h" typedef s ...
- Radial Blur
[Radial Blur] 核心代码如下: v2f vert (appdata_img v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.u ...
- tar使用
[tar使用] 1..tar.gz文件 压缩:tar -czvf dstFileName.tar.gz a.txt b.txt …… 解压:tar -xzvf fileName.tar.gz 2..t ...
- FP昨天的新单,今天交期回写到2020年
昨天新单6900000053,回写交期到2020年.在此视图查看此单回写的日期V_OUT_SHIPMENT_PLAN_TESTS,可看到日期是2020年. 1.检查OUT_SHIPMENT_PLAN表 ...