★PHP单线程实现并行抓取网页[1]

2013 年 9 月 11 日5110

【BK网络学院 - PHP】
本PHP教程将模拟并行抓取多个页面信息的过程,关键在于单线程的并行处理。

一般情况下,大家写抓取多个页面信息的程序都采用串行方案,但获取周期过长,不实用。于是我想到用curl 去并行抓取。但是,最后发现,那个虚拟服务器上没有curl,这真是让人纠结。于是,我决定改变思路,用单个线程也实现多个线程的效果。我想对网络编程有点

了解的人肯定知道IO复用这个概念,当然PHP上也是支持的,而且,内部支持,不需要任何扩展。

可能有很多年编程经验的人对PHP的stream 函数可能不太了解。PHP的压缩文件流,文件流,tcp 协议下的应用 都封装成一个stream。所以,读本地文件

和读网络文件没有任何的差别。说了这样多,我想大家都基本上明白了,直接贴上代码吧:

代码比较的粗糙,如果大家要实际用的话,还是要处理一些细节问题。

代码

php
function http_get_open($url)
{
$url = parse_url($url);
if (empty($url['host'])) {
return false;
}
$host = $url['host'];
if (empty($url['path'])) {
$url['path'] = "/";
}
$get = $url['path'] . "?" . @$url['query'];
$fp = stream_socket_client("tcp://{$host}:80", $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)
\n";
return false;
} else {
fwrite($fp, "GET {$get} HTTP/1.0\r\nHost: {$host}\r\nAccept: */*\r\n\r\n");
}
return $fp;
}

function http_multi_get($urls)
{
$result = array();
$fps = array();
foreach ($urls as $key => $url)
{
$fp = http_get_open($url);
if ($fp === false) {
$result[$key] = false;
} else {
$result[$key] = '';
$fps[$key] = $fp;
}
}
while (1)
{
$reads = $fps;
if (empty($reads)) {
break;
}
if (($num = stream_select($reads, $w = null, $e = null, 30)) === false ) {
echo "error";
return false;
} else if ($num > 0) {//can read
foreach ($reads as $value)
{
$key = array_search($value, $fps);
if (!feof($value)) {
$result[$key] .= fread($value, 128);
} else {
unset($fps[$key]);
}
}

PHP教学:实现汉字转区位码的示例代码

2011-01-25

Windows7系统环境安装配置PHP开发环境

2011-01-25

PHP实例:国际标准书号ISBN码校验函数

2011-01-25

PHP JSON格式数据交互实例详解

2011-01-25

Windows PHP环境搭建与配置的注意事项

2011-01-25

eclipse下php环境配置及调试配置的方法

2011-01-17

php中如何判断中英文字符

2011-01-17

PHP单线程实现并行抓取网页

2011-01-17

0 0