php多线程抓取多个网页

php多线程抓取多个网页

php多线程抓取多个网页(php结合curl实现多线程实现抓取收获的方法总结)

网站优化优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2021-12-13 01:04 • 来自相关话题

  php多线程抓取多个网页(php结合curl实现多线程实现抓取收获的方法总结)
  今天和大家聊聊PHP中如何使用curl进行多线程。很多人可能不太了解。为了让大家更加了解,小编为大家总结了以下内容。希望大家可以关注这篇文章。文章你可以有所收获。
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  $urls = array(
'https://www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
); // 设置要抓取的页面URL
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  $urls = array(
'https://www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
);
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  $urls=array(
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);
  看完上面的内容,你是不是对PHP中如何使用curl进行多线程爬取有了进一步的了解?如果您想了解更多知识或相关内容,请关注易速云行业资讯频道,感谢您的支持。 查看全部

  php多线程抓取多个网页(php结合curl实现多线程实现抓取收获的方法总结)
  今天和大家聊聊PHP中如何使用curl进行多线程。很多人可能不太了解。为了让大家更加了解,小编为大家总结了以下内容。希望大家可以关注这篇文章。文章你可以有所收获。
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  $urls = array(
'https://www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
); // 设置要抓取的页面URL
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  $urls = array(
'https://www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
);
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  $urls=array(
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);
  看完上面的内容,你是不是对PHP中如何使用curl进行多线程爬取有了进一步的了解?如果您想了解更多知识或相关内容,请关注易速云行业资讯频道,感谢您的支持。

php多线程抓取多个网页(php中curl_multi()的速度比较_init)

网站优化优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2021-12-02 20:13 • 来自相关话题

  php多线程抓取多个网页(php中curl_multi()的速度比较_init)
  本文介绍了 PHP 使用 curl_init() 和 curl_multi_init() 多线程的速度对比。分享给大家,供大家参考,如下:
  php中的curl_init()有很大的作用,尤其是在爬取网页内容或者文件信息的时候。比如curl_init()的强大在之前的文章《php使用curl进行头部检测和GZip压缩》中介绍过。
  curl_init() 以单线程模式处理事情。如果需要使用多线程模式进行事务处理,那么php为我们提供了一个函数curl_multi_init(),就是多线程模式处理事务的功能。
  curl_init()和curl_multi_init()的速度对比
  curl_multi_init() 多线程可以提高网页的处理速度吗?今天我将通过实验来验证这个问题。
  我今天的测试很简单,就是抓取网页内容,连续抓取5次,分别使用curl_init()和curl_multi_init()函数来完成,记录下两者的耗时,以及将它们进行比较得出结论。
  首先,使用 curl_init() 在单个线程中抓取网页内容 5 次。
  程序代码如下:
  然后,使用 curl_multi_init() 多线程连续抓取网页内容 5 次。
  代码显示如下:
<p> 查看全部

  php多线程抓取多个网页(php中curl_multi()的速度比较_init)
  本文介绍了 PHP 使用 curl_init() 和 curl_multi_init() 多线程的速度对比。分享给大家,供大家参考,如下:
  php中的curl_init()有很大的作用,尤其是在爬取网页内容或者文件信息的时候。比如curl_init()的强大在之前的文章《php使用curl进行头部检测和GZip压缩》中介绍过。
  curl_init() 以单线程模式处理事情。如果需要使用多线程模式进行事务处理,那么php为我们提供了一个函数curl_multi_init(),就是多线程模式处理事务的功能。
  curl_init()和curl_multi_init()的速度对比
  curl_multi_init() 多线程可以提高网页的处理速度吗?今天我将通过实验来验证这个问题。
  我今天的测试很简单,就是抓取网页内容,连续抓取5次,分别使用curl_init()和curl_multi_init()函数来完成,记录下两者的耗时,以及将它们进行比较得出结论。
  首先,使用 curl_init() 在单个线程中抓取网页内容 5 次。
  程序代码如下:
  然后,使用 curl_multi_init() 多线程连续抓取网页内容 5 次。
  代码显示如下:
<p>

php多线程抓取多个网页(phpcurl_exec()并发抓取网页内容_multi())

网站优化优采云 发表了文章 • 0 个评论 • 73 次浏览 • 2021-12-01 16:06 • 来自相关话题

  php多线程抓取多个网页(phpcurl_exec()并发抓取网页内容_multi())
  php curl_multi_exec() 并发抓取网页内容
  php是单线程语言,所以在某些方面速度不如java,java是多线程语言。毕竟主要方面不在这里。。不过php也有自己的多线程(实际上是并发)方法——curl_multi_exec()。
  我们可以使用curl来获取网页的内容(如果你不懂curl,可以找个简单的例子看看),但是如果同时获取多个网页的内容,速度是不理想。这时候 curl_multi_exec() 就可以发挥作用了。
  以下是我爬取优酷内容的例子:
  
function async_get_url($url_array, $wait_usec = 0)
{
if (!is_array($url_array))
return false;

$wait_usec = intval($wait_usec);

$data = array();
$handle = array();
$running = 0;

$mh = curl_multi_init(); // multi curl handler

$i = 0;
foreach($url_array as $url) {
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return don&#39;t print
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_USERAGENT, &#39;Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)&#39;);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
curl_setopt($ch, CURLOPT_MAXREDIRS, 7);

curl_multi_add_handle($mh, $ch); // 把 curl resource 放進 multi curl handler 裡

$handle[$i++] = $ch;
}

/* 此做法就可以避免掉 CPU loading 100% 的問題 */
// 參考自: http://www.hengss.com/xueyuan/ ... .html

do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
/*
// 感謝 Ren 指點的作法. (需要在測試一下)
// curl_multi_exec的返回值是用來返回多線程處裡時的錯誤,正常來說返回值是0,也就是說只用$mrc捕捉返回值當成判斷式的迴圈只會運行一次,而真的發生錯誤時,有拿$mrc判斷的都會變死迴圈。
// 而curl_multi_select的功能是curl發送請求後,在有回應前會一直處於等待狀態,所以不需要把它導入空迴圈,它就像是會自己做判斷&自己決定等待時間的sleep()。
/* 讀取資料 */
foreach($handle as $i => $ch) {
$content = curl_multi_getcontent($ch);
$data[$i] = (curl_errno($ch) == 0) ? $content : false;
}

/* 移除 handle*/
foreach($handle as $ch) {
curl_multi_remove_handle($mh, $ch);
}

curl_multi_close($mh);

return $data;
}

$url="http://m.youku.com/wap/";
$reg1="/(.*?)/i";//获取视频链接
$reg2="/]*)\s*class=\"imgdetail\"\s*src=(&#39;|\")([^&#39;\"]+)(&#39;|\")/i";
$reg3="";
$reg4= "/.*?/i";//获取视频标题(备选)

// 创建两个cURL资源
$ch1 = curl_init();
$resultArray=array();//装载所有数据的数组
$ch=array();
//$ch2 = curl_init();
// 指定URL和适当的参数
curl_setopt($ch1, CURLOPT_URL,$url);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_HEADER, 0);
$content=curl_exec($ch1);
curl_close($ch1);
//$content=file_get_contents($url);
preg_match_all($reg1, $content,$matches);
$video=$matches[0];//首页视频的链接
//print_r($video);
foreach ($video as $a=>$key)
{
$position=strpos($key, "href");
$substring=substr($key, $position+11);
$pos=strpos($substring, ">");
$link=substr($substring, 0,$pos-1);
$nextUrl[$a]=$url.$link;
}
//$url_array = array(
// &#39;http://www.google.com&#39;,
// &#39;http://www.baidu.com&#39;,
//);
//print_r($nextUrl);
//print_r(async_get_url($nextUrl));
//并发获取所有网页的内容
$allData=async_get_url($nextUrl);
foreach ($allData as $page)
{
//获取视频图片
preg_match_all($reg2, $page,$img);
$img_arr=$img[0];
foreach ($img_arr as $arr)
{
$position=strpos($arr, "src");
$sub=substr($arr, $position+5);
$pos=strpos($sub, "\"");
$last=substr($sub, 0,$pos);
}
//获取视频高清点播地址
preg_match_all($reg3, $page,$vids);
$video_arr=$vids[0];
$vid=$video_arr[0];
$position=strpos($vid, "href");
$v_string=substr($vid, $position+11);
$pos=strpos($v_string, "\"");
$add=substr($v_string, 0,$pos);
$video_url=$url.$add;
//获取视频的标题
preg_match_all($reg4, $page,$match);
$title=$match[0];
//print_r($er);
$r=serialize($title);
$position=mb_strpos($r, "");
$sub=substr($r, 0,$position);
$pos=mb_strrpos($sub, ">");
$til=substr($sub, $pos+1);

//整合到一个数组
$subArray=array(&#39;image&#39;=>$last,&#39;video&#39;=>$video_url,&#39;title&#39;=>$til);
array_push($resultArray, $subArray);
}
echo json_encode($resultArray);</p>
  重点是函数async_get_url
  
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
  上一段是重点和难点。
<p>第一个循环,$mrc == CURLM_CALL_MULTI_PERFORM(-1)表示还有句柄资源没有处理,所以继续$mrc = curl_multi_exec($mh, $active) 查看全部

  php多线程抓取多个网页(phpcurl_exec()并发抓取网页内容_multi())
  php curl_multi_exec() 并发抓取网页内容
  php是单线程语言,所以在某些方面速度不如java,java是多线程语言。毕竟主要方面不在这里。。不过php也有自己的多线程(实际上是并发)方法——curl_multi_exec()。
  我们可以使用curl来获取网页的内容(如果你不懂curl,可以找个简单的例子看看),但是如果同时获取多个网页的内容,速度是不理想。这时候 curl_multi_exec() 就可以发挥作用了。
  以下是我爬取优酷内容的例子:
  
function async_get_url($url_array, $wait_usec = 0)
{
if (!is_array($url_array))
return false;

$wait_usec = intval($wait_usec);

$data = array();
$handle = array();
$running = 0;

$mh = curl_multi_init(); // multi curl handler

$i = 0;
foreach($url_array as $url) {
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return don&#39;t print
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_USERAGENT, &#39;Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)&#39;);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
curl_setopt($ch, CURLOPT_MAXREDIRS, 7);

curl_multi_add_handle($mh, $ch); // 把 curl resource 放進 multi curl handler 裡

$handle[$i++] = $ch;
}

/* 此做法就可以避免掉 CPU loading 100% 的問題 */
// 參考自: http://www.hengss.com/xueyuan/ ... .html

do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
/*
// 感謝 Ren 指點的作法. (需要在測試一下)
// curl_multi_exec的返回值是用來返回多線程處裡時的錯誤,正常來說返回值是0,也就是說只用$mrc捕捉返回值當成判斷式的迴圈只會運行一次,而真的發生錯誤時,有拿$mrc判斷的都會變死迴圈。
// 而curl_multi_select的功能是curl發送請求後,在有回應前會一直處於等待狀態,所以不需要把它導入空迴圈,它就像是會自己做判斷&自己決定等待時間的sleep()。
/* 讀取資料 */
foreach($handle as $i => $ch) {
$content = curl_multi_getcontent($ch);
$data[$i] = (curl_errno($ch) == 0) ? $content : false;
}

/* 移除 handle*/
foreach($handle as $ch) {
curl_multi_remove_handle($mh, $ch);
}

curl_multi_close($mh);

return $data;
}

$url="http://m.youku.com/wap/";
$reg1="/(.*?)/i";//获取视频链接
$reg2="/]*)\s*class=\"imgdetail\"\s*src=(&#39;|\")([^&#39;\"]+)(&#39;|\")/i";
$reg3="";
$reg4= "/.*?/i";//获取视频标题(备选)

// 创建两个cURL资源
$ch1 = curl_init();
$resultArray=array();//装载所有数据的数组
$ch=array();
//$ch2 = curl_init();
// 指定URL和适当的参数
curl_setopt($ch1, CURLOPT_URL,$url);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_HEADER, 0);
$content=curl_exec($ch1);
curl_close($ch1);
//$content=file_get_contents($url);
preg_match_all($reg1, $content,$matches);
$video=$matches[0];//首页视频的链接
//print_r($video);
foreach ($video as $a=>$key)
{
$position=strpos($key, "href");
$substring=substr($key, $position+11);
$pos=strpos($substring, ">");
$link=substr($substring, 0,$pos-1);
$nextUrl[$a]=$url.$link;
}
//$url_array = array(
// &#39;http://www.google.com&#39;,
// &#39;http://www.baidu.com&#39;,
//);
//print_r($nextUrl);
//print_r(async_get_url($nextUrl));
//并发获取所有网页的内容
$allData=async_get_url($nextUrl);
foreach ($allData as $page)
{
//获取视频图片
preg_match_all($reg2, $page,$img);
$img_arr=$img[0];
foreach ($img_arr as $arr)
{
$position=strpos($arr, "src");
$sub=substr($arr, $position+5);
$pos=strpos($sub, "\"");
$last=substr($sub, 0,$pos);
}
//获取视频高清点播地址
preg_match_all($reg3, $page,$vids);
$video_arr=$vids[0];
$vid=$video_arr[0];
$position=strpos($vid, "href");
$v_string=substr($vid, $position+11);
$pos=strpos($v_string, "\"");
$add=substr($v_string, 0,$pos);
$video_url=$url.$add;
//获取视频的标题
preg_match_all($reg4, $page,$match);
$title=$match[0];
//print_r($er);
$r=serialize($title);
$position=mb_strpos($r, "");
$sub=substr($r, 0,$position);
$pos=mb_strrpos($sub, ">");
$til=substr($sub, $pos+1);

//整合到一个数组
$subArray=array(&#39;image&#39;=>$last,&#39;video&#39;=>$video_url,&#39;title&#39;=>$til);
array_push($resultArray, $subArray);
}
echo json_encode($resultArray);</p>
  重点是函数async_get_url
  
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
  上一段是重点和难点。
<p>第一个循环,$mrc == CURLM_CALL_MULTI_PERFORM(-1)表示还有句柄资源没有处理,所以继续$mrc = curl_multi_exec($mh, $active)

php多线程抓取多个网页(Python作为一门功能强大的脚本语言来说 )

网站优化优采云 发表了文章 • 0 个评论 • 69 次浏览 • 2021-11-29 15:03 • 来自相关话题

  php多线程抓取多个网页(Python作为一门功能强大的脚本语言来说
)
  Python 作为一种强大的脚本语言,经常被用来编写爬虫程序。下面是Python爬虫多线程爬取代理服务器
  首先,我通过谷歌找到了收录代理服务器地址的网页。我选择从这个 网站 中抓取它。我在上面抓取了 800 个代理(选择了 8 个页面)
  部分日志:
  
目标网站: http://www.cnproxy.com/proxy1.html
目标网站: http://www.cnproxy.com/proxy2.html
目标网站: http://www.cnproxy.com/proxy3.html
目标网站: http://www.cnproxy.com/proxy4.html
目标网站: http://www.cnproxy.com/proxy5.html
目标网站: http://www.cnproxy.com/proxy6.html
目标网站: http://www.cnproxy.com/proxy7.html
目标网站: http://www.cnproxy.com/proxy8.html
..........总共抓取了800个代理..........
..........总共有478个代理通过校验.........
173.213.113.111:8089 United States 0.341555833817
173.213.113.111:3128 United States 0.347477912903
210.101.131.232:8080 韩国 首尔 0.418715000153
...... 查看全部

  php多线程抓取多个网页(Python作为一门功能强大的脚本语言来说
)
  Python 作为一种强大的脚本语言,经常被用来编写爬虫程序。下面是Python爬虫多线程爬取代理服务器
  首先,我通过谷歌找到了收录代理服务器地址的网页。我选择从这个 网站 中抓取它。我在上面抓取了 800 个代理(选择了 8 个页面)
  部分日志:
  
目标网站: http://www.cnproxy.com/proxy1.html
目标网站: http://www.cnproxy.com/proxy2.html
目标网站: http://www.cnproxy.com/proxy3.html
目标网站: http://www.cnproxy.com/proxy4.html
目标网站: http://www.cnproxy.com/proxy5.html
目标网站: http://www.cnproxy.com/proxy6.html
目标网站: http://www.cnproxy.com/proxy7.html
目标网站: http://www.cnproxy.com/proxy8.html
..........总共抓取了800个代理..........
..........总共有478个代理通过校验.........
173.213.113.111:8089 United States 0.341555833817
173.213.113.111:3128 United States 0.347477912903
210.101.131.232:8080 韩国 首尔 0.418715000153
......

php多线程抓取多个网页(这里有新鲜出炉的PHP教程,程序狗速度看过来! )

网站优化优采云 发表了文章 • 0 个评论 • 58 次浏览 • 2021-11-24 13:02 • 来自相关话题

  php多线程抓取多个网页(这里有新鲜出炉的PHP教程,程序狗速度看过来!
)
  这里有新鲜的PHP教程,看看程序狗的速度!
  PHP 开源脚本语言 PHP(外文名:Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用的开源脚本语言。语法吸收了C语言、Java和Perl的特点,入门门槛低,易学,应用广泛。主要适用于Web开发领域。PHP 的文件扩展名为 php。
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,开发爬虫程序的效率不高,所以经常需要使用 Curl Multi Functions。实现多线程并发访问多个URL地址的函数,实现多线程并发抓取网页或下载文件
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  
$urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  
$urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  
$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh); 查看全部

  php多线程抓取多个网页(这里有新鲜出炉的PHP教程,程序狗速度看过来!
)
  这里有新鲜的PHP教程,看看程序狗的速度!
  PHP 开源脚本语言 PHP(外文名:Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用的开源脚本语言。语法吸收了C语言、Java和Perl的特点,入门门槛低,易学,应用广泛。主要适用于Web开发领域。PHP 的文件扩展名为 php。
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,开发爬虫程序的效率不高,所以经常需要使用 Curl Multi Functions。实现多线程并发访问多个URL地址的函数,实现多线程并发抓取网页或下载文件
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  
$urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  
$urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  
$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);

php多线程抓取多个网页(小结(一)并发的划分)

网站优化优采云 发表了文章 • 0 个评论 • 83 次浏览 • 2021-11-20 16:23 • 来自相关话题

  php多线程抓取多个网页(小结(一)并发的划分)
  本节试图解释更深层次的东西。
  sqlmap 在哪里使用多线程
  多线程并发可以加速IO密集型操作,但是sqlmap在哪里使用多线程呢?是时候进行测试了吗?是时候查表了,还是……?带着这个问题,接下来进行分析。
  sqlmap的一些技术细节(1)已经分析了多线程是如何实现的,并将线程封装到函数runThreads中,所以只需要全局搜索这个函数就可以找到使用多线程的地方。
  按场景分,一共发现了三个地方,分别用于注入、爆破、爬行,所以下面三个总结介绍一下它的作用。
  爆破
  在文件位置 lib/utils/brute.py 中找到两个地方
  
  根据函数名,可以猜测主要是爆表和爆表中的字段。具体实现比较简单。每个线程都会从字典中获取一个内容来运行。字典是基于文件的。另外提一下是不是检测表还是检测字段,sqlmap也会把原网页中的一些字段设置为字典。具体请看下面的函数实现。
  def getPageWordSet(page):
"""
Returns word set used in page content
>>> sorted(getPageWordSet(u&#39;foobartest&#39;))
[u&#39;foobar&#39;, u&#39;test&#39;]
"""
retVal = set()
# only if the page&#39;s charset has been successfully identified
if isinstance(page, unicode):
retVal = set(_.group(0) for _ in re.finditer(r"\w+", getFilteredPageContent(page)))
return retVal
  爬虫
  爬虫在爬取和采集 URL 时也是多线程的。sqlmap 定义了一个未处理的集合集合,多个线程从中弹出数据。
  参考sqlmap的技术细节(1)中的线程设计章节,sqlmap在底层实现了线程安全,所以这些细节不需要考虑。主要的爬取规则也是基于BeautifulSoup寻找标签。 ,判断URL满足条件的规则是检查同一个Host。
  def checkSameHost(*urls):
"""
Returns True if all provided urls share that same host
>>> checkSameHost(&#39;http://www.target.com/page1.php?id=1&#39;, &#39;http://www.target.com/images/page2.php&#39;)
True
>>> checkSameHost(&#39;http://www.target.com/page1.php?id=1&#39;, &#39;http://www.target2.com/images/page2.php&#39;)
False
"""
if not urls:
return None
elif len(urls) == 1:
return True
else:
return all(re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(url or "").netloc.split(&#39;:&#39;)[0]) == re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(urls[0] or "").netloc.split(&#39;:&#39;)[0]) for url in urls[1:])
  注射
  注入中多线程的目的,绝对是为了加快数据的读取速度。比如我们需要读取一个表的内容,每次请求只能返回一行数据,所以需要根据这个取出长度然后在多线程中运行,sqlmap的设计是每个线程被分配一个 id 来检索相应行的内容。
  一个简单的理解就是你需要在一个表中获取100条数据。在SQL注入语句中,需要一直使用limit 1,1、limit 2,1、..., limit 100,1 来限制读取哪一个。如果在sqlmap中,会先生成一个1到100的列表,每个线程都会从中取出一个num(这些都是线程安全的),在返回数据的时候,会按照num的顺序插入到结果中,所以你最后看到的结果也会是连续的。
  顺便说一句,sqlmap 会“聪明地”分配线程数。比如在这个例子中,sqlmap会将100与设定的线程数进行比较(默认为1),取最小者(非常聪明)。
  页面相似度比较
  前面说过,在做布尔盲注时,如何快速判断就是通过两个网页的相似度来判断。这种匹配方式在sqlmap,格式塔模式匹配(Ratcliff-Obershel palgorithm)中也有提到,它的定义是通过谷歌得到的
  Ratcliff/Obershelp 模式识别
  (算法)
  定义:计算两个字符串的相似度,即匹配的字符数除以两个字符串的总字符数。匹配字符是最长公共子序列中的字符加上递归匹配的最长公共子序列两侧的非匹配区域中的字符。
  更完美的是,python自带的库difflib/SequenceMatcher实现了这个算法。
  搜索关键词seqMatcher 可以找到几个比较的例子。
  检测页面的动态内容
  这个标题其实就是这个函数的字面意思。
  def checkDynamicContent(firstPage, secondPage):
"""
This function checks for the dynamic content in the provided pages
"""
pass
  很明显,作用是比较两个页面的相似度。当您真正查看代码时,您会发现它并不止于此。
  首先,如果其中一页的长度超过下面定义的值,就会很清楚
  # For preventing MemoryError exceptions (caused when using large sequences in difflib.SequenceMatcher)
MAX_DIFFLIB_SEQUENCE_LENGTH = 10 * 1024 * 1024
  不会有比较。
  其次,如果相似度小于0.98(UPPER_RATIO_BOUND = 0.98),sqlmap会查找两个页面的动态内容,找到前半部分和后半部分由两个动态内容共享的一半。在下一次请求中,中间的动态内容会被删除,然后继续比较,直到相似度大于0.98。当然,这个过滤也是有次数限制,超出次数不能使用此方法。“检测页面动态内容”主要用于“检测页面稳定性”的过程中,“检测页面稳定性”是sqlmap检查注入前的一个过程,通过访问同一时间段内两次相同的网页,如果相似度差异比较大,则通过“检测页面动态内容”。所以这个功能不是在注入中使用,而是在注入前“检测页面稳定性”。如何使用sqlmap查找动态内容?
  上面说的
  sqlmap会查找两个页面的动态内容,找到两个动态内容共享的前半部分和后半部分
  所以位于findDynamicContent函数中,这个函数的一个例子可以说明一切
  >>> findDynamicContent("Lorem ipsum dolor sit amet, congue tation referrentur ei sed. Ne nec legimus habemus recusabo, natum reque et per. Facer tritani reprehendunt eos id, modus constituam est te. Usu sumo indoctum ad, pri paulo molestiae complectitur no.", "Lorem ipsum dolor sit amet, congue tation referrentur ei sed. Ne nec legimus habemus recusabo, natum reque et per. Facer tritani reprehendunt eos id, modus constituam est te. Usu sumo indoctum ad, pri paulo molestiae complectitur no.")
>>> kb.dynamicMarkings
[(&#39;natum reque et per. &#39;, &#39;Facer tritani repreh&#39;)]
  具体算法懒得看。可想而知,动态值前后不断逼近,取20个字符作为最终结果。
  实际注射中的相似性检查
  以上相似性判断都是“前戏”,在实际注射过程中并没有发挥作用。在实际注入过程中,为了获取相似度,会去除页面的动态内容(稳定性检测中发现的)、html标签等。后者与之前相同,取值称为seqMatcher。
  空连接
  自动错误报告机制
  当出现未知错误时,sqlmap会使用帐号sqlmapreport自动提交问题到github。代码在 common.py 下的 createGithubIssue 函数中。这是值得学习的。主要通过github API来实现。
  提交的时候会寻找已经提交过的类似问题,这也是一个不错的设计。
  总结
  看sqlmap的代码很痛苦。这篇文章憋了两周,看了无数个“头部结缔组织”才明白sqlmap的大致含义。
  sqlmap的代码耦合度太高了,但是一般我们说代码耦合度越低越好。sqlmap源码值得学习,但是这种耦合一定不要学。. -=
  参考
  /p/44157153 查看全部

  php多线程抓取多个网页(小结(一)并发的划分)
  本节试图解释更深层次的东西。
  sqlmap 在哪里使用多线程
  多线程并发可以加速IO密集型操作,但是sqlmap在哪里使用多线程呢?是时候进行测试了吗?是时候查表了,还是……?带着这个问题,接下来进行分析。
  sqlmap的一些技术细节(1)已经分析了多线程是如何实现的,并将线程封装到函数runThreads中,所以只需要全局搜索这个函数就可以找到使用多线程的地方。
  按场景分,一共发现了三个地方,分别用于注入、爆破、爬行,所以下面三个总结介绍一下它的作用。
  爆破
  在文件位置 lib/utils/brute.py 中找到两个地方
  
  根据函数名,可以猜测主要是爆表和爆表中的字段。具体实现比较简单。每个线程都会从字典中获取一个内容来运行。字典是基于文件的。另外提一下是不是检测表还是检测字段,sqlmap也会把原网页中的一些字段设置为字典。具体请看下面的函数实现。
  def getPageWordSet(page):
"""
Returns word set used in page content
>>> sorted(getPageWordSet(u&#39;foobartest&#39;))
[u&#39;foobar&#39;, u&#39;test&#39;]
"""
retVal = set()
# only if the page&#39;s charset has been successfully identified
if isinstance(page, unicode):
retVal = set(_.group(0) for _ in re.finditer(r"\w+", getFilteredPageContent(page)))
return retVal
  爬虫
  爬虫在爬取和采集 URL 时也是多线程的。sqlmap 定义了一个未处理的集合集合,多个线程从中弹出数据。
  参考sqlmap的技术细节(1)中的线程设计章节,sqlmap在底层实现了线程安全,所以这些细节不需要考虑。主要的爬取规则也是基于BeautifulSoup寻找标签。 ,判断URL满足条件的规则是检查同一个Host。
  def checkSameHost(*urls):
"""
Returns True if all provided urls share that same host
>>> checkSameHost(&#39;http://www.target.com/page1.php?id=1&#39;, &#39;http://www.target.com/images/page2.php&#39;)
True
>>> checkSameHost(&#39;http://www.target.com/page1.php?id=1&#39;, &#39;http://www.target2.com/images/page2.php&#39;)
False
"""
if not urls:
return None
elif len(urls) == 1:
return True
else:
return all(re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(url or "").netloc.split(&#39;:&#39;)[0]) == re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(urls[0] or "").netloc.split(&#39;:&#39;)[0]) for url in urls[1:])
  注射
  注入中多线程的目的,绝对是为了加快数据的读取速度。比如我们需要读取一个表的内容,每次请求只能返回一行数据,所以需要根据这个取出长度然后在多线程中运行,sqlmap的设计是每个线程被分配一个 id 来检索相应行的内容。
  一个简单的理解就是你需要在一个表中获取100条数据。在SQL注入语句中,需要一直使用limit 1,1、limit 2,1、..., limit 100,1 来限制读取哪一个。如果在sqlmap中,会先生成一个1到100的列表,每个线程都会从中取出一个num(这些都是线程安全的),在返回数据的时候,会按照num的顺序插入到结果中,所以你最后看到的结果也会是连续的。
  顺便说一句,sqlmap 会“聪明地”分配线程数。比如在这个例子中,sqlmap会将100与设定的线程数进行比较(默认为1),取最小者(非常聪明)。
  页面相似度比较
  前面说过,在做布尔盲注时,如何快速判断就是通过两个网页的相似度来判断。这种匹配方式在sqlmap,格式塔模式匹配(Ratcliff-Obershel palgorithm)中也有提到,它的定义是通过谷歌得到的
  Ratcliff/Obershelp 模式识别
  (算法)
  定义:计算两个字符串的相似度,即匹配的字符数除以两个字符串的总字符数。匹配字符是最长公共子序列中的字符加上递归匹配的最长公共子序列两侧的非匹配区域中的字符。
  更完美的是,python自带的库difflib/SequenceMatcher实现了这个算法。
  搜索关键词seqMatcher 可以找到几个比较的例子。
  检测页面的动态内容
  这个标题其实就是这个函数的字面意思。
  def checkDynamicContent(firstPage, secondPage):
"""
This function checks for the dynamic content in the provided pages
"""
pass
  很明显,作用是比较两个页面的相似度。当您真正查看代码时,您会发现它并不止于此。
  首先,如果其中一页的长度超过下面定义的值,就会很清楚
  # For preventing MemoryError exceptions (caused when using large sequences in difflib.SequenceMatcher)
MAX_DIFFLIB_SEQUENCE_LENGTH = 10 * 1024 * 1024
  不会有比较。
  其次,如果相似度小于0.98(UPPER_RATIO_BOUND = 0.98),sqlmap会查找两个页面的动态内容,找到前半部分和后半部分由两个动态内容共享的一半。在下一次请求中,中间的动态内容会被删除,然后继续比较,直到相似度大于0.98。当然,这个过滤也是有次数限制,超出次数不能使用此方法。“检测页面动态内容”主要用于“检测页面稳定性”的过程中,“检测页面稳定性”是sqlmap检查注入前的一个过程,通过访问同一时间段内两次相同的网页,如果相似度差异比较大,则通过“检测页面动态内容”。所以这个功能不是在注入中使用,而是在注入前“检测页面稳定性”。如何使用sqlmap查找动态内容?
  上面说的
  sqlmap会查找两个页面的动态内容,找到两个动态内容共享的前半部分和后半部分
  所以位于findDynamicContent函数中,这个函数的一个例子可以说明一切
  >>> findDynamicContent("Lorem ipsum dolor sit amet, congue tation referrentur ei sed. Ne nec legimus habemus recusabo, natum reque et per. Facer tritani reprehendunt eos id, modus constituam est te. Usu sumo indoctum ad, pri paulo molestiae complectitur no.", "Lorem ipsum dolor sit amet, congue tation referrentur ei sed. Ne nec legimus habemus recusabo, natum reque et per. Facer tritani reprehendunt eos id, modus constituam est te. Usu sumo indoctum ad, pri paulo molestiae complectitur no.")
>>> kb.dynamicMarkings
[(&#39;natum reque et per. &#39;, &#39;Facer tritani repreh&#39;)]
  具体算法懒得看。可想而知,动态值前后不断逼近,取20个字符作为最终结果。
  实际注射中的相似性检查
  以上相似性判断都是“前戏”,在实际注射过程中并没有发挥作用。在实际注入过程中,为了获取相似度,会去除页面的动态内容(稳定性检测中发现的)、html标签等。后者与之前相同,取值称为seqMatcher。
  空连接
  自动错误报告机制
  当出现未知错误时,sqlmap会使用帐号sqlmapreport自动提交问题到github。代码在 common.py 下的 createGithubIssue 函数中。这是值得学习的。主要通过github API来实现。
  提交的时候会寻找已经提交过的类似问题,这也是一个不错的设计。
  总结
  看sqlmap的代码很痛苦。这篇文章憋了两周,看了无数个“头部结缔组织”才明白sqlmap的大致含义。
  sqlmap的代码耦合度太高了,但是一般我们说代码耦合度越低越好。sqlmap源码值得学习,但是这种耦合一定不要学。. -=
  参考
  /p/44157153

php多线程抓取多个网页(php多线程抓取多个网页,这样抓取抓取同时操作)

网站优化优采云 发表了文章 • 0 个评论 • 72 次浏览 • 2021-11-18 16:06 • 来自相关话题

  php多线程抓取多个网页(php多线程抓取多个网页,这样抓取抓取同时操作)
  php多线程抓取多个网页,这样多个抓取同时操作,会切换多线程读取器,抓取效率会降低;最好的方法是单线程抓取。php实现多线程抓取,并不是每一个url都要有过滤器过滤:实现方法一:在抓取任意网页的同时也要设置一个反爬虫的header,当url中包含cookie的时候,关于xss等问题都是会自动过滤掉;或者把url中的cookie从urllib的urllib2里面清除掉;php实现多线程抓取,但是反爬虫是通过xss获取cookie的,因此想实现真正的不去过滤cookie的抓取是不存在的;php实现多线程抓取,最简单的是用selenium库,但是selenium是不能抓取目录级别的,dom级别的才可以抓取到;目前用php实现爬虫最普遍的,是就是爬取某个网站,获取数据库里面的数据,做到我们后续其他工作的部分。
  能不用框架就不用框架,一键式的操作,减少很多操作链。最重要一点,不建议用太多的线程去抓取,爬取一些特定网站的内容可以用单线程爬取,大多数数据抓取的都是小站,用多线程太多线程维护更麻烦,更耗内存。
  可以采用urllib3库配合selenium,但是这需要写很多代码。另外支持多线程抓取的库很多,如openid、sleep、aircrypt等,intelcpython都有其他爬虫库的实现,只要用好框架,抓取效率并不低。 查看全部

  php多线程抓取多个网页(php多线程抓取多个网页,这样抓取抓取同时操作)
  php多线程抓取多个网页,这样多个抓取同时操作,会切换多线程读取器,抓取效率会降低;最好的方法是单线程抓取。php实现多线程抓取,并不是每一个url都要有过滤器过滤:实现方法一:在抓取任意网页的同时也要设置一个反爬虫的header,当url中包含cookie的时候,关于xss等问题都是会自动过滤掉;或者把url中的cookie从urllib的urllib2里面清除掉;php实现多线程抓取,但是反爬虫是通过xss获取cookie的,因此想实现真正的不去过滤cookie的抓取是不存在的;php实现多线程抓取,最简单的是用selenium库,但是selenium是不能抓取目录级别的,dom级别的才可以抓取到;目前用php实现爬虫最普遍的,是就是爬取某个网站,获取数据库里面的数据,做到我们后续其他工作的部分。
  能不用框架就不用框架,一键式的操作,减少很多操作链。最重要一点,不建议用太多的线程去抓取,爬取一些特定网站的内容可以用单线程爬取,大多数数据抓取的都是小站,用多线程太多线程维护更麻烦,更耗内存。
  可以采用urllib3库配合selenium,但是这需要写很多代码。另外支持多线程抓取的库很多,如openid、sleep、aircrypt等,intelcpython都有其他爬虫库的实现,只要用好框架,抓取效率并不低。

php多线程抓取多个网页(PHP利用CurlFunctions实现并发多线程下载文件(一) )

网站优化优采云 发表了文章 • 0 个评论 • 71 次浏览 • 2021-11-14 15:15 • 来自相关话题

  php多线程抓取多个网页(PHP利用CurlFunctions实现并发多线程下载文件(一)
)
  本文文章主要介绍PHP基于curl实现多线程爬取。有兴趣的可以参考一下,希望对大家有帮助。
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,开发爬虫程序的效率不高,所以经常需要使用 Curl Multi Functions。实现多线程并发访问多个URL地址的函数,实现网页的并发多线程爬取或下载文件
  代码显示如下:
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  $urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh); 查看全部

  php多线程抓取多个网页(PHP利用CurlFunctions实现并发多线程下载文件(一)
)
  本文文章主要介绍PHP基于curl实现多线程爬取。有兴趣的可以参考一下,希望对大家有帮助。
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,开发爬虫程序的效率不高,所以经常需要使用 Curl Multi Functions。实现多线程并发访问多个URL地址的函数,实现网页的并发多线程爬取或下载文件
  代码显示如下:
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  $urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);

php多线程抓取多个网页(离线浏览器(webstripper)v官方版介绍软件特色特色)

网站优化优采云 发表了文章 • 0 个评论 • 78 次浏览 • 2021-11-13 11:22 • 来自相关话题

  php多线程抓取多个网页(离线浏览器(webstripper)v官方版介绍软件特色特色)
  离线浏览器(webstripper)v官方版是英国迈克萨顿(Mike Sutton)编写的免费软件,也是目前互联网上功能最强大、最容易使用的离线浏览器(webstripper)v官方版。本软件不仅具有OE快速小巧,还可以支持多线程网页爬取,内置浏览器,代理服务器等功能。它可以轻松抓取整个网站 和单个旺页面,或同时抓取。多个网站使用起来非常方便,不会有OE造成的资源浪费。需要说明的是:目前离线浏览器(webstripper)v正式版只能支持英文版,没有中文版,很可惜。
  离线浏览器(webstripper) v 正式版介绍
  离线浏览器(webstripper)v 正式版分类目录中显示的名称,以及网页保存路径,按“下一步”设置是否抓取其他服务器上的文件,要抓取的文件的类型和大小以及可以在此窗口的“高级”选项中捕获多个目录级别中的文件。离线浏览器(webstripper) v 软件正式版默认抓取网页所在服务器上指定URL目录下的所有文件。如果你只是想抓取文本信息,可以选择只抓取txt文件,然后点击“完成”抓取你想要的网页中的文本信息。软件默认可以同时下载的线程数,爬取失败的次数,以及浏览网页时使用的浏览器都可以在菜单下的“选项”选项中进行设置。离线浏览器(webstripper)v 正式版在抓取网页的时候速度很快,但是需要很长时间才能停止。软件应该是将网页地址转换成本地连接,这样才能离线浏览器(webstripper)v正式版。对此,OE在下载的同时进行转换,所以只要你按停止,它就会立即停止。
  离线浏览器(webstripper) v 正式版汇总
  离线浏览器(webstripper)vV3.40 是一款适用于ios版本使用的其他软件的手机软件。如果你喜欢这个软件,请把下载地址分享给你的朋友: 查看全部

  php多线程抓取多个网页(离线浏览器(webstripper)v官方版介绍软件特色特色)
  离线浏览器(webstripper)v官方版是英国迈克萨顿(Mike Sutton)编写的免费软件,也是目前互联网上功能最强大、最容易使用的离线浏览器(webstripper)v官方版。本软件不仅具有OE快速小巧,还可以支持多线程网页爬取,内置浏览器,代理服务器等功能。它可以轻松抓取整个网站 和单个旺页面,或同时抓取。多个网站使用起来非常方便,不会有OE造成的资源浪费。需要说明的是:目前离线浏览器(webstripper)v正式版只能支持英文版,没有中文版,很可惜。
  离线浏览器(webstripper) v 正式版介绍
  离线浏览器(webstripper)v 正式版分类目录中显示的名称,以及网页保存路径,按“下一步”设置是否抓取其他服务器上的文件,要抓取的文件的类型和大小以及可以在此窗口的“高级”选项中捕获多个目录级别中的文件。离线浏览器(webstripper) v 软件正式版默认抓取网页所在服务器上指定URL目录下的所有文件。如果你只是想抓取文本信息,可以选择只抓取txt文件,然后点击“完成”抓取你想要的网页中的文本信息。软件默认可以同时下载的线程数,爬取失败的次数,以及浏览网页时使用的浏览器都可以在菜单下的“选项”选项中进行设置。离线浏览器(webstripper)v 正式版在抓取网页的时候速度很快,但是需要很长时间才能停止。软件应该是将网页地址转换成本地连接,这样才能离线浏览器(webstripper)v正式版。对此,OE在下载的同时进行转换,所以只要你按停止,它就会立即停止。
  离线浏览器(webstripper) v 正式版汇总
  离线浏览器(webstripper)vV3.40 是一款适用于ios版本使用的其他软件的手机软件。如果你喜欢这个软件,请把下载地址分享给你的朋友:

php多线程抓取多个网页( 【每日一题】几个例子(1)代码)

网站优化优采云 发表了文章 • 0 个评论 • 68 次浏览 • 2021-11-09 22:13 • 来自相关话题

  php多线程抓取多个网页(
【每日一题】几个例子(1)代码)
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面的代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  
$urls = array(
'//www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
); // 设置要抓取的页面url
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], curlopt_useragent, "mozilla/4.0 (compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i], curlopt_header ,0);
curl_setopt($conn[$i], curlopt_connecttimeout,60);
curl_setopt($conn[$i], curlopt_file,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取到的代码放入变量中,然后将获取到的内容写入指定文件
  
$urls = array(
'//www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
);
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], curlopt_useragent, "mozilla/4.0 (compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i], curlopt_header ,0);
curl_setopt($conn[$i], curlopt_connecttimeout,60);
curl_setopt($conn[$i],curlopt_returntransfer,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3)下面这段代码实现了利用PHP的curl函数实现文件的并发多线程下载
  
$urls=array(
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],curlopt_useragent,"mozilla/4.0(compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i],curlopt_file,$fp[$i]);
curl_setopt($conn[$i],curlopt_header ,0);
curl_setopt($conn[$i],curlopt_connecttimeout,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],curlopt_useragent,"mozilla/4.0(compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i],curlopt_file,$fp[$i]);
curl_setopt($conn[$i],curlopt_header ,0);
curl_setopt($conn[$i],curlopt_connecttimeout,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);
  以上就是本文的全部内容,希望大家喜欢。 查看全部

  php多线程抓取多个网页(
【每日一题】几个例子(1)代码)
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面的代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  
$urls = array(
'//www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
); // 设置要抓取的页面url
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], curlopt_useragent, "mozilla/4.0 (compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i], curlopt_header ,0);
curl_setopt($conn[$i], curlopt_connecttimeout,60);
curl_setopt($conn[$i], curlopt_file,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取到的代码放入变量中,然后将获取到的内容写入指定文件
  
$urls = array(
'//www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
);
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], curlopt_useragent, "mozilla/4.0 (compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i], curlopt_header ,0);
curl_setopt($conn[$i], curlopt_connecttimeout,60);
curl_setopt($conn[$i],curlopt_returntransfer,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3)下面这段代码实现了利用PHP的curl函数实现文件的并发多线程下载
  
$urls=array(
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],curlopt_useragent,"mozilla/4.0(compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i],curlopt_file,$fp[$i]);
curl_setopt($conn[$i],curlopt_header ,0);
curl_setopt($conn[$i],curlopt_connecttimeout,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],curlopt_useragent,"mozilla/4.0(compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i],curlopt_file,$fp[$i]);
curl_setopt($conn[$i],curlopt_header ,0);
curl_setopt($conn[$i],curlopt_connecttimeout,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);
  以上就是本文的全部内容,希望大家喜欢。

php多线程抓取多个网页(php多线程抓取多个网页看到类似以上的样式都可以很快去解决)

网站优化优采云 发表了文章 • 0 个评论 • 75 次浏览 • 2021-11-04 14:01 • 来自相关话题

  php多线程抓取多个网页(php多线程抓取多个网页看到类似以上的样式都可以很快去解决)
  php多线程抓取多个网页看到类似以上的样式都可以很快去解决,实践过程中发现这并不是我们需要的,如果我们想要解决这个问题我们需要用到库。我也整理过类似的问题我会尝试同时打开mongodb,mysql,php代码还是比较多。
  因为windows就是这样,php在windows上可以多线程执行,php5版本也是这样。别担心,先学会怎么用标准库。
  建议你去看看coroutine.
  你用的是mongodb吧.mongodb针对多线程的解决方案很多,比如queue.要写服务端负载均衡和各种查询优化,对你来说难度相对高一些.
  反对使用wpf或者gui方案,开发iosandroid微信小程序什么的因为在实际开发中用户真正想要的是各个网页之间的联动,而不是子页面轮流去响应爬虫。
  针对题主问题,最好能提供一下源代码啊,wpf语言本身不支持多线程,不过我写的一个网页(此网页不是他google搜索的相关结果),可以看到,一个java和php的实现,提供了相同的post请求,但是却可以很轻松的多次响应对一个页面的执行调用。
  小改一下xml的事件处理就能满足效率的问题
  以大多数网站的代码量来看,最多能支持到一个核心程序,一个进程,而更大的进程运行在服务器上时,往往会有更多线程来同时处理调用。这时候假设我在这个主页上定时监听不同的请求,把响应的请求数量等效到进程的线程数上的话,那么应该是相当大的数量。如果有coroutine,我感觉会效率更高。但其实我觉得做seo是个坑,你最好少做这种事情。 查看全部

  php多线程抓取多个网页(php多线程抓取多个网页看到类似以上的样式都可以很快去解决)
  php多线程抓取多个网页看到类似以上的样式都可以很快去解决,实践过程中发现这并不是我们需要的,如果我们想要解决这个问题我们需要用到库。我也整理过类似的问题我会尝试同时打开mongodb,mysql,php代码还是比较多。
  因为windows就是这样,php在windows上可以多线程执行,php5版本也是这样。别担心,先学会怎么用标准库。
  建议你去看看coroutine.
  你用的是mongodb吧.mongodb针对多线程的解决方案很多,比如queue.要写服务端负载均衡和各种查询优化,对你来说难度相对高一些.
  反对使用wpf或者gui方案,开发iosandroid微信小程序什么的因为在实际开发中用户真正想要的是各个网页之间的联动,而不是子页面轮流去响应爬虫。
  针对题主问题,最好能提供一下源代码啊,wpf语言本身不支持多线程,不过我写的一个网页(此网页不是他google搜索的相关结果),可以看到,一个java和php的实现,提供了相同的post请求,但是却可以很轻松的多次响应对一个页面的执行调用。
  小改一下xml的事件处理就能满足效率的问题
  以大多数网站的代码量来看,最多能支持到一个核心程序,一个进程,而更大的进程运行在服务器上时,往往会有更多线程来同时处理调用。这时候假设我在这个主页上定时监听不同的请求,把响应的请求数量等效到进程的线程数上的话,那么应该是相当大的数量。如果有coroutine,我感觉会效率更高。但其实我觉得做seo是个坑,你最好少做这种事情。

php多线程抓取多个网页(比较,结合实例形式详细分析了curl_init()和curl)

网站优化优采云 发表了文章 • 0 个评论 • 70 次浏览 • 2021-11-01 05:14 • 来自相关话题

  php多线程抓取多个网页(比较,结合实例形式详细分析了curl_init()和curl)
  本文文章主要介绍php使用curl_init()和curl_multi_init()多线程的速度对比,并结合curl_init()和curl_multi_init()的具体使用方法及相关效率对比进行详细分析示例表格。有需要的朋友可以参考
  本文介绍了 PHP 使用 curl_init() 和 curl_multi_init() 多线程的速度对比。分享给大家,供大家参考,如下:
  php中curl_init()的作用很棒,尤其是在爬取网页内容或者文件信息的时候。比如之前的文章《》介绍了curl_init()的强大。
  curl_init() 以单线程模式处理事情。如果需要使用多线程模式进行事务处理,那么php为我们提供了一个函数curl_multi_init(),就是多线程模式处理事务的功能。
  curl_init() 和 curl_multi_init() 速度对比
  curl_multi_init() 多线程可以提高网页的处理速度吗?今天我将通过实验来验证这个问题。
  我今天的测试很简单,就是抓取网页内容,连续抓取5次,分别用curl_init()和curl_multi_init()函数来完成,记录下两者的耗时,比较并得出结论。
  首先,使用 curl_init() 在单个线程中抓取网页内容 5 次。
  程序代码如下:
  然后,使用 curl_multi_init() 多线程连续抓取网页内容 5 次。
  代码显示如下:
<p> 查看全部

  php多线程抓取多个网页(比较,结合实例形式详细分析了curl_init()和curl)
  本文文章主要介绍php使用curl_init()和curl_multi_init()多线程的速度对比,并结合curl_init()和curl_multi_init()的具体使用方法及相关效率对比进行详细分析示例表格。有需要的朋友可以参考
  本文介绍了 PHP 使用 curl_init() 和 curl_multi_init() 多线程的速度对比。分享给大家,供大家参考,如下:
  php中curl_init()的作用很棒,尤其是在爬取网页内容或者文件信息的时候。比如之前的文章《》介绍了curl_init()的强大。
  curl_init() 以单线程模式处理事情。如果需要使用多线程模式进行事务处理,那么php为我们提供了一个函数curl_multi_init(),就是多线程模式处理事务的功能。
  curl_init() 和 curl_multi_init() 速度对比
  curl_multi_init() 多线程可以提高网页的处理速度吗?今天我将通过实验来验证这个问题。
  我今天的测试很简单,就是抓取网页内容,连续抓取5次,分别用curl_init()和curl_multi_init()函数来完成,记录下两者的耗时,比较并得出结论。
  首先,使用 curl_init() 在单个线程中抓取网页内容 5 次。
  程序代码如下:
  然后,使用 curl_multi_init() 多线程连续抓取网页内容 5 次。
  代码显示如下:
<p>

php多线程抓取多个网页(php多线程抓取多个网页,怎么也绕不开threadlocal)

网站优化优采云 发表了文章 • 0 个评论 • 67 次浏览 • 2021-10-29 15:02 • 来自相关话题

  php多线程抓取多个网页(php多线程抓取多个网页,怎么也绕不开threadlocal)
  php多线程抓取多个网页,怎么也绕不开threadlocal。爬虫里,用request()封装request对象,继承threadlocal继承threadlocalmap,然后让代码转化为线程安全的代码。是很好的思路。
  使用mysql就不需要考虑线程安全的问题,
  threadlocal的使用场景一般是定义需要被request获取的线程(即request线程)。这可以是http请求/响应等。线程安全,在当前的实现中,没有任何方法修改当前线程的状态,比如requesthandler以及其子类requesthandler的实现。这意味着你可以全局变量,不同的handler有不同的命名空间,甚至全局变量都不同。
  另外一点就是要正确理解需要提供给threadlocal的方法所定义的args也是必要的。如何使用threadlocal可以参考文章:-a-threadlocal-in-python/。
  想要问问,下面这个图有人能看懂吗?一个是有一个threadlocal,一个是thread里加了个t,
  threadlocal的存储结构如下:threadlocal中存储两个线程会引用对象:一个是threadlocalmap,另一个是threadlocal。threadlocalmap存储的是threadlocal对象,也就是线程组成员的副本,假设一个thread有100个线程,那么其中一个线程有1000个实例,而另一个线程只有1个实例。
  threadlocal同thread对象很像,引用对象时,会取所指对象的引用指向该线程。threadlocal属于python标准库模块,可以通过各种方式使用,下面这个是python3的threadlocal模块相关的类对应python2.6有一些差异(主要原因是python2中,threadlocal的存储结构如下图:threadlocals里存储的thread对象python3可能是下面这个样子:threadlocals中存储的threadlocal对象不一样,在创建threadlocal时,会直接指定对象的引用,比如:threadlocalitems=newthreadlocallist(),因此threadlocal可以以字典的形式存储threadlocalmap,对象所指向的方法一般有这些:returnprevstyleprevstyle是返回当前threadlocal对象,对应newthreadlocal:defprevstyle(item):item=newthreadlocal:prevstylereturnitem类似的一些操作,如扩展prevstyle的数据容器对象map或filter操作等,filter操作,必须抛出异常;而filter操作返回的是threadlocal对象。
  先补充一点,threadlocal的实例化对象,都可以通过下面这样的方式创建:newthreadlocal()上面就是所有threadlocal对象的创建方式:在项目中,一般都是用这种方式来创建threadlocal对象的。threadlocalmap按照python解释器在threadlocalprovider构造函数中的注释:我们。 查看全部

  php多线程抓取多个网页(php多线程抓取多个网页,怎么也绕不开threadlocal)
  php多线程抓取多个网页,怎么也绕不开threadlocal。爬虫里,用request()封装request对象,继承threadlocal继承threadlocalmap,然后让代码转化为线程安全的代码。是很好的思路。
  使用mysql就不需要考虑线程安全的问题,
  threadlocal的使用场景一般是定义需要被request获取的线程(即request线程)。这可以是http请求/响应等。线程安全,在当前的实现中,没有任何方法修改当前线程的状态,比如requesthandler以及其子类requesthandler的实现。这意味着你可以全局变量,不同的handler有不同的命名空间,甚至全局变量都不同。
  另外一点就是要正确理解需要提供给threadlocal的方法所定义的args也是必要的。如何使用threadlocal可以参考文章:-a-threadlocal-in-python/。
  想要问问,下面这个图有人能看懂吗?一个是有一个threadlocal,一个是thread里加了个t,
  threadlocal的存储结构如下:threadlocal中存储两个线程会引用对象:一个是threadlocalmap,另一个是threadlocal。threadlocalmap存储的是threadlocal对象,也就是线程组成员的副本,假设一个thread有100个线程,那么其中一个线程有1000个实例,而另一个线程只有1个实例。
  threadlocal同thread对象很像,引用对象时,会取所指对象的引用指向该线程。threadlocal属于python标准库模块,可以通过各种方式使用,下面这个是python3的threadlocal模块相关的类对应python2.6有一些差异(主要原因是python2中,threadlocal的存储结构如下图:threadlocals里存储的thread对象python3可能是下面这个样子:threadlocals中存储的threadlocal对象不一样,在创建threadlocal时,会直接指定对象的引用,比如:threadlocalitems=newthreadlocallist(),因此threadlocal可以以字典的形式存储threadlocalmap,对象所指向的方法一般有这些:returnprevstyleprevstyle是返回当前threadlocal对象,对应newthreadlocal:defprevstyle(item):item=newthreadlocal:prevstylereturnitem类似的一些操作,如扩展prevstyle的数据容器对象map或filter操作等,filter操作,必须抛出异常;而filter操作返回的是threadlocal对象。
  先补充一点,threadlocal的实例化对象,都可以通过下面这样的方式创建:newthreadlocal()上面就是所有threadlocal对象的创建方式:在项目中,一般都是用这种方式来创建threadlocal对象的。threadlocalmap按照python解释器在threadlocalprovider构造函数中的注释:我们。

php多线程抓取多个网页(publicstaticexternintSetProcessWorkingSetSize比之前的耗时长一些--解决思路-)

网站优化优采云 发表了文章 • 0 个评论 • 70 次浏览 • 2021-10-29 08:09 • 来自相关话题

  php多线程抓取多个网页(publicstaticexternintSetProcessWorkingSetSize比之前的耗时长一些--解决思路-)
  ThreadThread1=newThread(newThreadStart(Function A));
  线程1.开始();
  }
  -------------------------------------------------
  然后每隔一段时间(几乎每500毫秒一次)调用函数B,运行一段时间后报System.OutOfMemoryException。但是定义线程调用A,执行完后应该结束,应该释放资源,内存溢出。
  PS:我试过指定线程大小 ThreadThread1=newThread(newThreadStart(function A), 1024*256); 也会报内存溢出错误,但是比上一个耗时更长
  ------解决方案----------------------
  1、优化代码逻辑,将循环中每次需要申请内存的操作提取出循环外,每次共享一块内存;(并非每个内存使用都可以做到这一点)
  2. 手动GC。. . (性能低,但可以顺利处理,比如100个周期手动恢复一次)
  3.限制内存使用频率。如果代码环境代码环境是多线程导致内存过多,限制线程数,如果是循环引起的,降低循环速度,比如加一个thread.sleep等;
  1 效果最好,但并不总是适用, 2 代码简单,但性能损失高, 3 比较温和,肯定可用,但会降低执行效率;
  这是之前给别人的答案,内存溢出的处理方式,不过是循环,你是多线程的,性质是一样的
  ------解决方案----------------------
  [System.Runtime.InteropServices.DllImport("kernel32.dll",EntryPoint="SetProcessWorkingSetSize")]
  publicstaticexternintSetProcessWorkingSetSize(IntPtrprocess,intminSize,intmaxSize);
  ///
  ///释放内存
  ///
  publicstaticvoidClearMemory()
  {
  GC.Collect();
  GC.WaitForPendingFinalizers();
  if(Environment.OSVersion.Platform==PlatformID.Win32NT)
  {
  表单2.SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle,-1,-1);
  }
  } 查看全部

  php多线程抓取多个网页(publicstaticexternintSetProcessWorkingSetSize比之前的耗时长一些--解决思路-)
  ThreadThread1=newThread(newThreadStart(Function A));
  线程1.开始();
  }
  -------------------------------------------------
  然后每隔一段时间(几乎每500毫秒一次)调用函数B,运行一段时间后报System.OutOfMemoryException。但是定义线程调用A,执行完后应该结束,应该释放资源,内存溢出。
  PS:我试过指定线程大小 ThreadThread1=newThread(newThreadStart(function A), 1024*256); 也会报内存溢出错误,但是比上一个耗时更长
  ------解决方案----------------------
  1、优化代码逻辑,将循环中每次需要申请内存的操作提取出循环外,每次共享一块内存;(并非每个内存使用都可以做到这一点)
  2. 手动GC。. . (性能低,但可以顺利处理,比如100个周期手动恢复一次)
  3.限制内存使用频率。如果代码环境代码环境是多线程导致内存过多,限制线程数,如果是循环引起的,降低循环速度,比如加一个thread.sleep等;
  1 效果最好,但并不总是适用, 2 代码简单,但性能损失高, 3 比较温和,肯定可用,但会降低执行效率;
  这是之前给别人的答案,内存溢出的处理方式,不过是循环,你是多线程的,性质是一样的
  ------解决方案----------------------
  [System.Runtime.InteropServices.DllImport("kernel32.dll",EntryPoint="SetProcessWorkingSetSize")]
  publicstaticexternintSetProcessWorkingSetSize(IntPtrprocess,intminSize,intmaxSize);
  ///
  ///释放内存
  ///
  publicstaticvoidClearMemory()
  {
  GC.Collect();
  GC.WaitForPendingFinalizers();
  if(Environment.OSVersion.Platform==PlatformID.Win32NT)
  {
  表单2.SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle,-1,-1);
  }
  }

php多线程抓取多个网页(PHP利用Curl实现并发多线程抓取网页或者下载文件的操作 )

网站优化优采云 发表了文章 • 0 个评论 • 73 次浏览 • 2021-10-28 00:13 • 来自相关话题

  php多线程抓取多个网页(PHP利用Curl实现并发多线程抓取网页或者下载文件的操作
)
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,所以开发爬虫程序的效率不高。一般使用采集数据即可。使用PHPquery类来采集数据库,除此之外,还可以使用Curl,借助Curl这个功能实现多线程并发访问多个URL地址,实现网页的并发多线程爬取或下载文件。
  具体实现过程请参考以下示例:
  1、 实现抓取多个URL并将内容写入指定文件
  $urls = array( 
&#39;路径地址&#39;, 
&#39;路径地址&#39;, 
&#39;路径地址&#39; 
); // 设置要抓取的页面URL 
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件 
$st = fopen($save_to,"a"); 
$mh = curl_multi_init(); 
foreach ($urls as $i => $url) { 
$conn[$i] = curl_init($url); 
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"); 
curl_setopt($conn[$i], CURLOPT_HEADER ,0); 
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60); 
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件 
curl_multi_add_handle ($mh,$conn[$i]); 
} // 初始化 
do { 
curl_multi_exec($mh,$active); 
} while ($active); // 执行 
foreach ($urls as $i => $url) { 
curl_multi_remove_handle($mh,$conn[$i]); 
curl_close($conn[$i]); 
} // 结束清理 
curl_multi_close($mh); 
fclose($st);
  2、使用PHP的Curl抓取网页的URL并保存内容
  下面的代码和上面类似,只不过这个地方先把获取到的代码放入变量中,然后将获取到的内容写入到指定文件中
  $urls = array( 
&#39;路径地址&#39;, 
&#39;路径地址&#39;, 
&#39;路径地址&#39; 
); 
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件 
$st = fopen($save_to,"a"); 
$mh = curl_multi_init(); 
foreach ($urls as $i => $url) { 
$conn[$i] = curl_init($url); 
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"); 
curl_setopt($conn[$i], CURLOPT_HEADER ,0); 
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60); 
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串 
curl_multi_add_handle ($mh,$conn[$i]); 

do { 
curl_multi_exec($mh,$active); 
} while ($active); 
foreach ($urls as $i => $url) { 
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串 
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件 
foreach ($urls as $i => $url) { 
curl_multi_remove_handle($mh,$conn[$i]); 
curl_close($conn[$i]); 
}
curl_multi_close($mh); 
fclose($st);
  3、使用PHP的Curl实现文件的多线程并发下载
  $urls=array(
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh); 查看全部

  php多线程抓取多个网页(PHP利用Curl实现并发多线程抓取网页或者下载文件的操作
)
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,所以开发爬虫程序的效率不高。一般使用采集数据即可。使用PHPquery类来采集数据库,除此之外,还可以使用Curl,借助Curl这个功能实现多线程并发访问多个URL地址,实现网页的并发多线程爬取或下载文件。
  具体实现过程请参考以下示例:
  1、 实现抓取多个URL并将内容写入指定文件
  $urls = array( 
&#39;路径地址&#39;, 
&#39;路径地址&#39;, 
&#39;路径地址&#39; 
); // 设置要抓取的页面URL 
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件 
$st = fopen($save_to,"a"); 
$mh = curl_multi_init(); 
foreach ($urls as $i => $url) { 
$conn[$i] = curl_init($url); 
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"); 
curl_setopt($conn[$i], CURLOPT_HEADER ,0); 
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60); 
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件 
curl_multi_add_handle ($mh,$conn[$i]); 
} // 初始化 
do { 
curl_multi_exec($mh,$active); 
} while ($active); // 执行 
foreach ($urls as $i => $url) { 
curl_multi_remove_handle($mh,$conn[$i]); 
curl_close($conn[$i]); 
} // 结束清理 
curl_multi_close($mh); 
fclose($st);
  2、使用PHP的Curl抓取网页的URL并保存内容
  下面的代码和上面类似,只不过这个地方先把获取到的代码放入变量中,然后将获取到的内容写入到指定文件中
  $urls = array( 
&#39;路径地址&#39;, 
&#39;路径地址&#39;, 
&#39;路径地址&#39; 
); 
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件 
$st = fopen($save_to,"a"); 
$mh = curl_multi_init(); 
foreach ($urls as $i => $url) { 
$conn[$i] = curl_init($url); 
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"); 
curl_setopt($conn[$i], CURLOPT_HEADER ,0); 
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60); 
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串 
curl_multi_add_handle ($mh,$conn[$i]); 

do { 
curl_multi_exec($mh,$active); 
} while ($active); 
foreach ($urls as $i => $url) { 
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串 
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件 
foreach ($urls as $i => $url) { 
curl_multi_remove_handle($mh,$conn[$i]); 
curl_close($conn[$i]); 
}
curl_multi_close($mh); 
fclose($st);
  3、使用PHP的Curl实现文件的多线程并发下载
  $urls=array(
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);

php多线程抓取多个网页( hebedichPHP利用Curl实现并发多线程下载文件以上就是)

网站优化优采云 发表了文章 • 0 个评论 • 80 次浏览 • 2021-10-28 00:12 • 来自相关话题

  php多线程抓取多个网页(
hebedichPHP利用Curl实现并发多线程下载文件以上就是)
  PHP结合curl实现多线程爬取
  更新时间:2015-07-09 11:09:13 投稿:hebedich
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,开发爬虫程序的效率不高,所以经常需要使用 Curl Multi Functions。实现多线程并发访问多个URL地址的函数,实现网页的并发多线程爬取或下载文件
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  
$urls = array(
'https://www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
); // 设置要抓取的页面URL
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取到的代码放入变量中,然后将获取到的内容写入指定文件
  
$urls = array(
'https://www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
);
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  
$urls=array(
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);
  以上就是本文的全部内容,希望大家喜欢。 查看全部

  php多线程抓取多个网页(
hebedichPHP利用Curl实现并发多线程下载文件以上就是)
  PHP结合curl实现多线程爬取
  更新时间:2015-07-09 11:09:13 投稿:hebedich
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,开发爬虫程序的效率不高,所以经常需要使用 Curl Multi Functions。实现多线程并发访问多个URL地址的函数,实现网页的并发多线程爬取或下载文件
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  
$urls = array(
'https://www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
); // 设置要抓取的页面URL
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取到的代码放入变量中,然后将获取到的内容写入指定文件
  
$urls = array(
'https://www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
);
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  
$urls=array(
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);
  以上就是本文的全部内容,希望大家喜欢。

php多线程抓取多个网页(Python处理网页相关的工具+BeautifulSoup抓取Goolge搜索链接 )

网站优化优采云 发表了文章 • 0 个评论 • 85 次浏览 • 2021-10-27 23:13 • 来自相关话题

  php多线程抓取多个网页(Python处理网页相关的工具+BeautifulSoup抓取Goolge搜索链接
)
  1)urllib2+BeautifulSoup 抓取Goolge搜索链接
  最近参与项目需要处理谷歌搜索结果,之前学习了与处理网页相关的Python工具。在实际应用中,urllib2和beautifulsoup是用来抓取网页的,但是在抓取谷歌搜索结果的时候,发现如果直接处理谷歌搜索结果页面的源码,会得到很多“脏”的链接。
  看下图搜索“titanic james”的结果:
  
  图中红色标注的不需要,蓝色标注的需要抓取处理。
  这种“脏链接”当然可以通过常规过滤的方式过滤掉,但是程序的复杂度很高。就在我一脸悲伤地写过滤规则的时候。同学提醒谷歌应该提供相关的api,突然就明白了。
  (2)Google 网页搜索 API+多线程
  该文档提供了使用 Python 进行搜索的示例:
  在实际应用中,可能需要抓取Google的很多网页,因此需要使用多线程来分担抓取任务。使用google web search api的详细介绍请看这里(这里介绍了Standard URL Arguments)。另外要特别注意的是url中的参数rsz必须是8(包括8)以下的值。如果大于8会报错!
  (3)代码实现
  代码实现还存在问题,但是可以运行,健壮性差,有待改进。希望各位大神指点错误(初学Python),万分感谢。
  #-*-coding:utf-8-*-
import urllib2,urllib
import simplejson
import os, time,threading

import common, html_filter
#input the keywords
keywords = raw_input('Enter the keywords: ')

#define rnum_perpage, pages
rnum_perpage=8
pages=8

#定义线程函数
def thread_scratch(url, rnum_perpage, page):
url_set = []
try:
request = urllib2.Request(url, None, {'Referer': 'http://www.sina.com'})
response = urllib2.urlopen(request)
# Process the JSON string.
results = simplejson.load(response)
info = results['responseData']['results']
except Exception,e:
print 'error occured'
print e
else:
for minfo in info:
url_set.append(minfo['url'])
print minfo['url']
#处理链接
i = 0
for u in url_set:
try:
request_url = urllib2.Request(u, None, {'Referer': 'http://www.sina.com'})
request_url.add_header(
'User-agent',
'CSC'
)
response_data = urllib2.urlopen(request_url).read()
#过滤文件
#content_data = html_filter.filter_tags(response_data)
#写入文件
filenum = i+page
filename = dir_name+'/related_html_'+str(filenum)
print ' write start: related_html_'+str(filenum)
f = open(filename, 'w+', -1)
f.write(response_data)
#print content_data
f.close()
print ' write down: related_html_'+str(filenum)
except Exception, e:
print 'error occured 2'
print e
i = i+1
return

#创建文件夹
dir_name = 'related_html_'+urllib.quote(keywords)
if os.path.exists(dir_name):
print 'exists file'
common.delete_dir_or_file(dir_name)
os.makedirs(dir_name)

#抓取网页
print 'start to scratch web pages:'
for x in range(pages):
print "page:%s"%(x+1)
page = x * rnum_perpage
url = ('https://ajax.googleapis.com/ajax/services/search/web'
'?v=1.0&q=%s&rsz=%s&start=%s') % (urllib.quote(keywords), rnum_perpage,page)
print url
t = threading.Thread(target=thread_scratch, args=(url,rnum_perpage, page))
t.start()
#主线程等待子线程抓取完
main_thread = threading.currentThread()
for t in threading.enumerate():
if t is main_thread:
continue
t.join() 查看全部

  php多线程抓取多个网页(Python处理网页相关的工具+BeautifulSoup抓取Goolge搜索链接
)
  1)urllib2+BeautifulSoup 抓取Goolge搜索链接
  最近参与项目需要处理谷歌搜索结果,之前学习了与处理网页相关的Python工具。在实际应用中,urllib2和beautifulsoup是用来抓取网页的,但是在抓取谷歌搜索结果的时候,发现如果直接处理谷歌搜索结果页面的源码,会得到很多“脏”的链接。
  看下图搜索“titanic james”的结果:
  
  图中红色标注的不需要,蓝色标注的需要抓取处理。
  这种“脏链接”当然可以通过常规过滤的方式过滤掉,但是程序的复杂度很高。就在我一脸悲伤地写过滤规则的时候。同学提醒谷歌应该提供相关的api,突然就明白了。
  (2)Google 网页搜索 API+多线程
  该文档提供了使用 Python 进行搜索的示例:
  在实际应用中,可能需要抓取Google的很多网页,因此需要使用多线程来分担抓取任务。使用google web search api的详细介绍请看这里(这里介绍了Standard URL Arguments)。另外要特别注意的是url中的参数rsz必须是8(包括8)以下的值。如果大于8会报错!
  (3)代码实现
  代码实现还存在问题,但是可以运行,健壮性差,有待改进。希望各位大神指点错误(初学Python),万分感谢。
  #-*-coding:utf-8-*-
import urllib2,urllib
import simplejson
import os, time,threading

import common, html_filter
#input the keywords
keywords = raw_input('Enter the keywords: ')

#define rnum_perpage, pages
rnum_perpage=8
pages=8

#定义线程函数
def thread_scratch(url, rnum_perpage, page):
url_set = []
try:
request = urllib2.Request(url, None, {'Referer': 'http://www.sina.com'})
response = urllib2.urlopen(request)
# Process the JSON string.
results = simplejson.load(response)
info = results['responseData']['results']
except Exception,e:
print 'error occured'
print e
else:
for minfo in info:
url_set.append(minfo['url'])
print minfo['url']
#处理链接
i = 0
for u in url_set:
try:
request_url = urllib2.Request(u, None, {'Referer': 'http://www.sina.com'})
request_url.add_header(
'User-agent',
'CSC'
)
response_data = urllib2.urlopen(request_url).read()
#过滤文件
#content_data = html_filter.filter_tags(response_data)
#写入文件
filenum = i+page
filename = dir_name+'/related_html_'+str(filenum)
print ' write start: related_html_'+str(filenum)
f = open(filename, 'w+', -1)
f.write(response_data)
#print content_data
f.close()
print ' write down: related_html_'+str(filenum)
except Exception, e:
print 'error occured 2'
print e
i = i+1
return

#创建文件夹
dir_name = 'related_html_'+urllib.quote(keywords)
if os.path.exists(dir_name):
print 'exists file'
common.delete_dir_or_file(dir_name)
os.makedirs(dir_name)

#抓取网页
print 'start to scratch web pages:'
for x in range(pages):
print "page:%s"%(x+1)
page = x * rnum_perpage
url = ('https://ajax.googleapis.com/ajax/services/search/web'
'?v=1.0&q=%s&rsz=%s&start=%s') % (urllib.quote(keywords), rnum_perpage,page)
print url
t = threading.Thread(target=thread_scratch, args=(url,rnum_perpage, page))
t.start()
#主线程等待子线程抓取完
main_thread = threading.currentThread()
for t in threading.enumerate():
if t is main_thread:
continue
t.join()

php多线程抓取多个网页(爬虫所需技术及准备事项代码如下run_函数)

网站优化优采云 发表了文章 • 0 个评论 • 75 次浏览 • 2021-10-26 22:04 • 来自相关话题

  php多线程抓取多个网页(爬虫所需技术及准备事项代码如下run_函数)
  爬虫主要的运行时间消耗是请求一个网页时的io阻塞,所以开启多个线程,让不同的请求同时等待可以大大提高爬虫的运行效率。
  本文基于多线程(这里开了10个线程),使用github的api,抓取所有fork cpython项目的5000多个项目信息,并将数据存储在一个json文件中。
  抓取github的这个内容,在之前的文章文章中,展示了没有使用多线程的版本,这里是直接在此基础上的改进。
  爬虫需要的技术和准备
  爬虫代码如下
  import requests
import time
from threading import Thread
from queue import Queue
import json
def run_time(func):
def wrapper(*args, **kw):
start = time.time()
func(*args, **kw)
end = time.time()
print(&#39;running&#39;, end-start, &#39;s&#39;)
return wrapper
class Spider():
def __init__(self):
self.qurl = Queue()
self.data = list()
self.email = &#39;&#39; # 登录github用的邮箱
self.password = &#39;&#39; # 登录github用的密码
self.page_num = 171
self.thread_num = 10
def produce_url(self):
baseurl = &#39;https://api.github.com/repos/p ... ge%3D{}&#39;
for i in range(1, self.page_num + 1):
url = baseurl.format(i)
self.qurl.put(url) # 生成URL存入队列,等待其他线程提取
def get_info(self):
while not self.qurl.empty(): # 保证url遍历结束后能退出线程
url = self.qurl.get() # 从队列中获取URL
print(&#39;crawling&#39;, url)
req = requests.get(url, auth = (self.email, self.password))
data = req.json()
for datai in data:
result = {
&#39;project_name&#39;: datai[&#39;full_name&#39;],
&#39;project_url&#39;: datai[&#39;html_url&#39;],
&#39;project_api_url&#39;: datai[&#39;url&#39;],
&#39;star_count&#39;: datai[&#39;stargazers_count&#39;]
}
self.data.append(result)
@run_time
def run(self):
self.produce_url()
ths = []
for _ in range(self.thread_num):
th = Thread(target=self.get_info)
th.start()
ths.append(th)
for th in ths:
th.join()
s = json.dumps(self.data, ensure_ascii=False, indent=4)
with open(&#39;github_thread.json&#39;, &#39;w&#39;, encoding=&#39;utf-8&#39;) as f:
f.write(s)
print(&#39;Data crawling is finished.&#39;)
if __name__ == &#39;__main__&#39;:
Spider().run()
  读者只需要在Spider的__init__中指定自己的github邮箱和密码即可运行爬虫。
  爬虫描述如下
  1.run_time函数是计算程序运行时间的装饰器,作用于Spider对象的run函数
  2.蜘蛛类
  爬虫结果
  爬取结果显示如下
  
  该程序启动 10 个线程以获取 171 页需要 33 秒。在这个文章中,不使用多线程,耗时333秒。为了对多线程效率的提升有更清晰的体验,读者可以尝试修改上面代码中的self.page_num和self.thread_num。
  我这里做了个实验,self.page_num的值设置为20,表示总共会抓取20个页面
  一个问题
  最后,留下一个问题供读者思考:在之前的文章中,我们也实现了多线程爬虫。为什么当时的代码这么简单,现在却变得复杂了许多?
  跟进
  下一篇多线程爬虫文章将在翻页和爬取二级页面时实现多线程。
  栏目信息
  专栏首页:python编程
  栏目目录:目录
  履带目录:履带系列目录
  版本说明:软件和软件包版本说明 查看全部

  php多线程抓取多个网页(爬虫所需技术及准备事项代码如下run_函数)
  爬虫主要的运行时间消耗是请求一个网页时的io阻塞,所以开启多个线程,让不同的请求同时等待可以大大提高爬虫的运行效率。
  本文基于多线程(这里开了10个线程),使用github的api,抓取所有fork cpython项目的5000多个项目信息,并将数据存储在一个json文件中。
  抓取github的这个内容,在之前的文章文章中,展示了没有使用多线程的版本,这里是直接在此基础上的改进。
  爬虫需要的技术和准备
  爬虫代码如下
  import requests
import time
from threading import Thread
from queue import Queue
import json
def run_time(func):
def wrapper(*args, **kw):
start = time.time()
func(*args, **kw)
end = time.time()
print(&#39;running&#39;, end-start, &#39;s&#39;)
return wrapper
class Spider():
def __init__(self):
self.qurl = Queue()
self.data = list()
self.email = &#39;&#39; # 登录github用的邮箱
self.password = &#39;&#39; # 登录github用的密码
self.page_num = 171
self.thread_num = 10
def produce_url(self):
baseurl = &#39;https://api.github.com/repos/p ... ge%3D{}&#39;
for i in range(1, self.page_num + 1):
url = baseurl.format(i)
self.qurl.put(url) # 生成URL存入队列,等待其他线程提取
def get_info(self):
while not self.qurl.empty(): # 保证url遍历结束后能退出线程
url = self.qurl.get() # 从队列中获取URL
print(&#39;crawling&#39;, url)
req = requests.get(url, auth = (self.email, self.password))
data = req.json()
for datai in data:
result = {
&#39;project_name&#39;: datai[&#39;full_name&#39;],
&#39;project_url&#39;: datai[&#39;html_url&#39;],
&#39;project_api_url&#39;: datai[&#39;url&#39;],
&#39;star_count&#39;: datai[&#39;stargazers_count&#39;]
}
self.data.append(result)
@run_time
def run(self):
self.produce_url()
ths = []
for _ in range(self.thread_num):
th = Thread(target=self.get_info)
th.start()
ths.append(th)
for th in ths:
th.join()
s = json.dumps(self.data, ensure_ascii=False, indent=4)
with open(&#39;github_thread.json&#39;, &#39;w&#39;, encoding=&#39;utf-8&#39;) as f:
f.write(s)
print(&#39;Data crawling is finished.&#39;)
if __name__ == &#39;__main__&#39;:
Spider().run()
  读者只需要在Spider的__init__中指定自己的github邮箱和密码即可运行爬虫。
  爬虫描述如下
  1.run_time函数是计算程序运行时间的装饰器,作用于Spider对象的run函数
  2.蜘蛛类
  爬虫结果
  爬取结果显示如下
  
  该程序启动 10 个线程以获取 171 页需要 33 秒。在这个文章中,不使用多线程,耗时333秒。为了对多线程效率的提升有更清晰的体验,读者可以尝试修改上面代码中的self.page_num和self.thread_num。
  我这里做了个实验,self.page_num的值设置为20,表示总共会抓取20个页面
  一个问题
  最后,留下一个问题供读者思考:在之前的文章中,我们也实现了多线程爬虫。为什么当时的代码这么简单,现在却变得复杂了许多?
  跟进
  下一篇多线程爬虫文章将在翻页和爬取二级页面时实现多线程。
  栏目信息
  专栏首页:python编程
  栏目目录:目录
  履带目录:履带系列目录
  版本说明:软件和软件包版本说明

php多线程抓取多个网页(php中curl_multi()的速度比较_init)

网站优化优采云 发表了文章 • 0 个评论 • 71 次浏览 • 2021-10-26 21:09 • 来自相关话题

  php多线程抓取多个网页(php中curl_multi()的速度比较_init)
  本文介绍了 PHP 使用 curl_init() 和 curl_multi_init() 多线程的速度对比。分享给大家,供大家参考,如下:
  php中的curl_init()有很大的作用,尤其是在爬取网页内容或者文件信息的时候。比如curl_init()的强大在之前的文章《php使用curl进行头部检测和gzip压缩》中介绍过。
  curl_init() 以单线程模式处理事情。如果需要使用多线程模式进行事务处理,那么php为我们提供了一个函数curl_multi_init(),就是多线程模式处理事务的功能。
  curl_init() 和 curl_multi_init() 速度对比
  curl_multi_init() 多线程可以提高网页的处理速度吗?今天我将通过实验来验证这个问题。
  我今天的测试很简单,就是抓取网页内容,连续抓取5次,使用curl_init()和curl_multi_init()函数来完成,记录下两者的耗时,对比一下得出结论。
  首先,使用 curl_init() 在单个线程中抓取网页内容 5 次。
  程序代码如下:
  然后,使用 curl_multi_init() 多线程连续抓取网页内容 5 次。
  代码显示如下:
<p> 查看全部

  php多线程抓取多个网页(php中curl_multi()的速度比较_init)
  本文介绍了 PHP 使用 curl_init() 和 curl_multi_init() 多线程的速度对比。分享给大家,供大家参考,如下:
  php中的curl_init()有很大的作用,尤其是在爬取网页内容或者文件信息的时候。比如curl_init()的强大在之前的文章《php使用curl进行头部检测和gzip压缩》中介绍过。
  curl_init() 以单线程模式处理事情。如果需要使用多线程模式进行事务处理,那么php为我们提供了一个函数curl_multi_init(),就是多线程模式处理事务的功能。
  curl_init() 和 curl_multi_init() 速度对比
  curl_multi_init() 多线程可以提高网页的处理速度吗?今天我将通过实验来验证这个问题。
  我今天的测试很简单,就是抓取网页内容,连续抓取5次,使用curl_init()和curl_multi_init()函数来完成,记录下两者的耗时,对比一下得出结论。
  首先,使用 curl_init() 在单个线程中抓取网页内容 5 次。
  程序代码如下:
  然后,使用 curl_multi_init() 多线程连续抓取网页内容 5 次。
  代码显示如下:
<p>

php多线程抓取多个网页(《爬虫/蜘蛛程序的制作(C#语言)》一文)

网站优化优采云 发表了文章 • 0 个评论 • 82 次浏览 • 2021-10-12 14:25 • 来自相关话题

  php多线程抓取多个网页(《爬虫/蜘蛛程序的制作(C#语言)》一文)
  在《爬虫/蜘蛛程序制作(C#语言)》一文中,已经介绍了爬虫程序的基本实现方法。可以说已经实现了爬虫的功能。只是有效率问题,下载速度可能会很慢。这是由两个原因造成的: 分析和下载不能同时进行。在《爬虫/蜘蛛程序制作(C#语言)》中,已经介绍了爬虫程序的两个步骤:分析和下载。在单线程程序中,两者不能同时执行。也就是说,分析时网络会处于空闲状态,分析时间越长,下载效率越低。反之亦然,下载时不能同时进行分析,并且只有在下载停止后才能进行下一步分析。问题浮出水面,我想大家会想:如果在不同的线程中进行分析和下载,问题是不是就解决了?这只是一个单线程下载。相信大家都有下载Flash Express等资源的经历。里面可以设置线程数(近几年默认是10个,默认是5)。它会把文件分成和线程数一样的部分,然后每个线程下载自己的自己的部分,这样下载效率可能会有所提高,相信大家都有增加线程数来提高下载效率的经验,但是细心的用户会发现,在一定带宽的情况下,并不是线程变得更有效率。越多,速度越快,而是某一点的峰值。爬虫作为一种特殊的下载工具,没有多线程能力怎么能高效呢?信息时代爬虫的目的不就是快速获取信息吗?所以,爬虫需要有多个线程(数量可控)同时下载网页。
  好了,理解和分析问题后,问题解决了:多线程在C#中实现并不难。它有一个命名空间:System.Threading,它提供多线程支持。要启动一个新线程,需要进行如下初始化: ThreadStart startDownload newThreadStart( DownLoad //线程启动设置:每个线程执行DownLoad(),注意:DownLoad() 必须是一个不带参数的方法 Thread downloadThread newThread( startDownload //实例化new class to be open downloadThread.Start();//启动线程,因为线程开头启动的方法不能带参数,给多线程共享资源增加了麻烦。但是我们可以使用类级别的变量(的当然也可以用其他方法,我觉得这个方法最简单好用)来解决这个问题。了解了启用多线程下载的方法后,大家可能会有几个疑问:如何控制线程的结束?这里提出几个问题来解决这个问题: 线程数可以通过一个for循环来实现,就像我们年初学编程时的dot程序一样。例如,已知用户指定了 n 个(它是一个 int 变量)线程。可以用下面的方法启动5个A线程Thread[]downloadThread;//信誉下载线程,这就是C#的优点,就是数组初始化的时候,不需要指定其长度,而且只能在使用时指定。如何控制线程的结束?这里提出几个问题来解决这个问题: 线程数可以通过一个for循环来实现,就像我们年初学编程时的dot程序一样。例如,已知用户指定了 n 个(它是一个 int 变量)线程。可以用下面的方法启动5个A线程Thread[]downloadThread;//信誉下载线程,这就是C#的优点,就是数组初始化的时候,不需要指定其长度,而且只能在使用时指定。如何控制线程的结束?这里提出几个问题来解决这个问题: 线程数可以通过一个for循环来实现,就像我们年初学编程时的dot程序一样。例如,已知用户指定了 n 个(它是一个 int 变量)线程。可以用下面的方法启动5个A线程Thread[]downloadThread;//信誉下载线程,这就是C#的优点,就是数组初始化的时候,不需要指定其长度,而且只能在使用时指定。
  这个声明应该是类级别的,这样就可以提供其他方法控件,可以 ThreadStartstartDownload newThreadStart(DownLoad);//线程启动设置:即每个线程执行DownLoad()downloadThreadnewThread[newThread(startDownload);//指定the thread start setting downloadThread[i].Start();//下面出现的一个问题,一一启动线程:所有线程都调用了DonwLoad()方法,那么如何防止它们同时下载同一个网页时间?这个问题也很容易解决,只需要创建一个Url地址表,表中的每个地址只允许一个线程申请。具体实现:可以使用数据库创建表。表中有四列。一列专用于存储 URL 地址。另外两列存储地址对应的线程和地址已经申请的次数。最后一列存储下载的内容。(当然,对应的线程列不是必须的)。有线程申请时,将对应的线程列设置为当前线程号,将是否申请某列设置为申请一次,其他线程无法申请该页面。如果下载成功,则将内容存储在内容列表中。如果不成功,则内容栏仍为空,作为是否重新下载的依据之一,如果反复不成功,则该过程将达到重试次数(对应地址已申请的次数,用户可以设置),申请下一个Url地址。
  主要代码如下(使用VFP CREATE TABLE (ctablename) &amp;&amp;创建表ctablename.dbf,收录地址、文本内容、下载尝试次数、线程标志(初始值-1,线程标志是从0) 四 字段 cfullname ´.dbf´&amp;&amp; 添加扩展名 USE (cfullname) GO TOP LOCATE (EMPTY(ALLTRIM( ctext &amp;&amp;) ) 未成功下载的表应下载到属于权限的 Url 地址这个线程的,thisNum是当前线程的编号,可以通过参数获取gotUrl curlrecNum &amp;&amp; 如果在列表中找到这样的Url地址 UPDATE (cfullname) SET ldowned thisNumWHERE RECNO() recNum&amp;&amp; 更新表,更新这条记录被请求,即下载次数增加1,并且线程标志列设置为 编译该线程的cfulltablename ´.dbf´USE (cfulltablename) SET EXACT (csiteurl)&amp;&amp;csiteurl 为参数,即下载内容对应的URL地址 recNumNow RECNO()&amp;&amp; 得到收录这个地址的记录号 UPDATE (cfulltablename) SET ctext (ccontent)WHERE RECNO() recNumNow&amp;&amp;插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果有还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 加入列表,解决多线程中的线程冲突。csiteurl为参数,为下载内容对应的URL地址 recNumNow RECNO()&amp;&amp;获取收录该地址的记录号 UPDATE (cfulltablename) SET ctext (ccontent)WHERE RECNO() recNumNow&amp;&amp;插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 添加到列表中,这样多线程中的线程冲突是解决。csiteurl为参数,为下载内容对应的URL地址 recNumNow RECNO()&amp;&amp;获取收录该地址的记录号 UPDATE (cfulltablename) SET ctext (ccontent)WHERE RECNO() recNumNow&amp;&amp;插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 添加到列表中,这样多线程中的线程冲突是解决。插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 加入列表,所以解决了多线程中的线程冲突。插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 加入列表,所以解决了多线程中的线程冲突。
  当然,去重的问题也可以用C#语言解决,只需要创建一个临时文件(文本就够了),保存所有的Url地址,并为它们设置相应的属性,但是搜索效率可能没有那么快数据库。第二次后,仍然无法申请新的URL地址,则可以认为已经下载了所有链接。主要代码如下: string url inttimes );//调用GetAUrl方法尝试获取一个url times++;//尝试次数递增continue; //进行下一次尝试downloadThread[i].Abort;//退出进程//Continue 一步处理获取到的Url比较简单,因为在第一个问题中已经提示该线程称为a类级数组,非常容易控制。只需使用 for 循环结束。代码如下:)//关闭指定数量的线程n,一个蜘蛛程序就这样完成了,在C#面前,它的实现竟然如此简单。在这里我也想提醒读者:我只提供了一个想法和一个可实现的解决方案,但并不是最好的。即便是解决方案本身,也有很多可以改进的地方,留给读者去思考。最后说明一下我使用的环境:winXP sp2 Pro VFP 9.0 Visual Studio 2003 .net 中文企业版 可以改进的地方很多,留给读者去思考。最后说明一下我使用的环境:winXP sp2 Pro VFP 9.0 Visual Studio 2003 .net 中文企业版 可以改进的地方很多,留给读者去思考。最后说明一下我使用的环境:winXP sp2 Pro VFP 9.0 Visual Studio 2003 .net 中文企业版 查看全部

  php多线程抓取多个网页(《爬虫/蜘蛛程序的制作(C#语言)》一文)
  在《爬虫/蜘蛛程序制作(C#语言)》一文中,已经介绍了爬虫程序的基本实现方法。可以说已经实现了爬虫的功能。只是有效率问题,下载速度可能会很慢。这是由两个原因造成的: 分析和下载不能同时进行。在《爬虫/蜘蛛程序制作(C#语言)》中,已经介绍了爬虫程序的两个步骤:分析和下载。在单线程程序中,两者不能同时执行。也就是说,分析时网络会处于空闲状态,分析时间越长,下载效率越低。反之亦然,下载时不能同时进行分析,并且只有在下载停止后才能进行下一步分析。问题浮出水面,我想大家会想:如果在不同的线程中进行分析和下载,问题是不是就解决了?这只是一个单线程下载。相信大家都有下载Flash Express等资源的经历。里面可以设置线程数(近几年默认是10个,默认是5)。它会把文件分成和线程数一样的部分,然后每个线程下载自己的自己的部分,这样下载效率可能会有所提高,相信大家都有增加线程数来提高下载效率的经验,但是细心的用户会发现,在一定带宽的情况下,并不是线程变得更有效率。越多,速度越快,而是某一点的峰值。爬虫作为一种特殊的下载工具,没有多线程能力怎么能高效呢?信息时代爬虫的目的不就是快速获取信息吗?所以,爬虫需要有多个线程(数量可控)同时下载网页。
  好了,理解和分析问题后,问题解决了:多线程在C#中实现并不难。它有一个命名空间:System.Threading,它提供多线程支持。要启动一个新线程,需要进行如下初始化: ThreadStart startDownload newThreadStart( DownLoad //线程启动设置:每个线程执行DownLoad(),注意:DownLoad() 必须是一个不带参数的方法 Thread downloadThread newThread( startDownload //实例化new class to be open downloadThread.Start();//启动线程,因为线程开头启动的方法不能带参数,给多线程共享资源增加了麻烦。但是我们可以使用类级别的变量(的当然也可以用其他方法,我觉得这个方法最简单好用)来解决这个问题。了解了启用多线程下载的方法后,大家可能会有几个疑问:如何控制线程的结束?这里提出几个问题来解决这个问题: 线程数可以通过一个for循环来实现,就像我们年初学编程时的dot程序一样。例如,已知用户指定了 n 个(它是一个 int 变量)线程。可以用下面的方法启动5个A线程Thread[]downloadThread;//信誉下载线程,这就是C#的优点,就是数组初始化的时候,不需要指定其长度,而且只能在使用时指定。如何控制线程的结束?这里提出几个问题来解决这个问题: 线程数可以通过一个for循环来实现,就像我们年初学编程时的dot程序一样。例如,已知用户指定了 n 个(它是一个 int 变量)线程。可以用下面的方法启动5个A线程Thread[]downloadThread;//信誉下载线程,这就是C#的优点,就是数组初始化的时候,不需要指定其长度,而且只能在使用时指定。如何控制线程的结束?这里提出几个问题来解决这个问题: 线程数可以通过一个for循环来实现,就像我们年初学编程时的dot程序一样。例如,已知用户指定了 n 个(它是一个 int 变量)线程。可以用下面的方法启动5个A线程Thread[]downloadThread;//信誉下载线程,这就是C#的优点,就是数组初始化的时候,不需要指定其长度,而且只能在使用时指定。
  这个声明应该是类级别的,这样就可以提供其他方法控件,可以 ThreadStartstartDownload newThreadStart(DownLoad);//线程启动设置:即每个线程执行DownLoad()downloadThreadnewThread[newThread(startDownload);//指定the thread start setting downloadThread[i].Start();//下面出现的一个问题,一一启动线程:所有线程都调用了DonwLoad()方法,那么如何防止它们同时下载同一个网页时间?这个问题也很容易解决,只需要创建一个Url地址表,表中的每个地址只允许一个线程申请。具体实现:可以使用数据库创建表。表中有四列。一列专用于存储 URL 地址。另外两列存储地址对应的线程和地址已经申请的次数。最后一列存储下载的内容。(当然,对应的线程列不是必须的)。有线程申请时,将对应的线程列设置为当前线程号,将是否申请某列设置为申请一次,其他线程无法申请该页面。如果下载成功,则将内容存储在内容列表中。如果不成功,则内容栏仍为空,作为是否重新下载的依据之一,如果反复不成功,则该过程将达到重试次数(对应地址已申请的次数,用户可以设置),申请下一个Url地址。
  主要代码如下(使用VFP CREATE TABLE (ctablename) &amp;&amp;创建表ctablename.dbf,收录地址、文本内容、下载尝试次数、线程标志(初始值-1,线程标志是从0) 四 字段 cfullname ´.dbf´&amp;&amp; 添加扩展名 USE (cfullname) GO TOP LOCATE (EMPTY(ALLTRIM( ctext &amp;&amp;) ) 未成功下载的表应下载到属于权限的 Url 地址这个线程的,thisNum是当前线程的编号,可以通过参数获取gotUrl curlrecNum &amp;&amp; 如果在列表中找到这样的Url地址 UPDATE (cfullname) SET ldowned thisNumWHERE RECNO() recNum&amp;&amp; 更新表,更新这条记录被请求,即下载次数增加1,并且线程标志列设置为 编译该线程的cfulltablename ´.dbf´USE (cfulltablename) SET EXACT (csiteurl)&amp;&amp;csiteurl 为参数,即下载内容对应的URL地址 recNumNow RECNO()&amp;&amp; 得到收录这个地址的记录号 UPDATE (cfulltablename) SET ctext (ccontent)WHERE RECNO() recNumNow&amp;&amp;插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果有还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 加入列表,解决多线程中的线程冲突。csiteurl为参数,为下载内容对应的URL地址 recNumNow RECNO()&amp;&amp;获取收录该地址的记录号 UPDATE (cfulltablename) SET ctext (ccontent)WHERE RECNO() recNumNow&amp;&amp;插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 添加到列表中,这样多线程中的线程冲突是解决。csiteurl为参数,为下载内容对应的URL地址 recNumNow RECNO()&amp;&amp;获取收录该地址的记录号 UPDATE (cfulltablename) SET ctext (ccontent)WHERE RECNO() recNumNow&amp;&amp;插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 添加到列表中,这样多线程中的线程冲突是解决。插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 加入列表,所以解决了多线程中的线程冲突。插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 加入列表,所以解决了多线程中的线程冲突。
  当然,去重的问题也可以用C#语言解决,只需要创建一个临时文件(文本就够了),保存所有的Url地址,并为它们设置相应的属性,但是搜索效率可能没有那么快数据库。第二次后,仍然无法申请新的URL地址,则可以认为已经下载了所有链接。主要代码如下: string url inttimes );//调用GetAUrl方法尝试获取一个url times++;//尝试次数递增continue; //进行下一次尝试downloadThread[i].Abort;//退出进程//Continue 一步处理获取到的Url比较简单,因为在第一个问题中已经提示该线程称为a类级数组,非常容易控制。只需使用 for 循环结束。代码如下:)//关闭指定数量的线程n,一个蜘蛛程序就这样完成了,在C#面前,它的实现竟然如此简单。在这里我也想提醒读者:我只提供了一个想法和一个可实现的解决方案,但并不是最好的。即便是解决方案本身,也有很多可以改进的地方,留给读者去思考。最后说明一下我使用的环境:winXP sp2 Pro VFP 9.0 Visual Studio 2003 .net 中文企业版 可以改进的地方很多,留给读者去思考。最后说明一下我使用的环境:winXP sp2 Pro VFP 9.0 Visual Studio 2003 .net 中文企业版 可以改进的地方很多,留给读者去思考。最后说明一下我使用的环境:winXP sp2 Pro VFP 9.0 Visual Studio 2003 .net 中文企业版

php多线程抓取多个网页(php结合curl实现多线程实现抓取收获的方法总结)

网站优化优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2021-12-13 01:04 • 来自相关话题

  php多线程抓取多个网页(php结合curl实现多线程实现抓取收获的方法总结)
  今天和大家聊聊PHP中如何使用curl进行多线程。很多人可能不太了解。为了让大家更加了解,小编为大家总结了以下内容。希望大家可以关注这篇文章。文章你可以有所收获。
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  $urls = array(
&#39;https://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  $urls = array(
&#39;https://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  $urls=array(
&#39;https://www.jb51.net/5w.zip&#39;,
&#39;https://www.jb51.net/5w.zip&#39;,
&#39;https://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;https://www.jb51.net/5w.zip&#39;,
&#39;https://www.jb51.net/5w.zip&#39;,
&#39;https://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);
  看完上面的内容,你是不是对PHP中如何使用curl进行多线程爬取有了进一步的了解?如果您想了解更多知识或相关内容,请关注易速云行业资讯频道,感谢您的支持。 查看全部

  php多线程抓取多个网页(php结合curl实现多线程实现抓取收获的方法总结)
  今天和大家聊聊PHP中如何使用curl进行多线程。很多人可能不太了解。为了让大家更加了解,小编为大家总结了以下内容。希望大家可以关注这篇文章。文章你可以有所收获。
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  $urls = array(
&#39;https://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  $urls = array(
&#39;https://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  $urls=array(
&#39;https://www.jb51.net/5w.zip&#39;,
&#39;https://www.jb51.net/5w.zip&#39;,
&#39;https://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;https://www.jb51.net/5w.zip&#39;,
&#39;https://www.jb51.net/5w.zip&#39;,
&#39;https://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);
  看完上面的内容,你是不是对PHP中如何使用curl进行多线程爬取有了进一步的了解?如果您想了解更多知识或相关内容,请关注易速云行业资讯频道,感谢您的支持。

php多线程抓取多个网页(php中curl_multi()的速度比较_init)

网站优化优采云 发表了文章 • 0 个评论 • 65 次浏览 • 2021-12-02 20:13 • 来自相关话题

  php多线程抓取多个网页(php中curl_multi()的速度比较_init)
  本文介绍了 PHP 使用 curl_init() 和 curl_multi_init() 多线程的速度对比。分享给大家,供大家参考,如下:
  php中的curl_init()有很大的作用,尤其是在爬取网页内容或者文件信息的时候。比如curl_init()的强大在之前的文章《php使用curl进行头部检测和GZip压缩》中介绍过。
  curl_init() 以单线程模式处理事情。如果需要使用多线程模式进行事务处理,那么php为我们提供了一个函数curl_multi_init(),就是多线程模式处理事务的功能。
  curl_init()和curl_multi_init()的速度对比
  curl_multi_init() 多线程可以提高网页的处理速度吗?今天我将通过实验来验证这个问题。
  我今天的测试很简单,就是抓取网页内容,连续抓取5次,分别使用curl_init()和curl_multi_init()函数来完成,记录下两者的耗时,以及将它们进行比较得出结论。
  首先,使用 curl_init() 在单个线程中抓取网页内容 5 次。
  程序代码如下:
  然后,使用 curl_multi_init() 多线程连续抓取网页内容 5 次。
  代码显示如下:
<p> 查看全部

  php多线程抓取多个网页(php中curl_multi()的速度比较_init)
  本文介绍了 PHP 使用 curl_init() 和 curl_multi_init() 多线程的速度对比。分享给大家,供大家参考,如下:
  php中的curl_init()有很大的作用,尤其是在爬取网页内容或者文件信息的时候。比如curl_init()的强大在之前的文章《php使用curl进行头部检测和GZip压缩》中介绍过。
  curl_init() 以单线程模式处理事情。如果需要使用多线程模式进行事务处理,那么php为我们提供了一个函数curl_multi_init(),就是多线程模式处理事务的功能。
  curl_init()和curl_multi_init()的速度对比
  curl_multi_init() 多线程可以提高网页的处理速度吗?今天我将通过实验来验证这个问题。
  我今天的测试很简单,就是抓取网页内容,连续抓取5次,分别使用curl_init()和curl_multi_init()函数来完成,记录下两者的耗时,以及将它们进行比较得出结论。
  首先,使用 curl_init() 在单个线程中抓取网页内容 5 次。
  程序代码如下:
  然后,使用 curl_multi_init() 多线程连续抓取网页内容 5 次。
  代码显示如下:
<p>

php多线程抓取多个网页(phpcurl_exec()并发抓取网页内容_multi())

网站优化优采云 发表了文章 • 0 个评论 • 73 次浏览 • 2021-12-01 16:06 • 来自相关话题

  php多线程抓取多个网页(phpcurl_exec()并发抓取网页内容_multi())
  php curl_multi_exec() 并发抓取网页内容
  php是单线程语言,所以在某些方面速度不如java,java是多线程语言。毕竟主要方面不在这里。。不过php也有自己的多线程(实际上是并发)方法——curl_multi_exec()。
  我们可以使用curl来获取网页的内容(如果你不懂curl,可以找个简单的例子看看),但是如果同时获取多个网页的内容,速度是不理想。这时候 curl_multi_exec() 就可以发挥作用了。
  以下是我爬取优酷内容的例子:
  
function async_get_url($url_array, $wait_usec = 0)
{
if (!is_array($url_array))
return false;

$wait_usec = intval($wait_usec);

$data = array();
$handle = array();
$running = 0;

$mh = curl_multi_init(); // multi curl handler

$i = 0;
foreach($url_array as $url) {
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return don&#39;t print
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_USERAGENT, &#39;Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)&#39;);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
curl_setopt($ch, CURLOPT_MAXREDIRS, 7);

curl_multi_add_handle($mh, $ch); // 把 curl resource 放進 multi curl handler 裡

$handle[$i++] = $ch;
}

/* 此做法就可以避免掉 CPU loading 100% 的問題 */
// 參考自: http://www.hengss.com/xueyuan/ ... .html

do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
/*
// 感謝 Ren 指點的作法. (需要在測試一下)
// curl_multi_exec的返回值是用來返回多線程處裡時的錯誤,正常來說返回值是0,也就是說只用$mrc捕捉返回值當成判斷式的迴圈只會運行一次,而真的發生錯誤時,有拿$mrc判斷的都會變死迴圈。
// 而curl_multi_select的功能是curl發送請求後,在有回應前會一直處於等待狀態,所以不需要把它導入空迴圈,它就像是會自己做判斷&自己決定等待時間的sleep()。
/* 讀取資料 */
foreach($handle as $i => $ch) {
$content = curl_multi_getcontent($ch);
$data[$i] = (curl_errno($ch) == 0) ? $content : false;
}

/* 移除 handle*/
foreach($handle as $ch) {
curl_multi_remove_handle($mh, $ch);
}

curl_multi_close($mh);

return $data;
}

$url="http://m.youku.com/wap/";
$reg1="/(.*?)/i";//获取视频链接
$reg2="/]*)\s*class=\"imgdetail\"\s*src=(&#39;|\")([^&#39;\"]+)(&#39;|\")/i";
$reg3="";
$reg4= "/.*?/i";//获取视频标题(备选)

// 创建两个cURL资源
$ch1 = curl_init();
$resultArray=array();//装载所有数据的数组
$ch=array();
//$ch2 = curl_init();
// 指定URL和适当的参数
curl_setopt($ch1, CURLOPT_URL,$url);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_HEADER, 0);
$content=curl_exec($ch1);
curl_close($ch1);
//$content=file_get_contents($url);
preg_match_all($reg1, $content,$matches);
$video=$matches[0];//首页视频的链接
//print_r($video);
foreach ($video as $a=>$key)
{
$position=strpos($key, "href");
$substring=substr($key, $position+11);
$pos=strpos($substring, ">");
$link=substr($substring, 0,$pos-1);
$nextUrl[$a]=$url.$link;
}
//$url_array = array(
// &#39;http://www.google.com&#39;,
// &#39;http://www.baidu.com&#39;,
//);
//print_r($nextUrl);
//print_r(async_get_url($nextUrl));
//并发获取所有网页的内容
$allData=async_get_url($nextUrl);
foreach ($allData as $page)
{
//获取视频图片
preg_match_all($reg2, $page,$img);
$img_arr=$img[0];
foreach ($img_arr as $arr)
{
$position=strpos($arr, "src");
$sub=substr($arr, $position+5);
$pos=strpos($sub, "\"");
$last=substr($sub, 0,$pos);
}
//获取视频高清点播地址
preg_match_all($reg3, $page,$vids);
$video_arr=$vids[0];
$vid=$video_arr[0];
$position=strpos($vid, "href");
$v_string=substr($vid, $position+11);
$pos=strpos($v_string, "\"");
$add=substr($v_string, 0,$pos);
$video_url=$url.$add;
//获取视频的标题
preg_match_all($reg4, $page,$match);
$title=$match[0];
//print_r($er);
$r=serialize($title);
$position=mb_strpos($r, "");
$sub=substr($r, 0,$position);
$pos=mb_strrpos($sub, ">");
$til=substr($sub, $pos+1);

//整合到一个数组
$subArray=array(&#39;image&#39;=>$last,&#39;video&#39;=>$video_url,&#39;title&#39;=>$til);
array_push($resultArray, $subArray);
}
echo json_encode($resultArray);</p>
  重点是函数async_get_url
  
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
  上一段是重点和难点。
<p>第一个循环,$mrc == CURLM_CALL_MULTI_PERFORM(-1)表示还有句柄资源没有处理,所以继续$mrc = curl_multi_exec($mh, $active) 查看全部

  php多线程抓取多个网页(phpcurl_exec()并发抓取网页内容_multi())
  php curl_multi_exec() 并发抓取网页内容
  php是单线程语言,所以在某些方面速度不如java,java是多线程语言。毕竟主要方面不在这里。。不过php也有自己的多线程(实际上是并发)方法——curl_multi_exec()。
  我们可以使用curl来获取网页的内容(如果你不懂curl,可以找个简单的例子看看),但是如果同时获取多个网页的内容,速度是不理想。这时候 curl_multi_exec() 就可以发挥作用了。
  以下是我爬取优酷内容的例子:
  
function async_get_url($url_array, $wait_usec = 0)
{
if (!is_array($url_array))
return false;

$wait_usec = intval($wait_usec);

$data = array();
$handle = array();
$running = 0;

$mh = curl_multi_init(); // multi curl handler

$i = 0;
foreach($url_array as $url) {
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return don&#39;t print
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_USERAGENT, &#39;Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)&#39;);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
curl_setopt($ch, CURLOPT_MAXREDIRS, 7);

curl_multi_add_handle($mh, $ch); // 把 curl resource 放進 multi curl handler 裡

$handle[$i++] = $ch;
}

/* 此做法就可以避免掉 CPU loading 100% 的問題 */
// 參考自: http://www.hengss.com/xueyuan/ ... .html

do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
/*
// 感謝 Ren 指點的作法. (需要在測試一下)
// curl_multi_exec的返回值是用來返回多線程處裡時的錯誤,正常來說返回值是0,也就是說只用$mrc捕捉返回值當成判斷式的迴圈只會運行一次,而真的發生錯誤時,有拿$mrc判斷的都會變死迴圈。
// 而curl_multi_select的功能是curl發送請求後,在有回應前會一直處於等待狀態,所以不需要把它導入空迴圈,它就像是會自己做判斷&自己決定等待時間的sleep()。
/* 讀取資料 */
foreach($handle as $i => $ch) {
$content = curl_multi_getcontent($ch);
$data[$i] = (curl_errno($ch) == 0) ? $content : false;
}

/* 移除 handle*/
foreach($handle as $ch) {
curl_multi_remove_handle($mh, $ch);
}

curl_multi_close($mh);

return $data;
}

$url="http://m.youku.com/wap/";
$reg1="/(.*?)/i";//获取视频链接
$reg2="/]*)\s*class=\"imgdetail\"\s*src=(&#39;|\")([^&#39;\"]+)(&#39;|\")/i";
$reg3="";
$reg4= "/.*?/i";//获取视频标题(备选)

// 创建两个cURL资源
$ch1 = curl_init();
$resultArray=array();//装载所有数据的数组
$ch=array();
//$ch2 = curl_init();
// 指定URL和适当的参数
curl_setopt($ch1, CURLOPT_URL,$url);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_HEADER, 0);
$content=curl_exec($ch1);
curl_close($ch1);
//$content=file_get_contents($url);
preg_match_all($reg1, $content,$matches);
$video=$matches[0];//首页视频的链接
//print_r($video);
foreach ($video as $a=>$key)
{
$position=strpos($key, "href");
$substring=substr($key, $position+11);
$pos=strpos($substring, ">");
$link=substr($substring, 0,$pos-1);
$nextUrl[$a]=$url.$link;
}
//$url_array = array(
// &#39;http://www.google.com&#39;,
// &#39;http://www.baidu.com&#39;,
//);
//print_r($nextUrl);
//print_r(async_get_url($nextUrl));
//并发获取所有网页的内容
$allData=async_get_url($nextUrl);
foreach ($allData as $page)
{
//获取视频图片
preg_match_all($reg2, $page,$img);
$img_arr=$img[0];
foreach ($img_arr as $arr)
{
$position=strpos($arr, "src");
$sub=substr($arr, $position+5);
$pos=strpos($sub, "\"");
$last=substr($sub, 0,$pos);
}
//获取视频高清点播地址
preg_match_all($reg3, $page,$vids);
$video_arr=$vids[0];
$vid=$video_arr[0];
$position=strpos($vid, "href");
$v_string=substr($vid, $position+11);
$pos=strpos($v_string, "\"");
$add=substr($v_string, 0,$pos);
$video_url=$url.$add;
//获取视频的标题
preg_match_all($reg4, $page,$match);
$title=$match[0];
//print_r($er);
$r=serialize($title);
$position=mb_strpos($r, "");
$sub=substr($r, 0,$position);
$pos=mb_strrpos($sub, ">");
$til=substr($sub, $pos+1);

//整合到一个数组
$subArray=array(&#39;image&#39;=>$last,&#39;video&#39;=>$video_url,&#39;title&#39;=>$til);
array_push($resultArray, $subArray);
}
echo json_encode($resultArray);</p>
  重点是函数async_get_url
  
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
  上一段是重点和难点。
<p>第一个循环,$mrc == CURLM_CALL_MULTI_PERFORM(-1)表示还有句柄资源没有处理,所以继续$mrc = curl_multi_exec($mh, $active)

php多线程抓取多个网页(Python作为一门功能强大的脚本语言来说 )

网站优化优采云 发表了文章 • 0 个评论 • 69 次浏览 • 2021-11-29 15:03 • 来自相关话题

  php多线程抓取多个网页(Python作为一门功能强大的脚本语言来说
)
  Python 作为一种强大的脚本语言,经常被用来编写爬虫程序。下面是Python爬虫多线程爬取代理服务器
  首先,我通过谷歌找到了收录代理服务器地址的网页。我选择从这个 网站 中抓取它。我在上面抓取了 800 个代理(选择了 8 个页面)
  部分日志:
  
目标网站: http://www.cnproxy.com/proxy1.html
目标网站: http://www.cnproxy.com/proxy2.html
目标网站: http://www.cnproxy.com/proxy3.html
目标网站: http://www.cnproxy.com/proxy4.html
目标网站: http://www.cnproxy.com/proxy5.html
目标网站: http://www.cnproxy.com/proxy6.html
目标网站: http://www.cnproxy.com/proxy7.html
目标网站: http://www.cnproxy.com/proxy8.html
..........总共抓取了800个代理..........
..........总共有478个代理通过校验.........
173.213.113.111:8089 United States 0.341555833817
173.213.113.111:3128 United States 0.347477912903
210.101.131.232:8080 韩国 首尔 0.418715000153
...... 查看全部

  php多线程抓取多个网页(Python作为一门功能强大的脚本语言来说
)
  Python 作为一种强大的脚本语言,经常被用来编写爬虫程序。下面是Python爬虫多线程爬取代理服务器
  首先,我通过谷歌找到了收录代理服务器地址的网页。我选择从这个 网站 中抓取它。我在上面抓取了 800 个代理(选择了 8 个页面)
  部分日志:
  
目标网站: http://www.cnproxy.com/proxy1.html
目标网站: http://www.cnproxy.com/proxy2.html
目标网站: http://www.cnproxy.com/proxy3.html
目标网站: http://www.cnproxy.com/proxy4.html
目标网站: http://www.cnproxy.com/proxy5.html
目标网站: http://www.cnproxy.com/proxy6.html
目标网站: http://www.cnproxy.com/proxy7.html
目标网站: http://www.cnproxy.com/proxy8.html
..........总共抓取了800个代理..........
..........总共有478个代理通过校验.........
173.213.113.111:8089 United States 0.341555833817
173.213.113.111:3128 United States 0.347477912903
210.101.131.232:8080 韩国 首尔 0.418715000153
......

php多线程抓取多个网页(这里有新鲜出炉的PHP教程,程序狗速度看过来! )

网站优化优采云 发表了文章 • 0 个评论 • 58 次浏览 • 2021-11-24 13:02 • 来自相关话题

  php多线程抓取多个网页(这里有新鲜出炉的PHP教程,程序狗速度看过来!
)
  这里有新鲜的PHP教程,看看程序狗的速度!
  PHP 开源脚本语言 PHP(外文名:Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用的开源脚本语言。语法吸收了C语言、Java和Perl的特点,入门门槛低,易学,应用广泛。主要适用于Web开发领域。PHP 的文件扩展名为 php。
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,开发爬虫程序的效率不高,所以经常需要使用 Curl Multi Functions。实现多线程并发访问多个URL地址的函数,实现多线程并发抓取网页或下载文件
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  
$urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  
$urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  
$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh); 查看全部

  php多线程抓取多个网页(这里有新鲜出炉的PHP教程,程序狗速度看过来!
)
  这里有新鲜的PHP教程,看看程序狗的速度!
  PHP 开源脚本语言 PHP(外文名:Hypertext Preprocessor,中文名:“超文本预处理器”)是一种通用的开源脚本语言。语法吸收了C语言、Java和Perl的特点,入门门槛低,易学,应用广泛。主要适用于Web开发领域。PHP 的文件扩展名为 php。
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,开发爬虫程序的效率不高,所以经常需要使用 Curl Multi Functions。实现多线程并发访问多个URL地址的函数,实现多线程并发抓取网页或下载文件
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  
$urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  
$urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  
$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);

php多线程抓取多个网页(小结(一)并发的划分)

网站优化优采云 发表了文章 • 0 个评论 • 83 次浏览 • 2021-11-20 16:23 • 来自相关话题

  php多线程抓取多个网页(小结(一)并发的划分)
  本节试图解释更深层次的东西。
  sqlmap 在哪里使用多线程
  多线程并发可以加速IO密集型操作,但是sqlmap在哪里使用多线程呢?是时候进行测试了吗?是时候查表了,还是……?带着这个问题,接下来进行分析。
  sqlmap的一些技术细节(1)已经分析了多线程是如何实现的,并将线程封装到函数runThreads中,所以只需要全局搜索这个函数就可以找到使用多线程的地方。
  按场景分,一共发现了三个地方,分别用于注入、爆破、爬行,所以下面三个总结介绍一下它的作用。
  爆破
  在文件位置 lib/utils/brute.py 中找到两个地方
  
  根据函数名,可以猜测主要是爆表和爆表中的字段。具体实现比较简单。每个线程都会从字典中获取一个内容来运行。字典是基于文件的。另外提一下是不是检测表还是检测字段,sqlmap也会把原网页中的一些字段设置为字典。具体请看下面的函数实现。
  def getPageWordSet(page):
"""
Returns word set used in page content
>>> sorted(getPageWordSet(u&#39;foobartest&#39;))
[u&#39;foobar&#39;, u&#39;test&#39;]
"""
retVal = set()
# only if the page&#39;s charset has been successfully identified
if isinstance(page, unicode):
retVal = set(_.group(0) for _ in re.finditer(r"\w+", getFilteredPageContent(page)))
return retVal
  爬虫
  爬虫在爬取和采集 URL 时也是多线程的。sqlmap 定义了一个未处理的集合集合,多个线程从中弹出数据。
  参考sqlmap的技术细节(1)中的线程设计章节,sqlmap在底层实现了线程安全,所以这些细节不需要考虑。主要的爬取规则也是基于BeautifulSoup寻找标签。 ,判断URL满足条件的规则是检查同一个Host。
  def checkSameHost(*urls):
"""
Returns True if all provided urls share that same host
>>> checkSameHost(&#39;http://www.target.com/page1.php?id=1&#39;, &#39;http://www.target.com/images/page2.php&#39;)
True
>>> checkSameHost(&#39;http://www.target.com/page1.php?id=1&#39;, &#39;http://www.target2.com/images/page2.php&#39;)
False
"""
if not urls:
return None
elif len(urls) == 1:
return True
else:
return all(re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(url or "").netloc.split(&#39;:&#39;)[0]) == re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(urls[0] or "").netloc.split(&#39;:&#39;)[0]) for url in urls[1:])
  注射
  注入中多线程的目的,绝对是为了加快数据的读取速度。比如我们需要读取一个表的内容,每次请求只能返回一行数据,所以需要根据这个取出长度然后在多线程中运行,sqlmap的设计是每个线程被分配一个 id 来检索相应行的内容。
  一个简单的理解就是你需要在一个表中获取100条数据。在SQL注入语句中,需要一直使用limit 1,1、limit 2,1、..., limit 100,1 来限制读取哪一个。如果在sqlmap中,会先生成一个1到100的列表,每个线程都会从中取出一个num(这些都是线程安全的),在返回数据的时候,会按照num的顺序插入到结果中,所以你最后看到的结果也会是连续的。
  顺便说一句,sqlmap 会“聪明地”分配线程数。比如在这个例子中,sqlmap会将100与设定的线程数进行比较(默认为1),取最小者(非常聪明)。
  页面相似度比较
  前面说过,在做布尔盲注时,如何快速判断就是通过两个网页的相似度来判断。这种匹配方式在sqlmap,格式塔模式匹配(Ratcliff-Obershel palgorithm)中也有提到,它的定义是通过谷歌得到的
  Ratcliff/Obershelp 模式识别
  (算法)
  定义:计算两个字符串的相似度,即匹配的字符数除以两个字符串的总字符数。匹配字符是最长公共子序列中的字符加上递归匹配的最长公共子序列两侧的非匹配区域中的字符。
  更完美的是,python自带的库difflib/SequenceMatcher实现了这个算法。
  搜索关键词seqMatcher 可以找到几个比较的例子。
  检测页面的动态内容
  这个标题其实就是这个函数的字面意思。
  def checkDynamicContent(firstPage, secondPage):
"""
This function checks for the dynamic content in the provided pages
"""
pass
  很明显,作用是比较两个页面的相似度。当您真正查看代码时,您会发现它并不止于此。
  首先,如果其中一页的长度超过下面定义的值,就会很清楚
  # For preventing MemoryError exceptions (caused when using large sequences in difflib.SequenceMatcher)
MAX_DIFFLIB_SEQUENCE_LENGTH = 10 * 1024 * 1024
  不会有比较。
  其次,如果相似度小于0.98(UPPER_RATIO_BOUND = 0.98),sqlmap会查找两个页面的动态内容,找到前半部分和后半部分由两个动态内容共享的一半。在下一次请求中,中间的动态内容会被删除,然后继续比较,直到相似度大于0.98。当然,这个过滤也是有次数限制,超出次数不能使用此方法。“检测页面动态内容”主要用于“检测页面稳定性”的过程中,“检测页面稳定性”是sqlmap检查注入前的一个过程,通过访问同一时间段内两次相同的网页,如果相似度差异比较大,则通过“检测页面动态内容”。所以这个功能不是在注入中使用,而是在注入前“检测页面稳定性”。如何使用sqlmap查找动态内容?
  上面说的
  sqlmap会查找两个页面的动态内容,找到两个动态内容共享的前半部分和后半部分
  所以位于findDynamicContent函数中,这个函数的一个例子可以说明一切
  >>> findDynamicContent("Lorem ipsum dolor sit amet, congue tation referrentur ei sed. Ne nec legimus habemus recusabo, natum reque et per. Facer tritani reprehendunt eos id, modus constituam est te. Usu sumo indoctum ad, pri paulo molestiae complectitur no.", "Lorem ipsum dolor sit amet, congue tation referrentur ei sed. Ne nec legimus habemus recusabo, natum reque et per. Facer tritani reprehendunt eos id, modus constituam est te. Usu sumo indoctum ad, pri paulo molestiae complectitur no.")
>>> kb.dynamicMarkings
[(&#39;natum reque et per. &#39;, &#39;Facer tritani repreh&#39;)]
  具体算法懒得看。可想而知,动态值前后不断逼近,取20个字符作为最终结果。
  实际注射中的相似性检查
  以上相似性判断都是“前戏”,在实际注射过程中并没有发挥作用。在实际注入过程中,为了获取相似度,会去除页面的动态内容(稳定性检测中发现的)、html标签等。后者与之前相同,取值称为seqMatcher。
  空连接
  自动错误报告机制
  当出现未知错误时,sqlmap会使用帐号sqlmapreport自动提交问题到github。代码在 common.py 下的 createGithubIssue 函数中。这是值得学习的。主要通过github API来实现。
  提交的时候会寻找已经提交过的类似问题,这也是一个不错的设计。
  总结
  看sqlmap的代码很痛苦。这篇文章憋了两周,看了无数个“头部结缔组织”才明白sqlmap的大致含义。
  sqlmap的代码耦合度太高了,但是一般我们说代码耦合度越低越好。sqlmap源码值得学习,但是这种耦合一定不要学。. -=
  参考
  /p/44157153 查看全部

  php多线程抓取多个网页(小结(一)并发的划分)
  本节试图解释更深层次的东西。
  sqlmap 在哪里使用多线程
  多线程并发可以加速IO密集型操作,但是sqlmap在哪里使用多线程呢?是时候进行测试了吗?是时候查表了,还是……?带着这个问题,接下来进行分析。
  sqlmap的一些技术细节(1)已经分析了多线程是如何实现的,并将线程封装到函数runThreads中,所以只需要全局搜索这个函数就可以找到使用多线程的地方。
  按场景分,一共发现了三个地方,分别用于注入、爆破、爬行,所以下面三个总结介绍一下它的作用。
  爆破
  在文件位置 lib/utils/brute.py 中找到两个地方
  
  根据函数名,可以猜测主要是爆表和爆表中的字段。具体实现比较简单。每个线程都会从字典中获取一个内容来运行。字典是基于文件的。另外提一下是不是检测表还是检测字段,sqlmap也会把原网页中的一些字段设置为字典。具体请看下面的函数实现。
  def getPageWordSet(page):
"""
Returns word set used in page content
>>> sorted(getPageWordSet(u&#39;foobartest&#39;))
[u&#39;foobar&#39;, u&#39;test&#39;]
"""
retVal = set()
# only if the page&#39;s charset has been successfully identified
if isinstance(page, unicode):
retVal = set(_.group(0) for _ in re.finditer(r"\w+", getFilteredPageContent(page)))
return retVal
  爬虫
  爬虫在爬取和采集 URL 时也是多线程的。sqlmap 定义了一个未处理的集合集合,多个线程从中弹出数据。
  参考sqlmap的技术细节(1)中的线程设计章节,sqlmap在底层实现了线程安全,所以这些细节不需要考虑。主要的爬取规则也是基于BeautifulSoup寻找标签。 ,判断URL满足条件的规则是检查同一个Host。
  def checkSameHost(*urls):
"""
Returns True if all provided urls share that same host
>>> checkSameHost(&#39;http://www.target.com/page1.php?id=1&#39;, &#39;http://www.target.com/images/page2.php&#39;)
True
>>> checkSameHost(&#39;http://www.target.com/page1.php?id=1&#39;, &#39;http://www.target2.com/images/page2.php&#39;)
False
"""
if not urls:
return None
elif len(urls) == 1:
return True
else:
return all(re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(url or "").netloc.split(&#39;:&#39;)[0]) == re.sub(r"(?i)\Awww\.", "", urlparse.urlparse(urls[0] or "").netloc.split(&#39;:&#39;)[0]) for url in urls[1:])
  注射
  注入中多线程的目的,绝对是为了加快数据的读取速度。比如我们需要读取一个表的内容,每次请求只能返回一行数据,所以需要根据这个取出长度然后在多线程中运行,sqlmap的设计是每个线程被分配一个 id 来检索相应行的内容。
  一个简单的理解就是你需要在一个表中获取100条数据。在SQL注入语句中,需要一直使用limit 1,1、limit 2,1、..., limit 100,1 来限制读取哪一个。如果在sqlmap中,会先生成一个1到100的列表,每个线程都会从中取出一个num(这些都是线程安全的),在返回数据的时候,会按照num的顺序插入到结果中,所以你最后看到的结果也会是连续的。
  顺便说一句,sqlmap 会“聪明地”分配线程数。比如在这个例子中,sqlmap会将100与设定的线程数进行比较(默认为1),取最小者(非常聪明)。
  页面相似度比较
  前面说过,在做布尔盲注时,如何快速判断就是通过两个网页的相似度来判断。这种匹配方式在sqlmap,格式塔模式匹配(Ratcliff-Obershel palgorithm)中也有提到,它的定义是通过谷歌得到的
  Ratcliff/Obershelp 模式识别
  (算法)
  定义:计算两个字符串的相似度,即匹配的字符数除以两个字符串的总字符数。匹配字符是最长公共子序列中的字符加上递归匹配的最长公共子序列两侧的非匹配区域中的字符。
  更完美的是,python自带的库difflib/SequenceMatcher实现了这个算法。
  搜索关键词seqMatcher 可以找到几个比较的例子。
  检测页面的动态内容
  这个标题其实就是这个函数的字面意思。
  def checkDynamicContent(firstPage, secondPage):
"""
This function checks for the dynamic content in the provided pages
"""
pass
  很明显,作用是比较两个页面的相似度。当您真正查看代码时,您会发现它并不止于此。
  首先,如果其中一页的长度超过下面定义的值,就会很清楚
  # For preventing MemoryError exceptions (caused when using large sequences in difflib.SequenceMatcher)
MAX_DIFFLIB_SEQUENCE_LENGTH = 10 * 1024 * 1024
  不会有比较。
  其次,如果相似度小于0.98(UPPER_RATIO_BOUND = 0.98),sqlmap会查找两个页面的动态内容,找到前半部分和后半部分由两个动态内容共享的一半。在下一次请求中,中间的动态内容会被删除,然后继续比较,直到相似度大于0.98。当然,这个过滤也是有次数限制,超出次数不能使用此方法。“检测页面动态内容”主要用于“检测页面稳定性”的过程中,“检测页面稳定性”是sqlmap检查注入前的一个过程,通过访问同一时间段内两次相同的网页,如果相似度差异比较大,则通过“检测页面动态内容”。所以这个功能不是在注入中使用,而是在注入前“检测页面稳定性”。如何使用sqlmap查找动态内容?
  上面说的
  sqlmap会查找两个页面的动态内容,找到两个动态内容共享的前半部分和后半部分
  所以位于findDynamicContent函数中,这个函数的一个例子可以说明一切
  >>> findDynamicContent("Lorem ipsum dolor sit amet, congue tation referrentur ei sed. Ne nec legimus habemus recusabo, natum reque et per. Facer tritani reprehendunt eos id, modus constituam est te. Usu sumo indoctum ad, pri paulo molestiae complectitur no.", "Lorem ipsum dolor sit amet, congue tation referrentur ei sed. Ne nec legimus habemus recusabo, natum reque et per. Facer tritani reprehendunt eos id, modus constituam est te. Usu sumo indoctum ad, pri paulo molestiae complectitur no.")
>>> kb.dynamicMarkings
[(&#39;natum reque et per. &#39;, &#39;Facer tritani repreh&#39;)]
  具体算法懒得看。可想而知,动态值前后不断逼近,取20个字符作为最终结果。
  实际注射中的相似性检查
  以上相似性判断都是“前戏”,在实际注射过程中并没有发挥作用。在实际注入过程中,为了获取相似度,会去除页面的动态内容(稳定性检测中发现的)、html标签等。后者与之前相同,取值称为seqMatcher。
  空连接
  自动错误报告机制
  当出现未知错误时,sqlmap会使用帐号sqlmapreport自动提交问题到github。代码在 common.py 下的 createGithubIssue 函数中。这是值得学习的。主要通过github API来实现。
  提交的时候会寻找已经提交过的类似问题,这也是一个不错的设计。
  总结
  看sqlmap的代码很痛苦。这篇文章憋了两周,看了无数个“头部结缔组织”才明白sqlmap的大致含义。
  sqlmap的代码耦合度太高了,但是一般我们说代码耦合度越低越好。sqlmap源码值得学习,但是这种耦合一定不要学。. -=
  参考
  /p/44157153

php多线程抓取多个网页(php多线程抓取多个网页,这样抓取抓取同时操作)

网站优化优采云 发表了文章 • 0 个评论 • 72 次浏览 • 2021-11-18 16:06 • 来自相关话题

  php多线程抓取多个网页(php多线程抓取多个网页,这样抓取抓取同时操作)
  php多线程抓取多个网页,这样多个抓取同时操作,会切换多线程读取器,抓取效率会降低;最好的方法是单线程抓取。php实现多线程抓取,并不是每一个url都要有过滤器过滤:实现方法一:在抓取任意网页的同时也要设置一个反爬虫的header,当url中包含cookie的时候,关于xss等问题都是会自动过滤掉;或者把url中的cookie从urllib的urllib2里面清除掉;php实现多线程抓取,但是反爬虫是通过xss获取cookie的,因此想实现真正的不去过滤cookie的抓取是不存在的;php实现多线程抓取,最简单的是用selenium库,但是selenium是不能抓取目录级别的,dom级别的才可以抓取到;目前用php实现爬虫最普遍的,是就是爬取某个网站,获取数据库里面的数据,做到我们后续其他工作的部分。
  能不用框架就不用框架,一键式的操作,减少很多操作链。最重要一点,不建议用太多的线程去抓取,爬取一些特定网站的内容可以用单线程爬取,大多数数据抓取的都是小站,用多线程太多线程维护更麻烦,更耗内存。
  可以采用urllib3库配合selenium,但是这需要写很多代码。另外支持多线程抓取的库很多,如openid、sleep、aircrypt等,intelcpython都有其他爬虫库的实现,只要用好框架,抓取效率并不低。 查看全部

  php多线程抓取多个网页(php多线程抓取多个网页,这样抓取抓取同时操作)
  php多线程抓取多个网页,这样多个抓取同时操作,会切换多线程读取器,抓取效率会降低;最好的方法是单线程抓取。php实现多线程抓取,并不是每一个url都要有过滤器过滤:实现方法一:在抓取任意网页的同时也要设置一个反爬虫的header,当url中包含cookie的时候,关于xss等问题都是会自动过滤掉;或者把url中的cookie从urllib的urllib2里面清除掉;php实现多线程抓取,但是反爬虫是通过xss获取cookie的,因此想实现真正的不去过滤cookie的抓取是不存在的;php实现多线程抓取,最简单的是用selenium库,但是selenium是不能抓取目录级别的,dom级别的才可以抓取到;目前用php实现爬虫最普遍的,是就是爬取某个网站,获取数据库里面的数据,做到我们后续其他工作的部分。
  能不用框架就不用框架,一键式的操作,减少很多操作链。最重要一点,不建议用太多的线程去抓取,爬取一些特定网站的内容可以用单线程爬取,大多数数据抓取的都是小站,用多线程太多线程维护更麻烦,更耗内存。
  可以采用urllib3库配合selenium,但是这需要写很多代码。另外支持多线程抓取的库很多,如openid、sleep、aircrypt等,intelcpython都有其他爬虫库的实现,只要用好框架,抓取效率并不低。

php多线程抓取多个网页(PHP利用CurlFunctions实现并发多线程下载文件(一) )

网站优化优采云 发表了文章 • 0 个评论 • 71 次浏览 • 2021-11-14 15:15 • 来自相关话题

  php多线程抓取多个网页(PHP利用CurlFunctions实现并发多线程下载文件(一)
)
  本文文章主要介绍PHP基于curl实现多线程爬取。有兴趣的可以参考一下,希望对大家有帮助。
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,开发爬虫程序的效率不高,所以经常需要使用 Curl Multi Functions。实现多线程并发访问多个URL地址的函数,实现网页的并发多线程爬取或下载文件
  代码显示如下:
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  $urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh); 查看全部

  php多线程抓取多个网页(PHP利用CurlFunctions实现并发多线程下载文件(一)
)
  本文文章主要介绍PHP基于curl实现多线程爬取。有兴趣的可以参考一下,希望对大家有帮助。
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,开发爬虫程序的效率不高,所以经常需要使用 Curl Multi Functions。实现多线程并发访问多个URL地址的函数,实现网页的并发多线程爬取或下载文件
  代码显示如下:
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
); // 设置要抓取的页面URL
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取的代码放入变量中,然后将获取的内容写入指定的文件
  $urls = array(
&#39;http://www.jb51.net/&#39;,
&#39;http://www.google.com/&#39;,
&#39;http://www.example.com/&#39;
);
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  $urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;,
&#39;http://www.jb51.net/5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);

php多线程抓取多个网页(离线浏览器(webstripper)v官方版介绍软件特色特色)

网站优化优采云 发表了文章 • 0 个评论 • 78 次浏览 • 2021-11-13 11:22 • 来自相关话题

  php多线程抓取多个网页(离线浏览器(webstripper)v官方版介绍软件特色特色)
  离线浏览器(webstripper)v官方版是英国迈克萨顿(Mike Sutton)编写的免费软件,也是目前互联网上功能最强大、最容易使用的离线浏览器(webstripper)v官方版。本软件不仅具有OE快速小巧,还可以支持多线程网页爬取,内置浏览器,代理服务器等功能。它可以轻松抓取整个网站 和单个旺页面,或同时抓取。多个网站使用起来非常方便,不会有OE造成的资源浪费。需要说明的是:目前离线浏览器(webstripper)v正式版只能支持英文版,没有中文版,很可惜。
  离线浏览器(webstripper) v 正式版介绍
  离线浏览器(webstripper)v 正式版分类目录中显示的名称,以及网页保存路径,按“下一步”设置是否抓取其他服务器上的文件,要抓取的文件的类型和大小以及可以在此窗口的“高级”选项中捕获多个目录级别中的文件。离线浏览器(webstripper) v 软件正式版默认抓取网页所在服务器上指定URL目录下的所有文件。如果你只是想抓取文本信息,可以选择只抓取txt文件,然后点击“完成”抓取你想要的网页中的文本信息。软件默认可以同时下载的线程数,爬取失败的次数,以及浏览网页时使用的浏览器都可以在菜单下的“选项”选项中进行设置。离线浏览器(webstripper)v 正式版在抓取网页的时候速度很快,但是需要很长时间才能停止。软件应该是将网页地址转换成本地连接,这样才能离线浏览器(webstripper)v正式版。对此,OE在下载的同时进行转换,所以只要你按停止,它就会立即停止。
  离线浏览器(webstripper) v 正式版汇总
  离线浏览器(webstripper)vV3.40 是一款适用于ios版本使用的其他软件的手机软件。如果你喜欢这个软件,请把下载地址分享给你的朋友: 查看全部

  php多线程抓取多个网页(离线浏览器(webstripper)v官方版介绍软件特色特色)
  离线浏览器(webstripper)v官方版是英国迈克萨顿(Mike Sutton)编写的免费软件,也是目前互联网上功能最强大、最容易使用的离线浏览器(webstripper)v官方版。本软件不仅具有OE快速小巧,还可以支持多线程网页爬取,内置浏览器,代理服务器等功能。它可以轻松抓取整个网站 和单个旺页面,或同时抓取。多个网站使用起来非常方便,不会有OE造成的资源浪费。需要说明的是:目前离线浏览器(webstripper)v正式版只能支持英文版,没有中文版,很可惜。
  离线浏览器(webstripper) v 正式版介绍
  离线浏览器(webstripper)v 正式版分类目录中显示的名称,以及网页保存路径,按“下一步”设置是否抓取其他服务器上的文件,要抓取的文件的类型和大小以及可以在此窗口的“高级”选项中捕获多个目录级别中的文件。离线浏览器(webstripper) v 软件正式版默认抓取网页所在服务器上指定URL目录下的所有文件。如果你只是想抓取文本信息,可以选择只抓取txt文件,然后点击“完成”抓取你想要的网页中的文本信息。软件默认可以同时下载的线程数,爬取失败的次数,以及浏览网页时使用的浏览器都可以在菜单下的“选项”选项中进行设置。离线浏览器(webstripper)v 正式版在抓取网页的时候速度很快,但是需要很长时间才能停止。软件应该是将网页地址转换成本地连接,这样才能离线浏览器(webstripper)v正式版。对此,OE在下载的同时进行转换,所以只要你按停止,它就会立即停止。
  离线浏览器(webstripper) v 正式版汇总
  离线浏览器(webstripper)vV3.40 是一款适用于ios版本使用的其他软件的手机软件。如果你喜欢这个软件,请把下载地址分享给你的朋友:

php多线程抓取多个网页( 【每日一题】几个例子(1)代码)

网站优化优采云 发表了文章 • 0 个评论 • 68 次浏览 • 2021-11-09 22:13 • 来自相关话题

  php多线程抓取多个网页(
【每日一题】几个例子(1)代码)
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面的代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  
$urls = array(
'//www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
); // 设置要抓取的页面url
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], curlopt_useragent, "mozilla/4.0 (compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i], curlopt_header ,0);
curl_setopt($conn[$i], curlopt_connecttimeout,60);
curl_setopt($conn[$i], curlopt_file,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取到的代码放入变量中,然后将获取到的内容写入指定文件
  
$urls = array(
'//www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
);
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], curlopt_useragent, "mozilla/4.0 (compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i], curlopt_header ,0);
curl_setopt($conn[$i], curlopt_connecttimeout,60);
curl_setopt($conn[$i],curlopt_returntransfer,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3)下面这段代码实现了利用PHP的curl函数实现文件的并发多线程下载
  
$urls=array(
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],curlopt_useragent,"mozilla/4.0(compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i],curlopt_file,$fp[$i]);
curl_setopt($conn[$i],curlopt_header ,0);
curl_setopt($conn[$i],curlopt_connecttimeout,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],curlopt_useragent,"mozilla/4.0(compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i],curlopt_file,$fp[$i]);
curl_setopt($conn[$i],curlopt_header ,0);
curl_setopt($conn[$i],curlopt_connecttimeout,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);
  以上就是本文的全部内容,希望大家喜欢。 查看全部

  php多线程抓取多个网页(
【每日一题】几个例子(1)代码)
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面的代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  
$urls = array(
'//www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
); // 设置要抓取的页面url
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], curlopt_useragent, "mozilla/4.0 (compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i], curlopt_header ,0);
curl_setopt($conn[$i], curlopt_connecttimeout,60);
curl_setopt($conn[$i], curlopt_file,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取到的代码放入变量中,然后将获取到的内容写入指定文件
  
$urls = array(
'//www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
);
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], curlopt_useragent, "mozilla/4.0 (compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i], curlopt_header ,0);
curl_setopt($conn[$i], curlopt_connecttimeout,60);
curl_setopt($conn[$i],curlopt_returntransfer,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3)下面这段代码实现了利用PHP的curl函数实现文件的并发多线程下载
  
$urls=array(
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],curlopt_useragent,"mozilla/4.0(compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i],curlopt_file,$fp[$i]);
curl_setopt($conn[$i],curlopt_header ,0);
curl_setopt($conn[$i],curlopt_connecttimeout,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip',
'//www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],curlopt_useragent,"mozilla/4.0(compatible; msie 7.0; windows nt 6.0)");
curl_setopt($conn[$i],curlopt_file,$fp[$i]);
curl_setopt($conn[$i],curlopt_header ,0);
curl_setopt($conn[$i],curlopt_connecttimeout,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);
  以上就是本文的全部内容,希望大家喜欢。

php多线程抓取多个网页(php多线程抓取多个网页看到类似以上的样式都可以很快去解决)

网站优化优采云 发表了文章 • 0 个评论 • 75 次浏览 • 2021-11-04 14:01 • 来自相关话题

  php多线程抓取多个网页(php多线程抓取多个网页看到类似以上的样式都可以很快去解决)
  php多线程抓取多个网页看到类似以上的样式都可以很快去解决,实践过程中发现这并不是我们需要的,如果我们想要解决这个问题我们需要用到库。我也整理过类似的问题我会尝试同时打开mongodb,mysql,php代码还是比较多。
  因为windows就是这样,php在windows上可以多线程执行,php5版本也是这样。别担心,先学会怎么用标准库。
  建议你去看看coroutine.
  你用的是mongodb吧.mongodb针对多线程的解决方案很多,比如queue.要写服务端负载均衡和各种查询优化,对你来说难度相对高一些.
  反对使用wpf或者gui方案,开发iosandroid微信小程序什么的因为在实际开发中用户真正想要的是各个网页之间的联动,而不是子页面轮流去响应爬虫。
  针对题主问题,最好能提供一下源代码啊,wpf语言本身不支持多线程,不过我写的一个网页(此网页不是他google搜索的相关结果),可以看到,一个java和php的实现,提供了相同的post请求,但是却可以很轻松的多次响应对一个页面的执行调用。
  小改一下xml的事件处理就能满足效率的问题
  以大多数网站的代码量来看,最多能支持到一个核心程序,一个进程,而更大的进程运行在服务器上时,往往会有更多线程来同时处理调用。这时候假设我在这个主页上定时监听不同的请求,把响应的请求数量等效到进程的线程数上的话,那么应该是相当大的数量。如果有coroutine,我感觉会效率更高。但其实我觉得做seo是个坑,你最好少做这种事情。 查看全部

  php多线程抓取多个网页(php多线程抓取多个网页看到类似以上的样式都可以很快去解决)
  php多线程抓取多个网页看到类似以上的样式都可以很快去解决,实践过程中发现这并不是我们需要的,如果我们想要解决这个问题我们需要用到库。我也整理过类似的问题我会尝试同时打开mongodb,mysql,php代码还是比较多。
  因为windows就是这样,php在windows上可以多线程执行,php5版本也是这样。别担心,先学会怎么用标准库。
  建议你去看看coroutine.
  你用的是mongodb吧.mongodb针对多线程的解决方案很多,比如queue.要写服务端负载均衡和各种查询优化,对你来说难度相对高一些.
  反对使用wpf或者gui方案,开发iosandroid微信小程序什么的因为在实际开发中用户真正想要的是各个网页之间的联动,而不是子页面轮流去响应爬虫。
  针对题主问题,最好能提供一下源代码啊,wpf语言本身不支持多线程,不过我写的一个网页(此网页不是他google搜索的相关结果),可以看到,一个java和php的实现,提供了相同的post请求,但是却可以很轻松的多次响应对一个页面的执行调用。
  小改一下xml的事件处理就能满足效率的问题
  以大多数网站的代码量来看,最多能支持到一个核心程序,一个进程,而更大的进程运行在服务器上时,往往会有更多线程来同时处理调用。这时候假设我在这个主页上定时监听不同的请求,把响应的请求数量等效到进程的线程数上的话,那么应该是相当大的数量。如果有coroutine,我感觉会效率更高。但其实我觉得做seo是个坑,你最好少做这种事情。

php多线程抓取多个网页(比较,结合实例形式详细分析了curl_init()和curl)

网站优化优采云 发表了文章 • 0 个评论 • 70 次浏览 • 2021-11-01 05:14 • 来自相关话题

  php多线程抓取多个网页(比较,结合实例形式详细分析了curl_init()和curl)
  本文文章主要介绍php使用curl_init()和curl_multi_init()多线程的速度对比,并结合curl_init()和curl_multi_init()的具体使用方法及相关效率对比进行详细分析示例表格。有需要的朋友可以参考
  本文介绍了 PHP 使用 curl_init() 和 curl_multi_init() 多线程的速度对比。分享给大家,供大家参考,如下:
  php中curl_init()的作用很棒,尤其是在爬取网页内容或者文件信息的时候。比如之前的文章《》介绍了curl_init()的强大。
  curl_init() 以单线程模式处理事情。如果需要使用多线程模式进行事务处理,那么php为我们提供了一个函数curl_multi_init(),就是多线程模式处理事务的功能。
  curl_init() 和 curl_multi_init() 速度对比
  curl_multi_init() 多线程可以提高网页的处理速度吗?今天我将通过实验来验证这个问题。
  我今天的测试很简单,就是抓取网页内容,连续抓取5次,分别用curl_init()和curl_multi_init()函数来完成,记录下两者的耗时,比较并得出结论。
  首先,使用 curl_init() 在单个线程中抓取网页内容 5 次。
  程序代码如下:
  然后,使用 curl_multi_init() 多线程连续抓取网页内容 5 次。
  代码显示如下:
<p> 查看全部

  php多线程抓取多个网页(比较,结合实例形式详细分析了curl_init()和curl)
  本文文章主要介绍php使用curl_init()和curl_multi_init()多线程的速度对比,并结合curl_init()和curl_multi_init()的具体使用方法及相关效率对比进行详细分析示例表格。有需要的朋友可以参考
  本文介绍了 PHP 使用 curl_init() 和 curl_multi_init() 多线程的速度对比。分享给大家,供大家参考,如下:
  php中curl_init()的作用很棒,尤其是在爬取网页内容或者文件信息的时候。比如之前的文章《》介绍了curl_init()的强大。
  curl_init() 以单线程模式处理事情。如果需要使用多线程模式进行事务处理,那么php为我们提供了一个函数curl_multi_init(),就是多线程模式处理事务的功能。
  curl_init() 和 curl_multi_init() 速度对比
  curl_multi_init() 多线程可以提高网页的处理速度吗?今天我将通过实验来验证这个问题。
  我今天的测试很简单,就是抓取网页内容,连续抓取5次,分别用curl_init()和curl_multi_init()函数来完成,记录下两者的耗时,比较并得出结论。
  首先,使用 curl_init() 在单个线程中抓取网页内容 5 次。
  程序代码如下:
  然后,使用 curl_multi_init() 多线程连续抓取网页内容 5 次。
  代码显示如下:
<p>

php多线程抓取多个网页(php多线程抓取多个网页,怎么也绕不开threadlocal)

网站优化优采云 发表了文章 • 0 个评论 • 67 次浏览 • 2021-10-29 15:02 • 来自相关话题

  php多线程抓取多个网页(php多线程抓取多个网页,怎么也绕不开threadlocal)
  php多线程抓取多个网页,怎么也绕不开threadlocal。爬虫里,用request()封装request对象,继承threadlocal继承threadlocalmap,然后让代码转化为线程安全的代码。是很好的思路。
  使用mysql就不需要考虑线程安全的问题,
  threadlocal的使用场景一般是定义需要被request获取的线程(即request线程)。这可以是http请求/响应等。线程安全,在当前的实现中,没有任何方法修改当前线程的状态,比如requesthandler以及其子类requesthandler的实现。这意味着你可以全局变量,不同的handler有不同的命名空间,甚至全局变量都不同。
  另外一点就是要正确理解需要提供给threadlocal的方法所定义的args也是必要的。如何使用threadlocal可以参考文章:-a-threadlocal-in-python/。
  想要问问,下面这个图有人能看懂吗?一个是有一个threadlocal,一个是thread里加了个t,
  threadlocal的存储结构如下:threadlocal中存储两个线程会引用对象:一个是threadlocalmap,另一个是threadlocal。threadlocalmap存储的是threadlocal对象,也就是线程组成员的副本,假设一个thread有100个线程,那么其中一个线程有1000个实例,而另一个线程只有1个实例。
  threadlocal同thread对象很像,引用对象时,会取所指对象的引用指向该线程。threadlocal属于python标准库模块,可以通过各种方式使用,下面这个是python3的threadlocal模块相关的类对应python2.6有一些差异(主要原因是python2中,threadlocal的存储结构如下图:threadlocals里存储的thread对象python3可能是下面这个样子:threadlocals中存储的threadlocal对象不一样,在创建threadlocal时,会直接指定对象的引用,比如:threadlocalitems=newthreadlocallist(),因此threadlocal可以以字典的形式存储threadlocalmap,对象所指向的方法一般有这些:returnprevstyleprevstyle是返回当前threadlocal对象,对应newthreadlocal:defprevstyle(item):item=newthreadlocal:prevstylereturnitem类似的一些操作,如扩展prevstyle的数据容器对象map或filter操作等,filter操作,必须抛出异常;而filter操作返回的是threadlocal对象。
  先补充一点,threadlocal的实例化对象,都可以通过下面这样的方式创建:newthreadlocal()上面就是所有threadlocal对象的创建方式:在项目中,一般都是用这种方式来创建threadlocal对象的。threadlocalmap按照python解释器在threadlocalprovider构造函数中的注释:我们。 查看全部

  php多线程抓取多个网页(php多线程抓取多个网页,怎么也绕不开threadlocal)
  php多线程抓取多个网页,怎么也绕不开threadlocal。爬虫里,用request()封装request对象,继承threadlocal继承threadlocalmap,然后让代码转化为线程安全的代码。是很好的思路。
  使用mysql就不需要考虑线程安全的问题,
  threadlocal的使用场景一般是定义需要被request获取的线程(即request线程)。这可以是http请求/响应等。线程安全,在当前的实现中,没有任何方法修改当前线程的状态,比如requesthandler以及其子类requesthandler的实现。这意味着你可以全局变量,不同的handler有不同的命名空间,甚至全局变量都不同。
  另外一点就是要正确理解需要提供给threadlocal的方法所定义的args也是必要的。如何使用threadlocal可以参考文章:-a-threadlocal-in-python/。
  想要问问,下面这个图有人能看懂吗?一个是有一个threadlocal,一个是thread里加了个t,
  threadlocal的存储结构如下:threadlocal中存储两个线程会引用对象:一个是threadlocalmap,另一个是threadlocal。threadlocalmap存储的是threadlocal对象,也就是线程组成员的副本,假设一个thread有100个线程,那么其中一个线程有1000个实例,而另一个线程只有1个实例。
  threadlocal同thread对象很像,引用对象时,会取所指对象的引用指向该线程。threadlocal属于python标准库模块,可以通过各种方式使用,下面这个是python3的threadlocal模块相关的类对应python2.6有一些差异(主要原因是python2中,threadlocal的存储结构如下图:threadlocals里存储的thread对象python3可能是下面这个样子:threadlocals中存储的threadlocal对象不一样,在创建threadlocal时,会直接指定对象的引用,比如:threadlocalitems=newthreadlocallist(),因此threadlocal可以以字典的形式存储threadlocalmap,对象所指向的方法一般有这些:returnprevstyleprevstyle是返回当前threadlocal对象,对应newthreadlocal:defprevstyle(item):item=newthreadlocal:prevstylereturnitem类似的一些操作,如扩展prevstyle的数据容器对象map或filter操作等,filter操作,必须抛出异常;而filter操作返回的是threadlocal对象。
  先补充一点,threadlocal的实例化对象,都可以通过下面这样的方式创建:newthreadlocal()上面就是所有threadlocal对象的创建方式:在项目中,一般都是用这种方式来创建threadlocal对象的。threadlocalmap按照python解释器在threadlocalprovider构造函数中的注释:我们。

php多线程抓取多个网页(publicstaticexternintSetProcessWorkingSetSize比之前的耗时长一些--解决思路-)

网站优化优采云 发表了文章 • 0 个评论 • 70 次浏览 • 2021-10-29 08:09 • 来自相关话题

  php多线程抓取多个网页(publicstaticexternintSetProcessWorkingSetSize比之前的耗时长一些--解决思路-)
  ThreadThread1=newThread(newThreadStart(Function A));
  线程1.开始();
  }
  -------------------------------------------------
  然后每隔一段时间(几乎每500毫秒一次)调用函数B,运行一段时间后报System.OutOfMemoryException。但是定义线程调用A,执行完后应该结束,应该释放资源,内存溢出。
  PS:我试过指定线程大小 ThreadThread1=newThread(newThreadStart(function A), 1024*256); 也会报内存溢出错误,但是比上一个耗时更长
  ------解决方案----------------------
  1、优化代码逻辑,将循环中每次需要申请内存的操作提取出循环外,每次共享一块内存;(并非每个内存使用都可以做到这一点)
  2. 手动GC。. . (性能低,但可以顺利处理,比如100个周期手动恢复一次)
  3.限制内存使用频率。如果代码环境代码环境是多线程导致内存过多,限制线程数,如果是循环引起的,降低循环速度,比如加一个thread.sleep等;
  1 效果最好,但并不总是适用, 2 代码简单,但性能损失高, 3 比较温和,肯定可用,但会降低执行效率;
  这是之前给别人的答案,内存溢出的处理方式,不过是循环,你是多线程的,性质是一样的
  ------解决方案----------------------
  [System.Runtime.InteropServices.DllImport("kernel32.dll",EntryPoint="SetProcessWorkingSetSize")]
  publicstaticexternintSetProcessWorkingSetSize(IntPtrprocess,intminSize,intmaxSize);
  ///
  ///释放内存
  ///
  publicstaticvoidClearMemory()
  {
  GC.Collect();
  GC.WaitForPendingFinalizers();
  if(Environment.OSVersion.Platform==PlatformID.Win32NT)
  {
  表单2.SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle,-1,-1);
  }
  } 查看全部

  php多线程抓取多个网页(publicstaticexternintSetProcessWorkingSetSize比之前的耗时长一些--解决思路-)
  ThreadThread1=newThread(newThreadStart(Function A));
  线程1.开始();
  }
  -------------------------------------------------
  然后每隔一段时间(几乎每500毫秒一次)调用函数B,运行一段时间后报System.OutOfMemoryException。但是定义线程调用A,执行完后应该结束,应该释放资源,内存溢出。
  PS:我试过指定线程大小 ThreadThread1=newThread(newThreadStart(function A), 1024*256); 也会报内存溢出错误,但是比上一个耗时更长
  ------解决方案----------------------
  1、优化代码逻辑,将循环中每次需要申请内存的操作提取出循环外,每次共享一块内存;(并非每个内存使用都可以做到这一点)
  2. 手动GC。. . (性能低,但可以顺利处理,比如100个周期手动恢复一次)
  3.限制内存使用频率。如果代码环境代码环境是多线程导致内存过多,限制线程数,如果是循环引起的,降低循环速度,比如加一个thread.sleep等;
  1 效果最好,但并不总是适用, 2 代码简单,但性能损失高, 3 比较温和,肯定可用,但会降低执行效率;
  这是之前给别人的答案,内存溢出的处理方式,不过是循环,你是多线程的,性质是一样的
  ------解决方案----------------------
  [System.Runtime.InteropServices.DllImport("kernel32.dll",EntryPoint="SetProcessWorkingSetSize")]
  publicstaticexternintSetProcessWorkingSetSize(IntPtrprocess,intminSize,intmaxSize);
  ///
  ///释放内存
  ///
  publicstaticvoidClearMemory()
  {
  GC.Collect();
  GC.WaitForPendingFinalizers();
  if(Environment.OSVersion.Platform==PlatformID.Win32NT)
  {
  表单2.SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle,-1,-1);
  }
  }

php多线程抓取多个网页(PHP利用Curl实现并发多线程抓取网页或者下载文件的操作 )

网站优化优采云 发表了文章 • 0 个评论 • 73 次浏览 • 2021-10-28 00:13 • 来自相关话题

  php多线程抓取多个网页(PHP利用Curl实现并发多线程抓取网页或者下载文件的操作
)
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,所以开发爬虫程序的效率不高。一般使用采集数据即可。使用PHPquery类来采集数据库,除此之外,还可以使用Curl,借助Curl这个功能实现多线程并发访问多个URL地址,实现网页的并发多线程爬取或下载文件。
  具体实现过程请参考以下示例:
  1、 实现抓取多个URL并将内容写入指定文件
  $urls = array( 
&#39;路径地址&#39;, 
&#39;路径地址&#39;, 
&#39;路径地址&#39; 
); // 设置要抓取的页面URL 
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件 
$st = fopen($save_to,"a"); 
$mh = curl_multi_init(); 
foreach ($urls as $i => $url) { 
$conn[$i] = curl_init($url); 
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"); 
curl_setopt($conn[$i], CURLOPT_HEADER ,0); 
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60); 
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件 
curl_multi_add_handle ($mh,$conn[$i]); 
} // 初始化 
do { 
curl_multi_exec($mh,$active); 
} while ($active); // 执行 
foreach ($urls as $i => $url) { 
curl_multi_remove_handle($mh,$conn[$i]); 
curl_close($conn[$i]); 
} // 结束清理 
curl_multi_close($mh); 
fclose($st);
  2、使用PHP的Curl抓取网页的URL并保存内容
  下面的代码和上面类似,只不过这个地方先把获取到的代码放入变量中,然后将获取到的内容写入到指定文件中
  $urls = array( 
&#39;路径地址&#39;, 
&#39;路径地址&#39;, 
&#39;路径地址&#39; 
); 
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件 
$st = fopen($save_to,"a"); 
$mh = curl_multi_init(); 
foreach ($urls as $i => $url) { 
$conn[$i] = curl_init($url); 
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"); 
curl_setopt($conn[$i], CURLOPT_HEADER ,0); 
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60); 
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串 
curl_multi_add_handle ($mh,$conn[$i]); 

do { 
curl_multi_exec($mh,$active); 
} while ($active); 
foreach ($urls as $i => $url) { 
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串 
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件 
foreach ($urls as $i => $url) { 
curl_multi_remove_handle($mh,$conn[$i]); 
curl_close($conn[$i]); 
}
curl_multi_close($mh); 
fclose($st);
  3、使用PHP的Curl实现文件的多线程并发下载
  $urls=array(
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh); 查看全部

  php多线程抓取多个网页(PHP利用Curl实现并发多线程抓取网页或者下载文件的操作
)
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,所以开发爬虫程序的效率不高。一般使用采集数据即可。使用PHPquery类来采集数据库,除此之外,还可以使用Curl,借助Curl这个功能实现多线程并发访问多个URL地址,实现网页的并发多线程爬取或下载文件。
  具体实现过程请参考以下示例:
  1、 实现抓取多个URL并将内容写入指定文件
  $urls = array( 
&#39;路径地址&#39;, 
&#39;路径地址&#39;, 
&#39;路径地址&#39; 
); // 设置要抓取的页面URL 
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件 
$st = fopen($save_to,"a"); 
$mh = curl_multi_init(); 
foreach ($urls as $i => $url) { 
$conn[$i] = curl_init($url); 
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"); 
curl_setopt($conn[$i], CURLOPT_HEADER ,0); 
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60); 
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件 
curl_multi_add_handle ($mh,$conn[$i]); 
} // 初始化 
do { 
curl_multi_exec($mh,$active); 
} while ($active); // 执行 
foreach ($urls as $i => $url) { 
curl_multi_remove_handle($mh,$conn[$i]); 
curl_close($conn[$i]); 
} // 结束清理 
curl_multi_close($mh); 
fclose($st);
  2、使用PHP的Curl抓取网页的URL并保存内容
  下面的代码和上面类似,只不过这个地方先把获取到的代码放入变量中,然后将获取到的内容写入到指定文件中
  $urls = array( 
&#39;路径地址&#39;, 
&#39;路径地址&#39;, 
&#39;路径地址&#39; 
); 
$save_to=&#39;/test.txt&#39;; // 把抓取的代码写入该文件 
$st = fopen($save_to,"a"); 
$mh = curl_multi_init(); 
foreach ($urls as $i => $url) { 
$conn[$i] = curl_init($url); 
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"); 
curl_setopt($conn[$i], CURLOPT_HEADER ,0); 
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60); 
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串 
curl_multi_add_handle ($mh,$conn[$i]); 

do { 
curl_multi_exec($mh,$active); 
} while ($active); 
foreach ($urls as $i => $url) { 
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串 
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件 
foreach ($urls as $i => $url) { 
curl_multi_remove_handle($mh,$conn[$i]); 
curl_close($conn[$i]); 
}
curl_multi_close($mh); 
fclose($st);
  3、使用PHP的Curl实现文件的多线程并发下载
  $urls=array(
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;,
&#39;路径地址5w.zip&#39;
);
$save_to=&#39;./home/&#39;;
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);

php多线程抓取多个网页( hebedichPHP利用Curl实现并发多线程下载文件以上就是)

网站优化优采云 发表了文章 • 0 个评论 • 80 次浏览 • 2021-10-28 00:12 • 来自相关话题

  php多线程抓取多个网页(
hebedichPHP利用Curl实现并发多线程下载文件以上就是)
  PHP结合curl实现多线程爬取
  更新时间:2015-07-09 11:09:13 投稿:hebedich
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,开发爬虫程序的效率不高,所以经常需要使用 Curl Multi Functions。实现多线程并发访问多个URL地址的函数,实现网页的并发多线程爬取或下载文件
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  
$urls = array(
'https://www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
); // 设置要抓取的页面URL
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取到的代码放入变量中,然后将获取到的内容写入指定文件
  
$urls = array(
'https://www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
);
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  
$urls=array(
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);
  以上就是本文的全部内容,希望大家喜欢。 查看全部

  php多线程抓取多个网页(
hebedichPHP利用Curl实现并发多线程下载文件以上就是)
  PHP结合curl实现多线程爬取
  更新时间:2015-07-09 11:09:13 投稿:hebedich
  PHP可以使用Curl来完成各种文件传输操作,比如模拟浏览器发送GET、POST请求等,但是由于PHP语言本身不支持多线程,开发爬虫程序的效率不高,所以经常需要使用 Curl Multi Functions。实现多线程并发访问多个URL地址的函数,实现网页的并发多线程爬取或下载文件
  PHP结合curl实现多线程爬取
  让我们再看几个例子
  (1)下面这段代码是抓取多个网址,然后将抓取到的网址的页面代码写入指定文件
  
$urls = array(
'https://www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
); // 设置要抓取的页面URL
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i], CURLOPT_FILE,$st); // 将爬取的代码写入文件
curl_multi_add_handle ($mh,$conn[$i]);
} // 初始化
do {
curl_multi_exec($mh,$active);
} while ($active); // 执行
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
} // 结束清理
curl_multi_close($mh);
fclose($st);
  (2)下面的代码和上面的意思一样,只不过这个地方先把获取到的代码放入变量中,然后将获取到的内容写入指定文件
  
$urls = array(
'https://www.jb51.net/',
'http://www.google.com/',
'http://www.example.com/'
);
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
  (3) 下面一段代码实现了使用PHP的Curl Functions实现文件的并发多线程下载
  
$urls=array(
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);$urls=array(
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip',
'https://www.jb51.net/5w.zip'
);
$save_to='./home/';
$mh=curl_multi_init();
foreach($urls as $i=>$url){
$g=$save_to.basename($url);
if(!is_file($g)){
$conn[$i]=curl_init($url);
$fp[$i]=fopen($g,"w");
curl_setopt($conn[$i],CURLOPT_USERAGENT,"Mozilla/4.0(compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i],CURLOPT_FILE,$fp[$i]);
curl_setopt($conn[$i],CURLOPT_HEADER ,0);
curl_setopt($conn[$i],CURLOPT_CONNECTTIMEOUT,60);
curl_multi_add_handle($mh,$conn[$i]);
}
}
do{
$n=curl_multi_exec($mh,$active);
}while($active);
foreach($urls as $i=>$url){
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
fclose($fp[$i]);
}
curl_multi_close($mh);
  以上就是本文的全部内容,希望大家喜欢。

php多线程抓取多个网页(Python处理网页相关的工具+BeautifulSoup抓取Goolge搜索链接 )

网站优化优采云 发表了文章 • 0 个评论 • 85 次浏览 • 2021-10-27 23:13 • 来自相关话题

  php多线程抓取多个网页(Python处理网页相关的工具+BeautifulSoup抓取Goolge搜索链接
)
  1)urllib2+BeautifulSoup 抓取Goolge搜索链接
  最近参与项目需要处理谷歌搜索结果,之前学习了与处理网页相关的Python工具。在实际应用中,urllib2和beautifulsoup是用来抓取网页的,但是在抓取谷歌搜索结果的时候,发现如果直接处理谷歌搜索结果页面的源码,会得到很多“脏”的链接。
  看下图搜索“titanic james”的结果:
  
  图中红色标注的不需要,蓝色标注的需要抓取处理。
  这种“脏链接”当然可以通过常规过滤的方式过滤掉,但是程序的复杂度很高。就在我一脸悲伤地写过滤规则的时候。同学提醒谷歌应该提供相关的api,突然就明白了。
  (2)Google 网页搜索 API+多线程
  该文档提供了使用 Python 进行搜索的示例:
  在实际应用中,可能需要抓取Google的很多网页,因此需要使用多线程来分担抓取任务。使用google web search api的详细介绍请看这里(这里介绍了Standard URL Arguments)。另外要特别注意的是url中的参数rsz必须是8(包括8)以下的值。如果大于8会报错!
  (3)代码实现
  代码实现还存在问题,但是可以运行,健壮性差,有待改进。希望各位大神指点错误(初学Python),万分感谢。
  #-*-coding:utf-8-*-
import urllib2,urllib
import simplejson
import os, time,threading

import common, html_filter
#input the keywords
keywords = raw_input('Enter the keywords: ')

#define rnum_perpage, pages
rnum_perpage=8
pages=8

#定义线程函数
def thread_scratch(url, rnum_perpage, page):
url_set = []
try:
request = urllib2.Request(url, None, {'Referer': 'http://www.sina.com'})
response = urllib2.urlopen(request)
# Process the JSON string.
results = simplejson.load(response)
info = results['responseData']['results']
except Exception,e:
print 'error occured'
print e
else:
for minfo in info:
url_set.append(minfo['url'])
print minfo['url']
#处理链接
i = 0
for u in url_set:
try:
request_url = urllib2.Request(u, None, {'Referer': 'http://www.sina.com'})
request_url.add_header(
'User-agent',
'CSC'
)
response_data = urllib2.urlopen(request_url).read()
#过滤文件
#content_data = html_filter.filter_tags(response_data)
#写入文件
filenum = i+page
filename = dir_name+'/related_html_'+str(filenum)
print ' write start: related_html_'+str(filenum)
f = open(filename, 'w+', -1)
f.write(response_data)
#print content_data
f.close()
print ' write down: related_html_'+str(filenum)
except Exception, e:
print 'error occured 2'
print e
i = i+1
return

#创建文件夹
dir_name = 'related_html_'+urllib.quote(keywords)
if os.path.exists(dir_name):
print 'exists file'
common.delete_dir_or_file(dir_name)
os.makedirs(dir_name)

#抓取网页
print 'start to scratch web pages:'
for x in range(pages):
print "page:%s"%(x+1)
page = x * rnum_perpage
url = ('https://ajax.googleapis.com/ajax/services/search/web'
'?v=1.0&q=%s&rsz=%s&start=%s') % (urllib.quote(keywords), rnum_perpage,page)
print url
t = threading.Thread(target=thread_scratch, args=(url,rnum_perpage, page))
t.start()
#主线程等待子线程抓取完
main_thread = threading.currentThread()
for t in threading.enumerate():
if t is main_thread:
continue
t.join() 查看全部

  php多线程抓取多个网页(Python处理网页相关的工具+BeautifulSoup抓取Goolge搜索链接
)
  1)urllib2+BeautifulSoup 抓取Goolge搜索链接
  最近参与项目需要处理谷歌搜索结果,之前学习了与处理网页相关的Python工具。在实际应用中,urllib2和beautifulsoup是用来抓取网页的,但是在抓取谷歌搜索结果的时候,发现如果直接处理谷歌搜索结果页面的源码,会得到很多“脏”的链接。
  看下图搜索“titanic james”的结果:
  
  图中红色标注的不需要,蓝色标注的需要抓取处理。
  这种“脏链接”当然可以通过常规过滤的方式过滤掉,但是程序的复杂度很高。就在我一脸悲伤地写过滤规则的时候。同学提醒谷歌应该提供相关的api,突然就明白了。
  (2)Google 网页搜索 API+多线程
  该文档提供了使用 Python 进行搜索的示例:
  在实际应用中,可能需要抓取Google的很多网页,因此需要使用多线程来分担抓取任务。使用google web search api的详细介绍请看这里(这里介绍了Standard URL Arguments)。另外要特别注意的是url中的参数rsz必须是8(包括8)以下的值。如果大于8会报错!
  (3)代码实现
  代码实现还存在问题,但是可以运行,健壮性差,有待改进。希望各位大神指点错误(初学Python),万分感谢。
  #-*-coding:utf-8-*-
import urllib2,urllib
import simplejson
import os, time,threading

import common, html_filter
#input the keywords
keywords = raw_input('Enter the keywords: ')

#define rnum_perpage, pages
rnum_perpage=8
pages=8

#定义线程函数
def thread_scratch(url, rnum_perpage, page):
url_set = []
try:
request = urllib2.Request(url, None, {'Referer': 'http://www.sina.com'})
response = urllib2.urlopen(request)
# Process the JSON string.
results = simplejson.load(response)
info = results['responseData']['results']
except Exception,e:
print 'error occured'
print e
else:
for minfo in info:
url_set.append(minfo['url'])
print minfo['url']
#处理链接
i = 0
for u in url_set:
try:
request_url = urllib2.Request(u, None, {'Referer': 'http://www.sina.com'})
request_url.add_header(
'User-agent',
'CSC'
)
response_data = urllib2.urlopen(request_url).read()
#过滤文件
#content_data = html_filter.filter_tags(response_data)
#写入文件
filenum = i+page
filename = dir_name+'/related_html_'+str(filenum)
print ' write start: related_html_'+str(filenum)
f = open(filename, 'w+', -1)
f.write(response_data)
#print content_data
f.close()
print ' write down: related_html_'+str(filenum)
except Exception, e:
print 'error occured 2'
print e
i = i+1
return

#创建文件夹
dir_name = 'related_html_'+urllib.quote(keywords)
if os.path.exists(dir_name):
print 'exists file'
common.delete_dir_or_file(dir_name)
os.makedirs(dir_name)

#抓取网页
print 'start to scratch web pages:'
for x in range(pages):
print "page:%s"%(x+1)
page = x * rnum_perpage
url = ('https://ajax.googleapis.com/ajax/services/search/web'
'?v=1.0&q=%s&rsz=%s&start=%s') % (urllib.quote(keywords), rnum_perpage,page)
print url
t = threading.Thread(target=thread_scratch, args=(url,rnum_perpage, page))
t.start()
#主线程等待子线程抓取完
main_thread = threading.currentThread()
for t in threading.enumerate():
if t is main_thread:
continue
t.join()

php多线程抓取多个网页(爬虫所需技术及准备事项代码如下run_函数)

网站优化优采云 发表了文章 • 0 个评论 • 75 次浏览 • 2021-10-26 22:04 • 来自相关话题

  php多线程抓取多个网页(爬虫所需技术及准备事项代码如下run_函数)
  爬虫主要的运行时间消耗是请求一个网页时的io阻塞,所以开启多个线程,让不同的请求同时等待可以大大提高爬虫的运行效率。
  本文基于多线程(这里开了10个线程),使用github的api,抓取所有fork cpython项目的5000多个项目信息,并将数据存储在一个json文件中。
  抓取github的这个内容,在之前的文章文章中,展示了没有使用多线程的版本,这里是直接在此基础上的改进。
  爬虫需要的技术和准备
  爬虫代码如下
  import requests
import time
from threading import Thread
from queue import Queue
import json
def run_time(func):
def wrapper(*args, **kw):
start = time.time()
func(*args, **kw)
end = time.time()
print(&#39;running&#39;, end-start, &#39;s&#39;)
return wrapper
class Spider():
def __init__(self):
self.qurl = Queue()
self.data = list()
self.email = &#39;&#39; # 登录github用的邮箱
self.password = &#39;&#39; # 登录github用的密码
self.page_num = 171
self.thread_num = 10
def produce_url(self):
baseurl = &#39;https://api.github.com/repos/p ... ge%3D{}&#39;
for i in range(1, self.page_num + 1):
url = baseurl.format(i)
self.qurl.put(url) # 生成URL存入队列,等待其他线程提取
def get_info(self):
while not self.qurl.empty(): # 保证url遍历结束后能退出线程
url = self.qurl.get() # 从队列中获取URL
print(&#39;crawling&#39;, url)
req = requests.get(url, auth = (self.email, self.password))
data = req.json()
for datai in data:
result = {
&#39;project_name&#39;: datai[&#39;full_name&#39;],
&#39;project_url&#39;: datai[&#39;html_url&#39;],
&#39;project_api_url&#39;: datai[&#39;url&#39;],
&#39;star_count&#39;: datai[&#39;stargazers_count&#39;]
}
self.data.append(result)
@run_time
def run(self):
self.produce_url()
ths = []
for _ in range(self.thread_num):
th = Thread(target=self.get_info)
th.start()
ths.append(th)
for th in ths:
th.join()
s = json.dumps(self.data, ensure_ascii=False, indent=4)
with open(&#39;github_thread.json&#39;, &#39;w&#39;, encoding=&#39;utf-8&#39;) as f:
f.write(s)
print(&#39;Data crawling is finished.&#39;)
if __name__ == &#39;__main__&#39;:
Spider().run()
  读者只需要在Spider的__init__中指定自己的github邮箱和密码即可运行爬虫。
  爬虫描述如下
  1.run_time函数是计算程序运行时间的装饰器,作用于Spider对象的run函数
  2.蜘蛛类
  爬虫结果
  爬取结果显示如下
  
  该程序启动 10 个线程以获取 171 页需要 33 秒。在这个文章中,不使用多线程,耗时333秒。为了对多线程效率的提升有更清晰的体验,读者可以尝试修改上面代码中的self.page_num和self.thread_num。
  我这里做了个实验,self.page_num的值设置为20,表示总共会抓取20个页面
  一个问题
  最后,留下一个问题供读者思考:在之前的文章中,我们也实现了多线程爬虫。为什么当时的代码这么简单,现在却变得复杂了许多?
  跟进
  下一篇多线程爬虫文章将在翻页和爬取二级页面时实现多线程。
  栏目信息
  专栏首页:python编程
  栏目目录:目录
  履带目录:履带系列目录
  版本说明:软件和软件包版本说明 查看全部

  php多线程抓取多个网页(爬虫所需技术及准备事项代码如下run_函数)
  爬虫主要的运行时间消耗是请求一个网页时的io阻塞,所以开启多个线程,让不同的请求同时等待可以大大提高爬虫的运行效率。
  本文基于多线程(这里开了10个线程),使用github的api,抓取所有fork cpython项目的5000多个项目信息,并将数据存储在一个json文件中。
  抓取github的这个内容,在之前的文章文章中,展示了没有使用多线程的版本,这里是直接在此基础上的改进。
  爬虫需要的技术和准备
  爬虫代码如下
  import requests
import time
from threading import Thread
from queue import Queue
import json
def run_time(func):
def wrapper(*args, **kw):
start = time.time()
func(*args, **kw)
end = time.time()
print(&#39;running&#39;, end-start, &#39;s&#39;)
return wrapper
class Spider():
def __init__(self):
self.qurl = Queue()
self.data = list()
self.email = &#39;&#39; # 登录github用的邮箱
self.password = &#39;&#39; # 登录github用的密码
self.page_num = 171
self.thread_num = 10
def produce_url(self):
baseurl = &#39;https://api.github.com/repos/p ... ge%3D{}&#39;
for i in range(1, self.page_num + 1):
url = baseurl.format(i)
self.qurl.put(url) # 生成URL存入队列,等待其他线程提取
def get_info(self):
while not self.qurl.empty(): # 保证url遍历结束后能退出线程
url = self.qurl.get() # 从队列中获取URL
print(&#39;crawling&#39;, url)
req = requests.get(url, auth = (self.email, self.password))
data = req.json()
for datai in data:
result = {
&#39;project_name&#39;: datai[&#39;full_name&#39;],
&#39;project_url&#39;: datai[&#39;html_url&#39;],
&#39;project_api_url&#39;: datai[&#39;url&#39;],
&#39;star_count&#39;: datai[&#39;stargazers_count&#39;]
}
self.data.append(result)
@run_time
def run(self):
self.produce_url()
ths = []
for _ in range(self.thread_num):
th = Thread(target=self.get_info)
th.start()
ths.append(th)
for th in ths:
th.join()
s = json.dumps(self.data, ensure_ascii=False, indent=4)
with open(&#39;github_thread.json&#39;, &#39;w&#39;, encoding=&#39;utf-8&#39;) as f:
f.write(s)
print(&#39;Data crawling is finished.&#39;)
if __name__ == &#39;__main__&#39;:
Spider().run()
  读者只需要在Spider的__init__中指定自己的github邮箱和密码即可运行爬虫。
  爬虫描述如下
  1.run_time函数是计算程序运行时间的装饰器,作用于Spider对象的run函数
  2.蜘蛛类
  爬虫结果
  爬取结果显示如下
  
  该程序启动 10 个线程以获取 171 页需要 33 秒。在这个文章中,不使用多线程,耗时333秒。为了对多线程效率的提升有更清晰的体验,读者可以尝试修改上面代码中的self.page_num和self.thread_num。
  我这里做了个实验,self.page_num的值设置为20,表示总共会抓取20个页面
  一个问题
  最后,留下一个问题供读者思考:在之前的文章中,我们也实现了多线程爬虫。为什么当时的代码这么简单,现在却变得复杂了许多?
  跟进
  下一篇多线程爬虫文章将在翻页和爬取二级页面时实现多线程。
  栏目信息
  专栏首页:python编程
  栏目目录:目录
  履带目录:履带系列目录
  版本说明:软件和软件包版本说明

php多线程抓取多个网页(php中curl_multi()的速度比较_init)

网站优化优采云 发表了文章 • 0 个评论 • 71 次浏览 • 2021-10-26 21:09 • 来自相关话题

  php多线程抓取多个网页(php中curl_multi()的速度比较_init)
  本文介绍了 PHP 使用 curl_init() 和 curl_multi_init() 多线程的速度对比。分享给大家,供大家参考,如下:
  php中的curl_init()有很大的作用,尤其是在爬取网页内容或者文件信息的时候。比如curl_init()的强大在之前的文章《php使用curl进行头部检测和gzip压缩》中介绍过。
  curl_init() 以单线程模式处理事情。如果需要使用多线程模式进行事务处理,那么php为我们提供了一个函数curl_multi_init(),就是多线程模式处理事务的功能。
  curl_init() 和 curl_multi_init() 速度对比
  curl_multi_init() 多线程可以提高网页的处理速度吗?今天我将通过实验来验证这个问题。
  我今天的测试很简单,就是抓取网页内容,连续抓取5次,使用curl_init()和curl_multi_init()函数来完成,记录下两者的耗时,对比一下得出结论。
  首先,使用 curl_init() 在单个线程中抓取网页内容 5 次。
  程序代码如下:
  然后,使用 curl_multi_init() 多线程连续抓取网页内容 5 次。
  代码显示如下:
<p> 查看全部

  php多线程抓取多个网页(php中curl_multi()的速度比较_init)
  本文介绍了 PHP 使用 curl_init() 和 curl_multi_init() 多线程的速度对比。分享给大家,供大家参考,如下:
  php中的curl_init()有很大的作用,尤其是在爬取网页内容或者文件信息的时候。比如curl_init()的强大在之前的文章《php使用curl进行头部检测和gzip压缩》中介绍过。
  curl_init() 以单线程模式处理事情。如果需要使用多线程模式进行事务处理,那么php为我们提供了一个函数curl_multi_init(),就是多线程模式处理事务的功能。
  curl_init() 和 curl_multi_init() 速度对比
  curl_multi_init() 多线程可以提高网页的处理速度吗?今天我将通过实验来验证这个问题。
  我今天的测试很简单,就是抓取网页内容,连续抓取5次,使用curl_init()和curl_multi_init()函数来完成,记录下两者的耗时,对比一下得出结论。
  首先,使用 curl_init() 在单个线程中抓取网页内容 5 次。
  程序代码如下:
  然后,使用 curl_multi_init() 多线程连续抓取网页内容 5 次。
  代码显示如下:
<p>

php多线程抓取多个网页(《爬虫/蜘蛛程序的制作(C#语言)》一文)

网站优化优采云 发表了文章 • 0 个评论 • 82 次浏览 • 2021-10-12 14:25 • 来自相关话题

  php多线程抓取多个网页(《爬虫/蜘蛛程序的制作(C#语言)》一文)
  在《爬虫/蜘蛛程序制作(C#语言)》一文中,已经介绍了爬虫程序的基本实现方法。可以说已经实现了爬虫的功能。只是有效率问题,下载速度可能会很慢。这是由两个原因造成的: 分析和下载不能同时进行。在《爬虫/蜘蛛程序制作(C#语言)》中,已经介绍了爬虫程序的两个步骤:分析和下载。在单线程程序中,两者不能同时执行。也就是说,分析时网络会处于空闲状态,分析时间越长,下载效率越低。反之亦然,下载时不能同时进行分析,并且只有在下载停止后才能进行下一步分析。问题浮出水面,我想大家会想:如果在不同的线程中进行分析和下载,问题是不是就解决了?这只是一个单线程下载。相信大家都有下载Flash Express等资源的经历。里面可以设置线程数(近几年默认是10个,默认是5)。它会把文件分成和线程数一样的部分,然后每个线程下载自己的自己的部分,这样下载效率可能会有所提高,相信大家都有增加线程数来提高下载效率的经验,但是细心的用户会发现,在一定带宽的情况下,并不是线程变得更有效率。越多,速度越快,而是某一点的峰值。爬虫作为一种特殊的下载工具,没有多线程能力怎么能高效呢?信息时代爬虫的目的不就是快速获取信息吗?所以,爬虫需要有多个线程(数量可控)同时下载网页。
  好了,理解和分析问题后,问题解决了:多线程在C#中实现并不难。它有一个命名空间:System.Threading,它提供多线程支持。要启动一个新线程,需要进行如下初始化: ThreadStart startDownload newThreadStart( DownLoad //线程启动设置:每个线程执行DownLoad(),注意:DownLoad() 必须是一个不带参数的方法 Thread downloadThread newThread( startDownload //实例化new class to be open downloadThread.Start();//启动线程,因为线程开头启动的方法不能带参数,给多线程共享资源增加了麻烦。但是我们可以使用类级别的变量(的当然也可以用其他方法,我觉得这个方法最简单好用)来解决这个问题。了解了启用多线程下载的方法后,大家可能会有几个疑问:如何控制线程的结束?这里提出几个问题来解决这个问题: 线程数可以通过一个for循环来实现,就像我们年初学编程时的dot程序一样。例如,已知用户指定了 n 个(它是一个 int 变量)线程。可以用下面的方法启动5个A线程Thread[]downloadThread;//信誉下载线程,这就是C#的优点,就是数组初始化的时候,不需要指定其长度,而且只能在使用时指定。如何控制线程的结束?这里提出几个问题来解决这个问题: 线程数可以通过一个for循环来实现,就像我们年初学编程时的dot程序一样。例如,已知用户指定了 n 个(它是一个 int 变量)线程。可以用下面的方法启动5个A线程Thread[]downloadThread;//信誉下载线程,这就是C#的优点,就是数组初始化的时候,不需要指定其长度,而且只能在使用时指定。如何控制线程的结束?这里提出几个问题来解决这个问题: 线程数可以通过一个for循环来实现,就像我们年初学编程时的dot程序一样。例如,已知用户指定了 n 个(它是一个 int 变量)线程。可以用下面的方法启动5个A线程Thread[]downloadThread;//信誉下载线程,这就是C#的优点,就是数组初始化的时候,不需要指定其长度,而且只能在使用时指定。
  这个声明应该是类级别的,这样就可以提供其他方法控件,可以 ThreadStartstartDownload newThreadStart(DownLoad);//线程启动设置:即每个线程执行DownLoad()downloadThreadnewThread[newThread(startDownload);//指定the thread start setting downloadThread[i].Start();//下面出现的一个问题,一一启动线程:所有线程都调用了DonwLoad()方法,那么如何防止它们同时下载同一个网页时间?这个问题也很容易解决,只需要创建一个Url地址表,表中的每个地址只允许一个线程申请。具体实现:可以使用数据库创建表。表中有四列。一列专用于存储 URL 地址。另外两列存储地址对应的线程和地址已经申请的次数。最后一列存储下载的内容。(当然,对应的线程列不是必须的)。有线程申请时,将对应的线程列设置为当前线程号,将是否申请某列设置为申请一次,其他线程无法申请该页面。如果下载成功,则将内容存储在内容列表中。如果不成功,则内容栏仍为空,作为是否重新下载的依据之一,如果反复不成功,则该过程将达到重试次数(对应地址已申请的次数,用户可以设置),申请下一个Url地址。
  主要代码如下(使用VFP CREATE TABLE (ctablename) &amp;&amp;创建表ctablename.dbf,收录地址、文本内容、下载尝试次数、线程标志(初始值-1,线程标志是从0) 四 字段 cfullname ´.dbf´&amp;&amp; 添加扩展名 USE (cfullname) GO TOP LOCATE (EMPTY(ALLTRIM( ctext &amp;&amp;) ) 未成功下载的表应下载到属于权限的 Url 地址这个线程的,thisNum是当前线程的编号,可以通过参数获取gotUrl curlrecNum &amp;&amp; 如果在列表中找到这样的Url地址 UPDATE (cfullname) SET ldowned thisNumWHERE RECNO() recNum&amp;&amp; 更新表,更新这条记录被请求,即下载次数增加1,并且线程标志列设置为 编译该线程的cfulltablename ´.dbf´USE (cfulltablename) SET EXACT (csiteurl)&amp;&amp;csiteurl 为参数,即下载内容对应的URL地址 recNumNow RECNO()&amp;&amp; 得到收录这个地址的记录号 UPDATE (cfulltablename) SET ctext (ccontent)WHERE RECNO() recNumNow&amp;&amp;插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果有还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 加入列表,解决多线程中的线程冲突。csiteurl为参数,为下载内容对应的URL地址 recNumNow RECNO()&amp;&amp;获取收录该地址的记录号 UPDATE (cfulltablename) SET ctext (ccontent)WHERE RECNO() recNumNow&amp;&amp;插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 添加到列表中,这样多线程中的线程冲突是解决。csiteurl为参数,为下载内容对应的URL地址 recNumNow RECNO()&amp;&amp;获取收录该地址的记录号 UPDATE (cfulltablename) SET ctext (ccontent)WHERE RECNO() recNumNow&amp;&amp;插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 添加到列表中,这样多线程中的线程冲突是解决。插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 加入列表,所以解决了多线程中的线程冲突。插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 加入列表,所以解决了多线程中的线程冲突。
  当然,去重的问题也可以用C#语言解决,只需要创建一个临时文件(文本就够了),保存所有的Url地址,并为它们设置相应的属性,但是搜索效率可能没有那么快数据库。第二次后,仍然无法申请新的URL地址,则可以认为已经下载了所有链接。主要代码如下: string url inttimes );//调用GetAUrl方法尝试获取一个url times++;//尝试次数递增continue; //进行下一次尝试downloadThread[i].Abort;//退出进程//Continue 一步处理获取到的Url比较简单,因为在第一个问题中已经提示该线程称为a类级数组,非常容易控制。只需使用 for 循环结束。代码如下:)//关闭指定数量的线程n,一个蜘蛛程序就这样完成了,在C#面前,它的实现竟然如此简单。在这里我也想提醒读者:我只提供了一个想法和一个可实现的解决方案,但并不是最好的。即便是解决方案本身,也有很多可以改进的地方,留给读者去思考。最后说明一下我使用的环境:winXP sp2 Pro VFP 9.0 Visual Studio 2003 .net 中文企业版 可以改进的地方很多,留给读者去思考。最后说明一下我使用的环境:winXP sp2 Pro VFP 9.0 Visual Studio 2003 .net 中文企业版 可以改进的地方很多,留给读者去思考。最后说明一下我使用的环境:winXP sp2 Pro VFP 9.0 Visual Studio 2003 .net 中文企业版 查看全部

  php多线程抓取多个网页(《爬虫/蜘蛛程序的制作(C#语言)》一文)
  在《爬虫/蜘蛛程序制作(C#语言)》一文中,已经介绍了爬虫程序的基本实现方法。可以说已经实现了爬虫的功能。只是有效率问题,下载速度可能会很慢。这是由两个原因造成的: 分析和下载不能同时进行。在《爬虫/蜘蛛程序制作(C#语言)》中,已经介绍了爬虫程序的两个步骤:分析和下载。在单线程程序中,两者不能同时执行。也就是说,分析时网络会处于空闲状态,分析时间越长,下载效率越低。反之亦然,下载时不能同时进行分析,并且只有在下载停止后才能进行下一步分析。问题浮出水面,我想大家会想:如果在不同的线程中进行分析和下载,问题是不是就解决了?这只是一个单线程下载。相信大家都有下载Flash Express等资源的经历。里面可以设置线程数(近几年默认是10个,默认是5)。它会把文件分成和线程数一样的部分,然后每个线程下载自己的自己的部分,这样下载效率可能会有所提高,相信大家都有增加线程数来提高下载效率的经验,但是细心的用户会发现,在一定带宽的情况下,并不是线程变得更有效率。越多,速度越快,而是某一点的峰值。爬虫作为一种特殊的下载工具,没有多线程能力怎么能高效呢?信息时代爬虫的目的不就是快速获取信息吗?所以,爬虫需要有多个线程(数量可控)同时下载网页。
  好了,理解和分析问题后,问题解决了:多线程在C#中实现并不难。它有一个命名空间:System.Threading,它提供多线程支持。要启动一个新线程,需要进行如下初始化: ThreadStart startDownload newThreadStart( DownLoad //线程启动设置:每个线程执行DownLoad(),注意:DownLoad() 必须是一个不带参数的方法 Thread downloadThread newThread( startDownload //实例化new class to be open downloadThread.Start();//启动线程,因为线程开头启动的方法不能带参数,给多线程共享资源增加了麻烦。但是我们可以使用类级别的变量(的当然也可以用其他方法,我觉得这个方法最简单好用)来解决这个问题。了解了启用多线程下载的方法后,大家可能会有几个疑问:如何控制线程的结束?这里提出几个问题来解决这个问题: 线程数可以通过一个for循环来实现,就像我们年初学编程时的dot程序一样。例如,已知用户指定了 n 个(它是一个 int 变量)线程。可以用下面的方法启动5个A线程Thread[]downloadThread;//信誉下载线程,这就是C#的优点,就是数组初始化的时候,不需要指定其长度,而且只能在使用时指定。如何控制线程的结束?这里提出几个问题来解决这个问题: 线程数可以通过一个for循环来实现,就像我们年初学编程时的dot程序一样。例如,已知用户指定了 n 个(它是一个 int 变量)线程。可以用下面的方法启动5个A线程Thread[]downloadThread;//信誉下载线程,这就是C#的优点,就是数组初始化的时候,不需要指定其长度,而且只能在使用时指定。如何控制线程的结束?这里提出几个问题来解决这个问题: 线程数可以通过一个for循环来实现,就像我们年初学编程时的dot程序一样。例如,已知用户指定了 n 个(它是一个 int 变量)线程。可以用下面的方法启动5个A线程Thread[]downloadThread;//信誉下载线程,这就是C#的优点,就是数组初始化的时候,不需要指定其长度,而且只能在使用时指定。
  这个声明应该是类级别的,这样就可以提供其他方法控件,可以 ThreadStartstartDownload newThreadStart(DownLoad);//线程启动设置:即每个线程执行DownLoad()downloadThreadnewThread[newThread(startDownload);//指定the thread start setting downloadThread[i].Start();//下面出现的一个问题,一一启动线程:所有线程都调用了DonwLoad()方法,那么如何防止它们同时下载同一个网页时间?这个问题也很容易解决,只需要创建一个Url地址表,表中的每个地址只允许一个线程申请。具体实现:可以使用数据库创建表。表中有四列。一列专用于存储 URL 地址。另外两列存储地址对应的线程和地址已经申请的次数。最后一列存储下载的内容。(当然,对应的线程列不是必须的)。有线程申请时,将对应的线程列设置为当前线程号,将是否申请某列设置为申请一次,其他线程无法申请该页面。如果下载成功,则将内容存储在内容列表中。如果不成功,则内容栏仍为空,作为是否重新下载的依据之一,如果反复不成功,则该过程将达到重试次数(对应地址已申请的次数,用户可以设置),申请下一个Url地址。
  主要代码如下(使用VFP CREATE TABLE (ctablename) &amp;&amp;创建表ctablename.dbf,收录地址、文本内容、下载尝试次数、线程标志(初始值-1,线程标志是从0) 四 字段 cfullname ´.dbf´&amp;&amp; 添加扩展名 USE (cfullname) GO TOP LOCATE (EMPTY(ALLTRIM( ctext &amp;&amp;) ) 未成功下载的表应下载到属于权限的 Url 地址这个线程的,thisNum是当前线程的编号,可以通过参数获取gotUrl curlrecNum &amp;&amp; 如果在列表中找到这样的Url地址 UPDATE (cfullname) SET ldowned thisNumWHERE RECNO() recNum&amp;&amp; 更新表,更新这条记录被请求,即下载次数增加1,并且线程标志列设置为 编译该线程的cfulltablename ´.dbf´USE (cfulltablename) SET EXACT (csiteurl)&amp;&amp;csiteurl 为参数,即下载内容对应的URL地址 recNumNow RECNO()&amp;&amp; 得到收录这个地址的记录号 UPDATE (cfulltablename) SET ctext (ccontent)WHERE RECNO() recNumNow&amp;&amp;插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果有还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 加入列表,解决多线程中的线程冲突。csiteurl为参数,为下载内容对应的URL地址 recNumNow RECNO()&amp;&amp;获取收录该地址的记录号 UPDATE (cfulltablename) SET ctext (ccontent)WHERE RECNO() recNumNow&amp;&amp;插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 添加到列表中,这样多线程中的线程冲突是解决。csiteurl为参数,为下载内容对应的URL地址 recNumNow RECNO()&amp;&amp;获取收录该地址的记录号 UPDATE (cfulltablename) SET ctext (ccontent)WHERE RECNO() recNumNow&amp;&amp;插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 添加到列表中,这样多线程中的线程冲突是解决。插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 加入列表,所以解决了多线程中的线程冲突。插入对应地址的对应内容 ctablename ´.dbf´USE (ctablename) GO TOP SET EXACT (cnewurl)&amp;&amp;查找是否有这个地址&amp;&amp;如果还没有这个地址 SET CARRY OFF INSERT &amp;&amp;设置主页地址 加入列表,所以解决了多线程中的线程冲突。
  当然,去重的问题也可以用C#语言解决,只需要创建一个临时文件(文本就够了),保存所有的Url地址,并为它们设置相应的属性,但是搜索效率可能没有那么快数据库。第二次后,仍然无法申请新的URL地址,则可以认为已经下载了所有链接。主要代码如下: string url inttimes );//调用GetAUrl方法尝试获取一个url times++;//尝试次数递增continue; //进行下一次尝试downloadThread[i].Abort;//退出进程//Continue 一步处理获取到的Url比较简单,因为在第一个问题中已经提示该线程称为a类级数组,非常容易控制。只需使用 for 循环结束。代码如下:)//关闭指定数量的线程n,一个蜘蛛程序就这样完成了,在C#面前,它的实现竟然如此简单。在这里我也想提醒读者:我只提供了一个想法和一个可实现的解决方案,但并不是最好的。即便是解决方案本身,也有很多可以改进的地方,留给读者去思考。最后说明一下我使用的环境:winXP sp2 Pro VFP 9.0 Visual Studio 2003 .net 中文企业版 可以改进的地方很多,留给读者去思考。最后说明一下我使用的环境:winXP sp2 Pro VFP 9.0 Visual Studio 2003 .net 中文企业版 可以改进的地方很多,留给读者去思考。最后说明一下我使用的环境:winXP sp2 Pro VFP 9.0 Visual Studio 2003 .net 中文企业版

官方客服QQ群

微信人工客服

QQ人工客服


线