PHP採集商家資訊及採集方法概述(下)

技術小胖子發表於2017-11-07

 下面我們來上程式碼

資料庫採用PDO 主要用到了預處理 關於預處理的內容

參考:PHP5中PDO(PHP DATA OBJECT)模組基礎詳解

還有一個phpquery 原始碼下載 這個稍後在給出具體的教程

 

第一步:

基本的配置 資料庫檔案在第一講裡面

資料庫連線:conn.php


  1. <?php 
  2.     define(`DB_USER``root`);  
  3.     define(`DB_PASSWORD`);  
  4.     define(`DB_CHARSET``utf8`);  
  5.     try {  
  6.         $DBH = new PDO(`mysql:host=localhost;dbname=shopyijia`, DB_USER, DB_PASSWORD);  
  7.         $DBH->exec(`SET CHARACTER SET `.DB_CHARSET);  
  8.         $DBH->exec(`SET NAMES `.DB_CHARSET);  
  9.         /*  
  10.          * 如果想要在指令碼結束的時候不釋放連結那麼在引數裡面加上array(PDO::ATTR_PERSISTENT => true)不過一般情況下可以不用常連結  
  11.         $dbh = new PDO(`mysql:host=localhost;dbname=test`, $user, $pass, array(  
  12.             PDO::ATTR_PERSISTENT => true  
  13.             ));  
  14.          */  
  15.     } catch (PDOException $e) {  
  16.         print “Error!: “ . $e->getMessage() . “<br/>”;  
  17.         die();  
  18.     }  

 

 

第二步:

手動新增一級分類的資訊地址

 

第三步:

爬取二級分類

 


  1. <?php 
  2. /* 
  3.  * 獲取所有商家目錄資訊 
  4.  */ 
  5. header(“Content-type:text/html;charset=utf8”); 
  6. set_time_limit(0); 
  7. define(`SHOP_BASE_URL``http://shop.yijia.com`); 
  8. require_once `conn.php`//資料庫初始化 
  9. require(`phpQuery/phpQuery.php`); //採集器初始化 
  10. $Sql = `SELECT * FROM yj_shop_category WHERE is_grab=`0` AND sc_parent_id=0`
  11. $un_grab_cat = $DBH->query($Sql)->fetchAll(); //爬取一級分類下面的二級分類頁面 
  12. //預處理SQL 
  13. $stmt = $DBH->prepare(`INSERT INTO yj_shop_category(sc_name,sc_parent_id,sc_url,sc_add_time) VALUES (:sc_name,:sc_parent_id,:sc_url,:sc_add_time)`);  
  14. $sc_name = $sc_parent_id = $sc_url = $sc_add_time = null; 
  15.  
  16. $stmt->bindParam(`:sc_name`$sc_name); //  
  17. $stmt->bindParam(`:sc_parent_id`$sc_parent_id); 
  18. $stmt->bindParam(`:sc_url`$sc_url);  
  19. $stmt->bindParam(`:sc_add_time`$sc_add_time);   
  20.  
  21. foreach ($un_grab_cat as $_key => $_value){ 
  22.     $sc_url = $_value[`sc_url`]; 
  23.     $sc_parent_id = $_value[`sc_id`];//父分類id 
  24.     $file = file_get_contents($sc_url); 
  25.     $dom = phpQuery::newDocument($file);  //初始化物件 
  26.     foreach(pq(“#dd_open_1 ul > li”as $item){ 
  27.         $sc_name =  pq($item)->text(); 
  28.         $sc_url =  SHOP_BASE_URL.pq($item)->find(`a:first`)->attr(`href`); 
  29.         $sc_add_time = time(); 
  30.         $stmt->execute();  
  31.     } 
  32.     phpQuery::$documents = array(); 
  33. echo `over`
  34. die(); 

 

第四步:

爬取二級分類的頁面更新對應的分頁

 


  1. <?php 
  2. header(“Content-type:text/html;charset=utf8”); 
  3. set_time_limit(0); 
  4. define(`SHOP_BASE_URL``http://shop.yijia.com`); 
  5. require_once `conn.php`//資料庫初始化 
  6. require(`phpQuery/phpQuery.php`); //採集器初始化 
  7. $Sql = `SELECT sc_id,sc_url FROM yj_shop_category WHERE is_grab=`0` AND sc_parent_id!=0`
  8. $un_grab_cat = $DBH->query($Sql)->fetchAll(); //爬取一級分類下面的二級分類頁面 
  9. //預處理SQL 
  10. $stmt = $DBH->prepare(`UPDATE yj_shop_category SET sc_page_num = :sc_page_num WHERE sc_id = :sc_id`);  
  11. $sc_page_num = $sc_id  = null; 
  12.  
  13. $stmt->bindParam(`:sc_page_num`$sc_page_num); //  
  14. $stmt->bindParam(`:sc_id`$sc_id);   
  15.  
  16. foreach ($un_grab_cat as $_key => $_value){ 
  17.     $sc_id = $_value[`sc_id`]; 
  18.     $sc_url = $_value[`sc_url`]; 
  19.     $file = file_get_contents($sc_url); 
  20.     $dom = phpQuery::newDocument($file);  //初始化物件 
  21.     $last_a = pq(`div.pager > a:last`); 
  22.     $A_parm = explode(`_`, pq($last_a)->attr(`href`)); 
  23.     $sc_page_num = intval($A_parm[5]); 
  24.     $stmt->execute(); 
  25.     phpQuery::$documents = array(); 
  26.     sleep(1); 
  27. echo `over`
  28. die(); 

第五步:

爬取二級分類所有分頁的商家資訊

 


  1. <?php 
  2. /* 
  3.  * 獲取所有商家資訊 
  4.  */ 
  5. header(“Content-type:text/html;charset=utf8”); 
  6. set_time_limit(0); 
  7. error_reporting(E_ALL); 
  8. define(`SHOP_BASE_URL``http://shop.yijia.com`); 
  9. require_once `conn.php`//資料庫初始化 
  10. require(`phpQuery/phpQuery.php`); //採集器初始化 
  11. $Sql = `SELECT sc_id,sc_url,sc_page_num,sc_current_page_num FROM yj_shop_category WHERE is_grab=`0` AND sc_parent_id!=0`
  12. $un_grab_cat = $DBH->query($Sql)->fetchAll(); //獲取所有的未被抓取的二級分類資訊 
  13.  
  14. foreach ($un_grab_cat as $_key => $_value){ 
  15.     $sc_url = $_value[`sc_url`]; 
  16.     $sc_id = $_value[`sc_id`];//父分類id 
  17.     if($_value[`sc_page_num`] == `0`){ //如果只有一頁  
  18.         $sc_tmp_url = $sc_url
  19.         if(getPageShopInfo($sc_tmp_url,$sc_id)){ 
  20.             $DBH->exec(`UPDATE yj_shop_category SET is_grab=1 WHERE sc_id=`.$sc_id);             
  21.         } 
  22.     }else//如果有多頁 
  23.         for($i=$_value[`sc_current_page_num`];$i<=$_value[`sc_page_num`];$i++){ 
  24.             $A_param = explode(`_`$sc_url); 
  25.             $A_param[2] = intval($A_param[2]).`_0_0_`.$i.`/`
  26.             $sc_tmp_url = implode(`_`,$A_param);//拼接出來一個的url 要符合當前的規則哦 以後可能會有變動哦             
  27.             if(getPageShopInfo($sc_tmp_url$sc_id)){ 
  28.                 $DBH->exec(`UPDATE yj_shop_category SET sc_current_page_num=`.$i.` WHERE sc_id=`.$sc_id); 
  29.                 $last_page = $i
  30.             } 
  31.         } 
  32.         if($last_page == $_value[`sc_page_num`]){ //如果後一個分頁爬取完成 那麼更新當前 這個分類的狀態為已抓取 
  33.             $DBH->exec(`UPDATE yj_shop_category SET is_grab=1 WHERE sc_id=`.$sc_id); 
  34.         } 
  35.          
  36.     } 
  37.  
  38. function getPageShopInfo($url,$sc_parent_id){ 
  39.     global $DBH
  40.     $stmt = $DBH->prepare(`INSERT INTO yj_shop_information(si_name,si_cat_id,si_yijia_url,si_logo_url,si_front_desc,si_add_time) VALUES (:si_name,:si_cat_id,:si_yijia_url,:si_logo_url,:si_front_desc,:si_add_time)`);  
  41.     $si_name = $si_cat_id = $si_yijia_url = $si_logo_url = $si_front_desc =  $si_add_time = null; 
  42.     $stmt->bindParam(`:si_name`$si_name);  
  43.     $stmt->bindParam(`:si_cat_id`$si_cat_id);  
  44.     $stmt->bindParam(`:si_yijia_url`$si_yijia_url);  
  45.     $stmt->bindParam(`:si_logo_url`$si_logo_url);  
  46.     $stmt->bindParam(`:si_front_desc`$si_front_desc);  
  47.     $stmt->bindParam(`:si_add_time`$si_add_time);  
  48.      
  49.     $file = file_get_contents($url); 
  50.     $dom = phpQuery::newDocument($file);  //初始化物件 
  51.     foreach ($dom->find(`div.shopping_list`as $item){ //迴圈節點 
  52.         $si_name = pq($item)->find(`h2:first > a:first`)->text(); //店鋪名稱 
  53.         $si_cat_id = $sc_parent_id//分類名稱 
  54.         $si_yijia_url = SHOP_BASE_URL.pq($item)->find(`h2:first > a:first`)->attr(`href`); //一家網中商家介紹頁面 
  55.         $si_logo_url =  pq($item)->find(`div.fl > a > img:first`)->attr(`src`); 
  56.         $si_front_desc =  pq($item)->find(`div.shopping_description:first`)->text(); 
  57.         $si_add_time = time(); 
  58.         $stmt->execute(); 
  59.     } 
  60.     phpQuery::$documents = array(); 
  61.     sleep(1);//休息一秒 友情點 不要給他們太大壓力是吧 
  62.     return true; 
  63.  
  64.  
  65. echo `over`
  66. die(); 

 

 

第六步:獲取商家的真實url 和具體的描述

 


  1. <?php 
  2. /* 
  3.  * 獲取商家的具體資訊 
  4.  */ 
  5. header(“Content-type:text/html;charset=utf8”); 
  6. set_time_limit(0); 
  7. define(`SHOP_BASE_URL``http://shop.yijia.com`); 
  8. require_once `conn.php`//資料庫初始化 
  9. require(`phpQuery/phpQuery.php`); //採集器初始化 
  10. $Sql = `SELECT si_id,si_yijia_url  FROM yj_shop_information WHERE si_shop_url =“ `
  11. $un_grab_cat = $DBH->query($Sql)->fetchAll(); //所有的沒有被重新爬取的商家url 
  12.  
  13. //更新預處理SQL 
  14.  
  15. $stmt = $DBH->prepare(`UPDATE yj_shop_information SET si_shop_url=:si_shop_url,si_true_url=:si_true_url,si_desc=:si_desc WHERE si_id=:si_id`);  
  16.  
  17. $si_true_url = $si_shop_url  = $si_desc = $si_id = $sc_add_time = null; 
  18.  
  19. $stmt->bindParam(`:si_true_url`$si_true_url); //  
  20. $stmt->bindParam(`:si_shop_url`$si_shop_url); //  
  21. $stmt->bindParam(`:si_desc`$si_desc); 
  22. $stmt->bindParam(`:si_id`$si_id);  
  23. $i=1; 
  24. foreach ($un_grab_cat as $_key => $_value){ 
  25.     $si_yijia_url = $_value[`si_yijia_url`]; 
  26.     $si_id = $_value[`si_id`];//id 
  27.     $file = file_get_contents($si_yijia_url); 
  28.     $dom = phpQuery::newDocument($file);  //初始化物件 
  29.     $si_shop_url = SHOP_BASE_URL.pq(`div.shop_logo > a:first`)->attr(`href`); 
  30.     $http_info = getContents($si_shop_url); 
  31.     $si_true_url = $http_info[`url`]; 
  32.     $si_desc = pq(`div.shop_detailinfo > strong:first`)->text(); 
  33.     $stmt->execute(); 
  34.     if(fmod($i,3) == 0) 
  35.     sleep(1); 
  36.  
  37.     $i++; 
  38.     phpQuery::$documents = array(); 
  39.  
  40. function getContents($url){ 
  41.   $header = array(“Referer:http://www.tx29.com/”); 
  42.   $ch = curl_init(); 
  43.   curl_setopt($ch, CURLOPT_URL, $url); 
  44.   curl_setopt($ch, CURLOPT_TIMEOUT, 30); 
  45.   curl_setopt($ch, CURLOPT_HTTPHEADER,$header); 
  46.   curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1); 
  47.   ob_start(); 
  48.   curl_exec($ch); 
  49.   ob_end_clean(); 
  50.   $x = curl_getinfo($ch); 
  51.   curl_close($ch); 
  52.   return $x
  53.  
  54.  
  55.  
  56. echo `over`
  57. die(); 


最後算了下時間 如果友情爬取的話需要48個小時。可以分幾個ip多個指令碼跑沒問題。 那個我 這裡爬取好的資料如果非同行需要的話 留言聯絡…..同行的就自己抓取把

這裡最後說下不要暴力爬取哦

 

 

    本文轉自kefirking 51CTO部落格,原文連結:http://blog.51cto.com/phpzf/799555,如需轉載請自行聯絡原作者


相關文章