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