加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

PHP开发:使用PHP抓取百万知乎用户以及知识点札记

发布时间:2016-10-16 04:07:17 所属栏目:PHP教程 来源:博客园
导读:副标题#e# 代码托管地址:https://github.com/hhqcontinue/zhihuSpider 开发前的准备 安装Linux系统(Ubuntu14.04),在VMWare虚拟机下安装一个Ubuntu; 安装PHP5.6或以上版本; 安装curl、pcntl扩展。 使用PHP的curl扩展抓取页面数据 PHP的curl扩展是PHP支

其中, ls -l 是长列表输出该目录下的文件信息(这里的文件可以是目录、链接、设备文件等); grep "^-" 过滤长列表输出信息, "^-"  只保留一般文件,如果只保留目录是 "^d" ; wc -l 是统计输出信息的行数。下面是一个运行示例:

PHP开发:使用PHP抓取百万知乎用户以及知识点札记

 插入MySQL时重复数据的处理

程序运行了一段时间后,发现有很多用户的数据是重复的,因此需要在插入重复用户数据的时候做处理。处理方案如下:

1)插入数据库之前检查数据是否已经存在数据库;

2)添加唯一索引,插入时使用 INSERT INTO ... ON DUPLICATE KEY UPDATE...

3)添加唯一索引,插入时使用 INSERT INGNORE INTO...

4)添加唯一索引,插入时使用 REPLACE INTO...

使用curl_multi实现多线程抓取页面

刚开始单进程而且单个curl去抓取数据,速度很慢,挂机爬了一个晚上只能抓到2W的数据,于是便想到能不能在进入新的用户页面发curl请求的时候一次性请求多个用户,后来发现了curl_multi这个好东西。curl_multi这类函数可以实现同时请求多个url,而不是一个个请求,这类似于linux系统中一个进程开多条线程执行的功能。下面是使用curl_multi实现多线程爬虫的示例:

  1. $mh = curl_multi_init(); //返回一个新cURL批处理句柄 
  2.         for ($i = 0; $i < $max_size; $i++) 
  3.         { 
  4.             $ch = curl_init();  //初始化单个cURL会话 
  5.             curl_setopt($ch, CURLOPT_HEADER, 0); 
  6.             curl_setopt($ch, CURLOPT_URL, 'http://www.zhihu.com/people/' . $user_list[$i] . '/about'); 
  7.             curl_setopt($ch, CURLOPT_COOKIE, self::$user_cookie); 
  8.             curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36'); 
  9.             curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  
  10.             curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
  11.             $requestMap[$i] = $ch; 
  12.             curl_multi_add_handle($mh, $ch);  //向curl批处理会话中添加单独的curl句柄 
  13.         } 
  14.  
  15.         $user_arr = array(); 
  16.         do { 
  17.                         //运行当前 cURL 句柄的子连接 
  18.             while (($cme = curl_multi_exec($mh, $active)) == CURLM_CALL_MULTI_PERFORM); 
  19.              
  20.             if ($cme != CURLM_OK) {break;} 
  21.                         //获取当前解析的cURL的相关传输信息 
  22.             while ($done = curl_multi_info_read($mh)) 
  23.             { 
  24.                 $info = curl_getinfo($done['handle']); 
  25.                 $tmp_result = curl_multi_getcontent($done['handle']); 
  26.                 $error = curl_error($done['handle']); 
  27.  
  28.                 $user_arr[] = array_values(getUserInfo($tmp_result)); 
  29.  
  30.                 //保证同时有$max_size个请求在处理 
  31.                 if ($i < sizeof($user_list) && isset($user_list[$i]) && $i < count($user_list)) 
  32.                 { 
  33.                     $ch = curl_init(); 
  34.                     curl_setopt($ch, CURLOPT_HEADER, 0); 
  35.                     curl_setopt($ch, CURLOPT_URL, 'http://www.zhihu.com/people/' . $user_list[$i] . '/about'); 
  36.                     curl_setopt($ch, CURLOPT_COOKIE, self::$user_cookie); 
  37.                     curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36'); 
  38.                     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  
  39.                     curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
  40.                     $requestMap[$i] = $ch; 
  41.                     curl_multi_add_handle($mh, $ch); 
  42.  
  43.                     $i++; 
  44.                 } 
  45.  
  46.                 curl_multi_remove_handle($mh, $done['handle']); 
  47.             } 
  48.  
  49.             if ($active) 
  50.                 curl_multi_select($mh, 10); 
  51.         } while ($active); 
  52.  
  53.         curl_multi_close($mh); 
  54.         return $user_arr; 

HTTP 429 Too Many Requests

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读