下面我們來上代碼
資料庫采用PDO 主要用到了預處理 關于預處理的内容
基本的配置 資料庫檔案在第一講裡面
資料庫連接配接:conn.php
<?php
define('DB_USER', 'root');
define('DB_PASSWORD', '');
define('DB_CHARSET', 'utf8');
try {
$DBH = new PDO('mysql:host=localhost;dbname=shopyijia', DB_USER, DB_PASSWORD);
$DBH->exec('SET CHARACTER SET '.DB_CHARSET);
$DBH->exec('SET NAMES '.DB_CHARSET);
/*
* 如果想要在腳本結束的時候不釋放連結那麼在參數裡面加上array(PDO::ATTR_PERSISTENT => true)不過一般情況下可以不用常連結
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(
PDO::ATTR_PERSISTENT => true
));
*/
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
手動添加一級分類的資訊位址
<a target="_blank" href="http://blog.51cto.com/attachment/201203/160643787.png"></a>
爬取二級分類
/*
* 擷取所有商家目錄資訊
*/
header("Content-type:text/html;charset=utf8");
set_time_limit(0);
define('SHOP_BASE_URL', 'http://shop.yijia.com');
require_once 'conn.php'; //資料庫初始化
require('phpQuery/phpQuery.php'); //采集器初始化
$Sql = 'SELECT * FROM yj_shop_category WHERE is_grab=\'0\' AND sc_parent_id=0';
$un_grab_cat = $DBH->query($Sql)->fetchAll(); //爬取一級分類下面的二級分類頁面
//預處理SQL
$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)');
$sc_name = $sc_parent_id = $sc_url = $sc_add_time = null;
$stmt->bindParam(':sc_name', $sc_name); //
$stmt->bindParam(':sc_parent_id', $sc_parent_id);
$stmt->bindParam(':sc_url', $sc_url);
$stmt->bindParam(':sc_add_time', $sc_add_time);
foreach ($un_grab_cat as $_key => $_value){
$sc_url = $_value['sc_url'];
$sc_parent_id = $_value['sc_id'];//父分類id
$file = file_get_contents($sc_url);
$dom = phpQuery::newDocument($file); //初始化對象
foreach(pq("#dd_open_1 ul > li") as $item){
$sc_name = pq($item)->text();
$sc_url = SHOP_BASE_URL.pq($item)->find('a:first')->attr('href');
$sc_add_time = time();
$stmt->execute();
}
phpQuery::$documents = array();
}
echo 'over';
die();
爬取二級分類的頁面更新對應的分頁
$Sql = 'SELECT sc_id,sc_url FROM yj_shop_category WHERE is_grab=\'0\' AND sc_parent_id!=0';
$stmt = $DBH->prepare('UPDATE yj_shop_category SET sc_page_num = :sc_page_num WHERE sc_id = :sc_id');
$sc_page_num = $sc_id = null;
$stmt->bindParam(':sc_page_num', $sc_page_num); //
$stmt->bindParam(':sc_id', $sc_id);
$sc_id = $_value['sc_id'];
$last_a = pq('div.pager > a:last');
$A_parm = explode('_', pq($last_a)->attr('href'));
$sc_page_num = intval($A_parm[5]);
$stmt->execute();
sleep(1);
爬取二級分類所有分頁的商家資訊
* 擷取所有商家資訊
error_reporting(E_ALL);
$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';
$un_grab_cat = $DBH->query($Sql)->fetchAll(); //擷取所有的未被抓取的二級分類資訊
$sc_id = $_value['sc_id'];//父分類id
if($_value['sc_page_num'] == '0'){ //如果隻有一頁
$sc_tmp_url = $sc_url;
if(getPageShopInfo($sc_tmp_url,$sc_id)){
$DBH->exec('UPDATE yj_shop_category SET is_grab=1 WHERE sc_id='.$sc_id);
}
}else{ //如果有多頁
for($i=$_value['sc_current_page_num'];$i<=$_value['sc_page_num'];$i++){
$A_param = explode('_', $sc_url);
$A_param[2] = intval($A_param[2]).'_0_0_'.$i.'/';
$sc_tmp_url = implode('_',$A_param);//拼接出來一個的url 要符合目前的規則哦 以後可能會有變動哦
if(getPageShopInfo($sc_tmp_url, $sc_id)){
$DBH->exec('UPDATE yj_shop_category SET sc_current_page_num='.$i.' WHERE sc_id='.$sc_id);
$last_page = $i;
}
if($last_page == $_value['sc_page_num']){ //如果後一個分頁爬取完成 那麼更新目前 這個分類的狀态為已抓取
$DBH->exec('UPDATE yj_shop_category SET is_grab=1 WHERE sc_id='.$sc_id);
function getPageShopInfo($url,$sc_parent_id){
global $DBH;
$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)');
$si_name = $si_cat_id = $si_yijia_url = $si_logo_url = $si_front_desc = $si_add_time = null;
$stmt->bindParam(':si_name', $si_name);
$stmt->bindParam(':si_cat_id', $si_cat_id);
$stmt->bindParam(':si_yijia_url', $si_yijia_url);
$stmt->bindParam(':si_logo_url', $si_logo_url);
$stmt->bindParam(':si_front_desc', $si_front_desc);
$stmt->bindParam(':si_add_time', $si_add_time);
$file = file_get_contents($url);
foreach ($dom->find('div.shopping_list') as $item){ //循環節點
$si_name = pq($item)->find('h2:first > a:first')->text(); //店鋪名稱
$si_cat_id = $sc_parent_id; //分類名稱
$si_yijia_url = SHOP_BASE_URL.pq($item)->find('h2:first > a:first')->attr('href'); //一家網中商家介紹頁面
$si_logo_url = pq($item)->find('div.fl > a > img:first')->attr('src');
$si_front_desc = pq($item)->find('div.shopping_description:first')->text();
$si_add_time = time();
$stmt->execute();
sleep(1);//休息一秒 友情點 不要給他們太大壓力是吧
return true;
* 擷取商家的具體資訊
$Sql = 'SELECT si_id,si_yijia_url FROM yj_shop_information WHERE si_shop_url =\'\' ';
$un_grab_cat = $DBH->query($Sql)->fetchAll(); //所有的沒有被重新爬取的商家url
//更新預處理SQL
$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');
$si_true_url = $si_shop_url = $si_desc = $si_id = $sc_add_time = null;
$stmt->bindParam(':si_true_url', $si_true_url); //
$stmt->bindParam(':si_shop_url', $si_shop_url); //
$stmt->bindParam(':si_desc', $si_desc);
$stmt->bindParam(':si_id', $si_id);
$i=1;
$si_yijia_url = $_value['si_yijia_url'];
$si_id = $_value['si_id'];//id
$file = file_get_contents($si_yijia_url);
$si_shop_url = SHOP_BASE_URL.pq('div.shop_logo > a:first')->attr('href');
$http_info = getContents($si_shop_url);
$si_true_url = $http_info['url'];
$si_desc = pq('div.shop_detailinfo > strong:first')->text();
if(fmod($i,3) == 0)
$i++;
function getContents($url){
$header = array("Referer:http://www.tx29.com/");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
ob_start();
curl_exec($ch);
ob_end_clean();
$x = curl_getinfo($ch);
curl_close($ch);
return $x;
最後算了下時間 如果友情爬取的話需要48個小時。可以分幾個ip多個腳本跑沒問題。 那個我 這裡爬取好的資料如果非同行需要的話 留言聯系.....同行的就自己抓取把
這裡最後說下不要暴力爬取哦
本文轉自kefirking 51CTO部落格,原文連結:http://blog.51cto.com/phpzf/799555,如需轉載請自行聯系原作者