抓取“维库电子市场”供应商程序

  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 ?>

posted @ 2012-08-19 21:37  小2010  阅读(315)  评论(0编辑  收藏  举报