1 <?php 2 /** 3 * 抓取“维库电子市场”供应商主程序 4 * author Lee. 5 * Last modify $Date: 2012-2-3 9:30:21 $ 6 * 注:本程序按照编码 GB2312 执行,因为“维库电子市场”网站是GB2312编码,数据库也得保持一致 7 */ 8 class weiku { 9 private $key; // 型号 10 private $pageNum; // 页码 11 12 /** 13 * 入口程序 14 */ 15 public function go($key) { 16 $this->key = $key; 17 $this->pageNum = $this->getPageNum(); 18 $this->getInfo(); 19 } 20 21 /** 22 * 获取供应商 url 链接数组 23 * @return ArrayObject 24 */ 25 private function getInfo() { 26 if ($this->pageNum==1) { # 处理只有一页的情况 27 $arr = $this->shopAddContact($this->shopUrlMatchReArr($this->getContent())); 28 $this->isAddSuccess($arr); 29 } elseif ($this->pageNum>1) { # 多页 30 for ($i=1; $i<=$this->pageNum; $i++) { 31 $arr = $this->shopAddContact($this->shopUrlMatchReArr($this->getContent($i))); 32 $this->isAddSuccess($arr); 33 } 34 } 35 } 36 37 /** 38 * 打印是否添加成功 39 * @param ArrayObject $arr 40 * @return string 41 */ 42 private function isAddSuccess($arr) { 43 foreach ($arr as $k=>$v) { 44 if ($this->execAdd($this->getInfoByShopUrl($v))) { 45 echo 'Add Success!!'; 46 } else { 47 echo 'Add Faild!!'; 48 } 49 } 50 } 51 52 /** 53 * 执行添加到数据库 54 * @param ArrayObject $infoArr 55 * @return Number 受影响的行数 56 */ 57 private function execAdd($infoArr) { 58 $mysqli = $this->getDb(); 59 if (!empty($infoArr['company'])) { 60 if (!$this->isExists($mysqli, $infoArr)) { 61 $num = $mysqli->query("INSERT INTO weiku(company,person,phone,fax,mobile,qq,msn,email,address,shopUrl) VALUES ('{$infoArr['company']}','{$infoArr['person']}','{$infoArr['phone']}','{$infoArr['fax']}','{$infoArr['mobile']}','{$infoArr['qq']}','{$infoArr['msn']}','{$infoArr['email']}','{$infoArr['address']}','{$infoArr['shopUrl']}')"); 62 return $num; 63 } else { 64 return false; # 表示数据已经存在 65 } 66 } else { 67 return false; 68 } 69 } 70 71 /** 72 * 连接数据库 73 */ 74 private function getDb() { 75 $mysqli = new mysqli('localhost', 'root', '1715544', 'weiku'); 76 $mysqli->query('SET NAMES GB2312'); 77 return $mysqli; 78 } 79 80 /** 81 * 检查公司是否已经存在 82 * @param Resource $mysqli 83 * @param ArrayObject $infoArr 84 * @return bool 85 */ 86 private function isExists($mysqli, $infoArr) { 87 $mysqli->query("SELECT company FROM weiku WHERE company = '{$infoArr['company']}'"); 88 if ($mysqli->affected_rows) { 89 return true; 90 } else { 91 return false; 92 } 93 } 94 95 /** 96 * 抓取信息 97 * @param $url 98 * @return ArrayObject 99 */ 100 private function getInfoByShopUrl($url) { 101 $re = $this->getUrlInfo($url); 102 preg_match_all('/<b>公司名称:<\/b><span>(.*)<\/span>/Usi', $re, $companyArr); 103 preg_match_all('/<b>联系人:<\/b><span>(.*)<\/span>/Usi', $re, $personArr); 104 preg_match_all('/<b>电话:<\/b><span>(.*)<\/span>/Usi', $re, $phoneArr); 105 preg_match_all('/<b>传真:<\/b><span>(.*)<\/span>/Usi', $re, $faxArr); 106 preg_match_all('/<b>手机:<\/b><span>(.*)<\/span>/Usi', $re, $mobileArr); 107 preg_match_all('/<b>QQ:<\/b><span>(.*)<\/span>/Usi', $re, $qqArr); 108 preg_match_all('/<b>MSN:<\/b><span>(.*)<\/span>/Usi', $re, $msnArr); 109 preg_match_all('/<b>E-Mail:<\/b><span>(.*)<\/span>/Usi', $re, $emailArr); 110 preg_match_all('/<b>公司地址:<\/b><span>(.*)<\/span>/Usi', $re, $addressArr); 111 $infoArr = array( 112 'company'=>$this->stripATags($companyArr[1][0]), 113 'person'=>trim($personArr[1][0]), 114 'phone'=>trim($phoneArr[1][0]), 115 'fax'=>trim($faxArr[1][0]), 116 'mobile'=>trim($mobileArr[1][0]), 117 'qq'=>$this->formatQqMsn($qqArr[1][0]), 118 'msn'=>$this->formatQqMsn($msnArr[1][0], 'MSN'), 119 'email'=>$this->stripATags($emailArr[1][0]), 120 'address'=>trim($addressArr[1][0]), 121 'shopUrl'=>$url 122 ); 123 return $infoArr; 124 } 125 126 /** 127 * 根据页面获取供应商 url 数组 128 * @param string $re 129 * @return ArrayObject 130 */ 131 private function shopUrlMatchReArr($re) { 132 $re = preg_replace('/<img.* [\/]>/', '', $re); 133 $re = preg_replace('/<img.*>/', '', $re); 134 $re = preg_replace('/<a href=\".+\" target=\"\_blank\">[A-Z]<\/a>/', '', $re); 135 $re = preg_replace('/<a href=\".+\" target=\"\_blank\">[0-9]<\/a>/', '', $re); 136 $re = preg_replace('/<a href=\".+\" target=\"\_blank\">.*<\/a>/', '', $re); 137 $re = preg_replace('/<a href="javascript.+">.*<\/a>/', '', $re); 138 $re = preg_replace('/<a href.+>营业执照<\/a>/', '', $re); 139 $re = preg_replace('/<a href.+>该企业更多资质>><\/a>/', '', $re); 140 $re = preg_replace('/<a href.+>点此反馈<\/a>/', '', $re); 141 $re = preg_replace('/<a href.+>首页<\/a>/', '', $re); 142 $re = preg_replace('/<a href.+>IC<\/a>/', '', $re); 143 $re = preg_replace('/<a href.+>简洁<\/a>/', '', $re); 144 $re = preg_replace('/<a href.+>信用<\/a>/', '', $re); 145 $re = preg_replace('/<a href.+>.*更多报价信息>><\/a>/', '', $re); 146 $re = preg_replace('/<a href=\".*\" target=\"\_blank\" rel=\"nofollow\">.*<\/a>/', '', $re); 147 $re = preg_replace('/<div class="kingbanan mb8">.*/', '', $re); 148 preg_match_all('/<a href=\"(.+)\".*>.+<\/a>/Usi', $re, $arr); 149 $arr = $this->formatUrlArr(array_unique($arr[1])); 150 return $arr; 151 } 152 153 /** 154 * 格式化数组 155 * @param Array $arr 156 * @return ArrayObject 157 */ 158 private function formatUrlArr($arr) { 159 $newArr = array(); 160 foreach ($arr as $key=>$value) { 161 if ($this->isExistsHttp($value)) { 162 $newArr[$key] = $value; 163 } 164 } 165 return $newArr; 166 } 167 168 /** 169 * 格式化 QQ 170 * @param string $str 171 * @return string 172 */ 173 private function formatQqMsn($str, $e='QQ') { 174 if (empty($str)) return ''; 175 preg_match_all('/alt="'.$e.'\:(.+)"/Usi', $str, $arr); 176 if (count($arr[1])==1) return $arr[1][0]; 177 $newStr = null; 178 foreach ($arr[1] as $value) { 179 $newStr .= $value . ' '; 180 } 181 return rtrim($newStr, ' '); 182 } 183 184 /** 185 * 供应商店铺链接添加 contact.html 186 * @param array $arr 187 * @return string 188 */ 189 private function shopAddContact($arr) { 190 foreach ($arr as $k=>$v) { 191 $arr[$k] = $v . '/contact.html'; 192 } 193 return $arr; 194 } 195 196 /** 197 * 去掉网址的 A 标签 198 * @param string $site 199 * @return string 200 */ 201 private function stripATags($site) { 202 $site = preg_replace('/<a.+>(.+)<\/a>/', '\1', $site); 203 return $site; 204 } 205 206 /** 207 * 检查 url 是否有 http 208 * @param string $url 209 * @return bool 210 */ 211 private function isExistsHttp($url) { 212 if (stristr($url, 'http://')) { 213 return true; 214 } else { 215 return false; 216 } 217 } 218 219 /** 220 * 获取页面内容 221 * @param Number $page 222 * @return string 223 */ 224 private function getContent($page=1) { 225 $re = file_get_contents($this->getUrl($this->key, $page)); 226 return $re; 227 } 228 229 /** 230 * 获取页码 231 * @return Number 232 */ 233 private function getPageNum() { 234 $i = 1; 235 while (true) { 236 $re = $this->getContent($i); 237 # 处理单页避免处理死循环 238 if (!strstr($re, '下一页')) { 239 break; 240 } else { 241 # 多页,计算出页码 242 if (stristr($re, '<span>下一页</span></li>')) break; 243 $i++; 244 } 245 } 246 return $i; 247 } 248 249 /** 250 * 获取 URL 链接 251 * @param string $str 252 * @param int $page 页码 253 * @return string 254 */ 255 private function getUrl($str, $page=1) { 256 return "http://www.dzsc.com/ic/sell_search.html?keyword={$str}&ic_sel=supplygoods&Submit=%26%23160%3B&page={$page}"; 257 } 258 259 /** 260 * 获取页面内容 261 * @param string $url 262 * @return string 263 */ 264 private function getUrlInfo($url) { 265 $re = file_get_contents($url); 266 return $re; 267 } 268 } 269 270 /* 271 程序运行思路:根据“华强电子网”的IC搜索功能,输入型号进行搜索,然后抓取供应商信息 272 273 数据库结构 274 CREATE TABLE `weiku` ( 275 `id` mediumint(8) unsigned NOT NULL auto_increment COMMENT 'ID', 276 `company` varchar(300) default NULL COMMENT '公司名称', 277 `person` varchar(200) default NULL COMMENT '联系人', 278 `phone` varchar(300) default NULL COMMENT '电话', 279 `fax` varchar(300) default NULL COMMENT '传真', 280 `mobile` varchar(300) default NULL COMMENT '手机', 281 `qq` varchar(200) default NULL COMMENT 'QQ', 282 `msn` varchar(200) default NULL COMMENT 'MSN', 283 `email` varchar(300) default NULL COMMENT '邮箱', 284 `address` varchar(500) default NULL COMMENT '公司地址', 285 `shopUrl` varchar(200) default NULL COMMENT '维库网店铺地址', 286 PRIMARY KEY (`id`) 287 ) ENGINE=InnoDB DEFAULT CHARSET=gb2312 288 */ 289 290 $k = new weiku(); 291 $arr = array_unique(array('MAX3232', 'AML8613', 'MT6225A', 'OM8373PS/N3/A', 'PT7313', 'MAX8212ESA', 'TL431', 'S3C2440', 'TMS320F2812PGFA', 'PCM1704', 'AN6717', 'CA3162E', 'CA3161E', 'LM393N', 'DS18B20', 'SHT10', 'AML8613', 'AN6717', 'LM393N', 'CA3161E', 'CA3162E', 'PCM1704', 'STK392-040', 'K1667', 'MAX232', 'STM32F103', 'LM358')); 292 foreach ($arr as $v) { 293 $k->go($v); 294 } 295 ?>