Dai Chong's blog

引言

 之前公司有需求要做一个采集信息的工具,包括获取商品信息导入数据库,比价什么的功能,没办法只能尝试这做一下。
 考虑到是做定向爬取,我就选择了jquery,因为jquery相比其他语言做爬虫是简单轻松很多。

不同语言自然会有不同用处。离开环境谈哪个好,哪个不好都是耍流氓。
1,如果是自己做着玩的话,定向爬几个页面,效率不是核心要求的话,问题不会大,什么语言都行的,性能差异不会大。当然,如果碰到十分复杂的页面,正则写的很复杂的话,爬虫的可维护性就会下降。

2,如果是做定向爬取,而目标又要解析动态js。
那么这个时候,用普通的请求页面,然后得到内容的方法肯定不行了,就要一个类似firfox,chrome的js引擎来对js代码做动态解析。这个时候推荐casperJS+phantomjs或slimerJS+phantomjs


3,如果是大规模的网站爬取。
这个时候就要考虑到,效率,扩展性,可维护性,等等了。
大规模的爬取涉及的方面很多,比如分布式爬取,判重机制,任务调度。这些问题深入下去哪一个简单了?
语言选取这个时候很重要。
NodeJs:做爬虫效率很高。高并发,多线程编程变成了简单的遍历和callback,内存cpu占用小,要处理好callback。

PHP:各种框架到处有,随便拉个来用都行。但是,PHP的效率真的有问题…不多说
Python:我用python写的比较多,对各种问题都有比较好的支持。scrapy框架很好用,优点多。
我觉得js也不是很适合写…效率问题。没写过,估计会有麻烦一堆。
据我知道的,大公司也有用c++的,总之大多数都是在开源框架上改造。真重新造个轮子的不多吧。
不值。

来自segmentfault一位大佬

jquery实现


抓取代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
javascript: (function() {
try {
var Arr = {
'name': getTitle(),
'img': getImgs(),
'price': getPirce(),
'sku': getSku(),
'desc': getDesc(),
};
//获取图片
function getImgs() {
var imgArr = [];
$("#dt-tab ul li").each(function(k, v) {
var imgJson = JSON.parse($(v).attr('data-imgs'));
if (imgJson) {
imgArr.push(imgJson.preview);
};
});
return imgArr;
};
//获取名称
function getTitle() {
var _this = $('#mod-detail-title .d-title');
return _this.html();
};
//获取价格
function getPirce() {
var _this = $("#mod-detail-price .price .ladder-3-1");
var priceJson = JSON.parse(_this.attr('data-range'));
return priceJson.price;
};
//获取sku属性
function getSku() {
var skuArr = [];
var _this = $(".obj-sku .table-sku tr");
if (_this) {
var step = 0;
_this.each(function(k, v) {
step++;
skuArr.push({
'sku_name': $(v).find('.name span').html(),
'price': $(v).find('.price span .value').html(),
'img': getSkuImg(step),
});
});
};
return skuArr;
};
//获取商品详情
function getDesc() {
var descArr = [];
var _this = $("#mod-detail-description img");
if (_this) {
_this.each(function(k, v) {
var url = $(v).attr('src');
var patt = new RegExp("[a-zA-z]+://[^\s]*");
if(patt.test(url)){
descArr.push(url);
}
});
};
return descArr;
};
//获取sku图片
function getSkuImg(step) {
if ($("#dt-tab ul li") && $(".obj-sku .table-sku tr")) {
return $("#dt-tab ul li:eq(" + step + ") .box-img img").attr('src');
};
return '';
};
if(confirm('获取成功,确认要采集吗?')==true){
console.log(Arr);
return false;
$.ajax({
type:"post",
url:'www.daichongweb.com',
data:{
post:Arr
},
dataType:'json',
success:function(res){
if(res.code==0){
alert('采集成功!');
}else{
alert(res.message);
}
},error:function(res){
alert('采集失败!');
},beforeSend:function(res){
$('body').append('<div id="daichongweb" style="position:fixed;top:0;left:0;background: rgba(0, 0, 0, .5);text-align: center;line-height: 20;font-size: 30px;color: white;width:100vw;height:100vh;z-index:1000000000;">采集中!</div>');
},complete:function(res){
$("#daichongweb").remove();
}
});
}
} catch (err) {
alert(err);
};
})();

定向商品链接->1688.com 当然了,这个采集代码不只是针对这一个商品,它可以抓取和他页面结构一样的所有商品。

PS:这里的抓取可根据自己的实际业务来改变,比如需要让页面中的轮播图切换这个才能获取,那就在抓取之前写个切换的脚本;切换一张抓取一张;

怎么才能在谷歌中运行这个脚本


 方法一:直接放在控制台(这里并不推荐使用,因为公司的人不可能都懂代码,而且操作麻烦)。
 方法二:在浏览器中添加书签,把代码复制到网址栏里,要采集的时候点击一下就ok了!

PS:整体运用情况看,个人觉得jquery做采集还是挺不错的。当然相比php、python的话显得有点低端的感觉,那也没办法谁让php、python是动态获取的呢?
之后会用php或python做个一个动态抓取的脚本,当然也包括比价之类的运用…..

后端处理数据(可忽略)


php处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
<?php
require_once './oss/autoload.php';
use OSS\OssClient;
use OSS\Core\OssException;

header('Content-Type: text/html;charset=utf-8');
header('Access-Control-Allow-Origin:*'); // *代表允许任何网址请求
header('Access-Control-Allow-Methods:POST,GET,OPTIONS,DELETE'); // 允许请求的类型
header('Access-Control-Allow-Credentials: true'); // 设置是否允许发送 cookies
header('Access-Control-Allow-Headers: Content-Type,Content-Length,Accept-Encoding,X-Requested-with, Origin');

if($_POST){

$post = $_POST['post'];
if($post){

//处理大图
$imgArr = $post['img'];
if($imgArr){
foreach ($imgArr as $k => $v) {
$name = saveImgToLocal($v);
$ossPath = 'collect/'.date('Ym').'/'.$name;
uploadImgOss($ossPath,'./img/'.$name);
$imgArr[$k] = $ossPath;
}
$post['img'] = $imgArr;
}
if(array_key_exists('sku', $post)){
//处理小图
$sku = $post['sku'];
if($sku){
foreach ($sku as $k => $v) {
$name = saveImgToLocal($v['img']);
$ossPath = 'collect/'.date('Ym').'/'.$name;
uploadImgOss($ossPath,'./img/'.$name);
$sku[$k]['img'] = $ossPath;
}
$post['sku'] = $sku;
}
}
if(array_key_exists('desc', $post)){
//处理详情图
$desc = $post['desc'];
if($desc){
foreach ($desc as $k => $v) {
$name = saveImgToLocal($v);
$ossPath = 'collect/'.date('Ym').'/'.$name;
uploadImgOss($ossPath,'./img/'.$name);
$desc[$k] = $ossPath;
}
$post['desc'] = $desc;
}
}
}
//连接数据库
$Db = mysqli_connect("127.0.0.1","root","daichongweb","shop");
if (mysqli_connect_errno($Db))
{
echo "连接 MySQL 失败: " . mysqli_connect_error();
}
insertDb($Db,$post);

}

//保存图片到本地
function saveImgToLocal($telefile,$path='./img/'){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $telefile);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
$file = curl_exec($ch);
curl_close($ch);

$filename = pathinfo($telefile, PATHINFO_BASENAME);
$resource = fopen($path . $filename, 'a');
fwrite($resource, $file);
fclose($resource);
return $filename;
}
//上传图片的oss
function uploadImgOss($object,$filePath){

$accessKeyId = "阿里ossKeyID";
$accessKeySecret = 阿里ossKeySecret;
$endpoint = "项目地址";
$bucket = "项目名称";

try{
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
$ossClient->uploadFile($bucket, $object, $filePath);
} catch(OssException $e) {
print_r($e->getMessage());
exit;
}
}
/**
* 获得随机字符串
* @param $len 需要的长度
* @param $special 是否需要特殊符号
* @return string 返回随机字符串
*/
function getRandomStr($len, $special = false){
$chars = array(
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
"3", "4", "5", "6", "7", "8", "9"
);
if($special){
$chars = array_merge($chars, array(
"!", "@", "#", "$", "?", "|", "{", "/", ":", ";",
"%", "^", "&", "*", "(", ")", "-", "_", "[", "]",
"}", "<", ">", "~", "+", "=", ",", "."
));
}

$charsLen = count($chars) - 1;
shuffle($chars); //打乱数组顺序
$str = '';
for($i=0; $i<$len; $i++){
$str .= $chars[mt_rand(0, $charsLen)]; //随机取出一位
}
return $str;
}

//把数据插入数据库
function insertDb($Db,$data){
//商品主表
$pd_product_field = [
'product_art_no' => '',
'product_number' => getRandomStr(32),
'pd_name' => $data['name'],
'pd_subtitle' =>'',
'pd_descs' => '',
'pd_category_id' => 0,
'pd_seller_id' => 0,
'pd_brand_id' => 0,
'express_tpl_id' => 0,
'meun_id' => 0,
'pd_unit' => '',
'pd_weight' => 0,
'pd_weight_unit' => '',
'pd_volume' => 0,
'pd_volume_unit' => '',
'min_price' => 0,
'market_price' => 0,
'cost_price'=> 0,
'detail_descr' => '',
'pd_key_word' => '',
'pd_remark' => '',
'pd_picture_prefix' => '',
'pd_detail_info' => '',
'detail_title' => '',
'created_at' => date('Y-m-d H:i:s'),
];

$pd_detail_info = '';

foreach ($data['desc'] as $k => $v) {
$pd_detail_info .= '<img src="'.$v.'">';
}

$pd_product_field['pd_detail_info'] = addslashes(bin2hex(gzcompress($pd_detail_info)));
$pd_product_field['pd_image_url'] = implode(',',$data['img']);
$pd_product_field['pd_translation_pic'] = implode(',',$data['img']);
$pd_product_keys = '';
$pd_product_values = '';

foreach ($pd_product_field as $key => $value) {
$pd_product_keys .= $key.',';
$pd_product_values .= "'".$value."'".',';
}

$pd_product_keys = trim($pd_product_keys,',');
$pd_product_values = trim($pd_product_values,',');
$inser_pd_product = "insert into pd_product($pd_product_keys) value($pd_product_values)";

mysqli_autocommit($Db,false);//开启事务
try {
$product_number = $pd_product_field['product_number'];
$pd_product_reslut = mysqli_query($Db,$inser_pd_product);
$product_id = mysqli_insert_id($Db);
$pd_sku_result = 0;
$pd_sku_properties_reslut = 0;
$sku_unique_code = getRandomStr(32);
if(array_key_exists('sku',$data) && count($data['sku'])>0){

foreach ($data['sku'] as $key => $value) {

$property = $value['sku_name'];
$pd_price = $value['price'];
$sku_picture_url = $value['img'];

$insert_pd_sku = "insert into pd_sku(sku_unique_code,product_number,property,sku_code,product_id) value('$sku_unique_code','$product_number','$property','',$product_id)";
$pd_sku_result = mysqli_query($Db,$insert_pd_sku);
$sku_id = mysqli_insert_id($Db);

$insert_pd_sku_properties = "insert into pd_sku_properties(sku_id,sku_unique_code,product_id,product_number,sku_value,pd_price,sku_picture_url,sku_code) value($sku_id,'',$product_id,'$product_number','$property','$pd_price','$sku_picture_url','')";
$pd_sku_properties_reslut = mysqli_query($Db,$insert_pd_sku_properties);
}
}else{
$pd_sku_result = 1;
$pd_sku_properties_reslut = 1;
}

if($pd_product_reslut && $pd_sku_result && $pd_sku_properties_reslut){
mysqli_commit($Db);//提交事务
$code = 0;
$message = '插入成功';
}else{
mysqli_rollback($Db);//回滚
$code = 1;
$message = '插入失败';
}

} catch (\Exception $e) {
mysqli_rollback($Db);//回滚
$code = 1;
$message = $e->getMessage();
}

//删除本地下载的图片
foreach ($data['img'] as $key => $value) {
$arr = explode('/',$value);
unlink('./img/'.array_pop($arr));
}
if(array_key_exists('desc', $data)){
foreach ($data['desc'] as $key => $value) {
$arr = explode('/',$value);
unlink('./img/'.array_pop($arr));
}
}
if(array_key_exists('sku', $data)){
foreach ($data['sku'] as $key => $value) {
$arr = explode('/',$value['img']);
unlink('./img/'.array_pop($arr));
}
}
echo json_encode([
'code' => $code,
'message' => $message
]);
}


 评论