您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

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

2024/6/7 23:32:54发布34次查看
php单线程实现并行抓取网页 本php教程将模拟并行抓取多个页面信息的过程,关键在于单线程的并行处理。
一般情况下,大家写抓取多个页面信息的程序都采用串行方案,但获取周期过长,不实用。于是我想到用curl 去并行抓取。但是,最后发现,那个虚拟服务器上没有curl,这真是让人纠结。于是,我决定改变思路,用单个线程也实现多个线程的效果。我想对网络编程有点
了解的人肯定知道io复用这个概念,当然php上也是支持的,而且,内部支持,不需要任何扩展。
可能有很多年编程经验的人对php的stream 函数可能不太了解。php的压缩文件流,文件流,tcp 协议下的应用 都封装成一个stream。所以,读本地文件
和读网络文件没有任何的差别。说了这样多,我想大家都基本上明白了,直接贴上代码吧:
代码比较的粗糙,如果大家要实际用的话,还是要处理一些细节问题。
代码
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]);
}
}
} else {//time out
echo timeout;
return false;
}
}
foreach ($result as $key => &$value)
{
if ($value) {
$value = explode(\r\n\r\n, $value, 2);
}
}
return $result;
}
$urls = array();
$urls[] = http://www.qq.com;
$urls[] = http://www.sina.com.cn;
$urls[] = http://www.sohu.com;
$urls[] = http://www.blue1000.com;
//并行的抓取
$t1 = microtime(true);
$result = http_multi_get($urls);
$t1 = microtime(true) - $t1;
var_dump(cost: . $t1);
//串行的抓取
$t1 = microtime(true);
foreach ($urls as $value)
{
file_get_contents($value);
}
$t1 = microtime(true) - $t1;
var_dump(cost: . $t1);
?>
最后运行的结果:
string 'cost: 3.2403128147125' (length=21)
string 'cost: 6.2333900928497' (length=21)
基本上是两倍的效率,当然,发现新浪非常的慢,要2.5s 左右,
基本上是被他给拖累了,360只要 0.2s
如果,所有网站都差不多的速度,并行的数目更大,那么差的倍数也就越大。
http://www.bkjia.com/phpjc/847205.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/847205.htmltecharticlephp单线程实现并行抓取网页 本php教程将模拟并行抓取多个页面信息的过程,关键在于单线程的并行处理。 一般情况下,大家写抓取多个页...
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product