前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >唯品会专场监控系统

唯品会专场监控系统

作者头像
机器学习和大数据挖掘
发布2019-07-02 10:29:46
7940
发布2019-07-02 10:29:46
举报
文章被收录于专栏:数据挖掘数据挖掘

唯品会的对于数据的封锁是很严重的,例如某个界面:

一片空白!!!

身为一个数据分析师,没有数据更谈不上分析了,所以数据挖掘下还是有的:

果断F12,突然发现了一个页面:

1 http://stock.vip.com/list/?callback=te_list&brandId=813542

最后面的813542是这个店铺的ID,前边都是一样的

打开页面:

 很醒目的:sold_out

 数据是要自己找的,所以就可以发挥一下自己的小特长来搞个数据监控,顺便为自己的数据分析提供点帮助

这样子就可以做一个售罄的监控系统,监控别家店铺的售罄情况,最后得到的效果图如下:

代码语言:javascript
复制
你们在我眼里是没有秘密的!

代码解析:

确定专场ID、监控的时间间隔、监控的次数:

代码语言:javascript
复制
 1         info_data_id = input('请输入需要监控专场的ID:')
 2 
 3         ##设置间隔时长
 4         try:
 5             info_time_interval = int(input('请输入监控时间间隔分钟(min)(默认3分钟):'))
 6             if info_time_interval < 0:
 7                 print('间隔太短')
 8                 info_time_interval = 3 * 60
 9             else:
10                 info_time_interval = info_time_interval * 60
11         except:
12             info_time_interval = 3 * 60
13 
14         ##设置监控次数
15         try:
16             info_time_frequency = int(input('请输入监控次数(默认2次):'))
17             if info_time_frequency > 50:
18                 print('不要监控那么久,不能超过50次')
19                 info_time_frequency = 2
20         except:
21             info_time_frequency = 2

由于

代码语言:javascript
复制
time.sleep(second)

所以要乘以60变成分钟

给定频率最开始的代码是

代码语言:javascript
复制
frequency = 0
while frequency < info_time_frequency:
    time.sleep(info_time_interval)
    frequency = frequency + 1

在睡眠里面加入代码:

代码语言:javascript
复制
 1             url = 'http://stock.vip.com/list/?callback=te_list&brandId=' + info_data_id
 2             info_data = (get_all(getHtml(url).decode('UTF-8', 'ignore')))  # ('UTF-8')('unicode_escape')('gbk','ignore')
 3 
 4             ##下面是判断
 5             if frequency == 0:
 6                 info_data_new = info_data[0][1].split(',')
 7                 print('######导入售罄情况开始监控######')
 8             elif len(info_data_new) == len(info_data[0][1].split(',')):
 9                 print('######售罄情况没什么变化######')
10             elif len(info_data_new) > len(info_data[0][1].split(',')):
11                 for j in range(0, len(info_data_new)):
12                     info_data_name = []
13                     info_html_jpg = []
14                     if info_data_new[j] in info_data[0][1].split(','):
15                         pass
16                     else:
17                         print('该商品异常,估计被下了订单或者被取消付款:' + info_data_new[j])
18 
19                         ##图片名字,包括专场名称、商品名称
20                         namepath = get_data(getHtml(
21                             'http://www.vip.com/detail-' + info_data_id + '-' + info_data_new[j] + '.html').decode(
22                             'UTF-8', 'ignore'))
23                         rstr = '[’!"#$///%&\'*+,./:;<=>?@[\\]\\\^_`//{|}~]+'
24                         info_data_name = re.sub(rstr, "", namepath[0][1])
25                         name = time.strftime('%Y%m%d%H%S', time.localtime())  # 当时时间
26 
27                         ##得到图片网址
28                         jpgpath = get_jpg(getHtml(
29                             'http://www.vip.com/detail-' + info_data_id + '-' + info_data_new[j] + '.html').decode(
30                             'UTF-8', 'ignore'))
31 
32                         # 图片放大
33                         try:
34                             info_html_jpg = jpgpath[0][1].replace('95x120', '720x720')
35                         except:
36                             info_html_jpg = jpgpath[0][1]
37 
38                         pic = urllib.request.urlopen(info_html_jpg)  # 解析图片网址
39 
40                         ##下面是保存图片
41                         file = 'C:\\Users\\Administrator\\Desktop\\monitor\\' + time.strftime('%Y%m%d',
42                                                                                               time.localtime()) + '-' + info_data_id + '\\'
43                         filess = open(file + name + info_data_name + info_data_new[j] + '异常.jpg', 'wb')
44                         filess.write(pic.read())
45                         filess.close()
46 
47                 info_data_new = info_data[0][1].split(',')  ##更新数组
48                 continue

分段解释:

代码语言:javascript
复制
getHtml#解析头,爬虫的都知道

正则表达式得到商品的ID,附上:

代码语言:javascript
复制
 1 ##解析网址的正则表达式,将售罄的product_id搞出来
 2 def get_all(html_all):
 3     reg = r'(sold_out":")(.+?)(","sold_chance)'
 4     all = re.compile(reg);
 5     alllist = re.findall(all, html_all)
 6     return alllist

得到店铺ID,那么我要用商品的的名称来,再去看商品的product_id解析情况:

 那么正则写为:

代码语言:javascript
复制
1 def get_data(html_all):
2     reg = r'(keywords" content=")(.+?)(" />)'
3     all = re.compile(reg);
4     alllist = re.findall(all, html_all)
5     return alllist

图片的网址也要,要下载图片来看看什么东西那么好卖:

 那么正则写为:

代码语言:javascript
复制
1 def get_jpg(html_all):
2     reg = r'(<img src=")(.+?)(" width=)'
3     all = re.compile(reg);
4     alllist = re.findall(all, html_all)
5     return alllist

将得到的product_id按照“,”号来分开存入一个新数组里面,这个心的数组用来作为下次循环的判断依据,即下一次循环得到的数组和这个新数组进行比较:

代码语言:javascript
复制
info_data_new = info_data[0][1].split(',')

如果两个数组长度一样就不判断了

因为解析得到的是售罄的情况

假如售罄的商品不增加还变少了,那么就可以判断是别人下单后取消订单了

因为这里下单后会假如没有库存了就会被判断为售罄

但是别人取消订单,那么售罄状态解除

如果是正常的变多,那就遍历一次就行了,找到没有的

再把判断数组更新就行

代码语言:javascript
复制
info_data_new = info_data[0][1].split(',')

这一段的代码如下:

代码语言:javascript
复制
 1                 if frequency == 0:
 2                 info_data_new = info_data[0][1].split(',')
 3                 print('######导入售罄情况开始监控######')
 4             elif len(info_data_new) == len(info_data[0][1].split(',')):
 5                 print('######售罄情况没什么变化######')
 6             elif len(info_data_new) > len(info_data[0][1].split(',')):
 7                 for j in range(0, len(info_data_new)):
 8                     info_data_name = []
 9                     info_html_jpg = []
10                     if info_data_new[j] in info_data[0][1].split(','):
11                         pass
12                     else:
13                         print('该商品异常,估计被下了订单或者被取消付款:' + info_data_new[j])

 解析也能得到图片的网址,那么就要把图片保存下来:

代码语言:javascript
复制
 1                         ##图片名字,包括专场名称、商品名称
 2                         namepath = get_data(getHtml(
 3                             'http://www.vip.com/detail-' + info_data_id + '-' + info_data_new[j] + '.html').decode(
 4                             'UTF-8', 'ignore'))
 5                         rstr = '[’!"#$///%&\'*+,./:;<=>?@[\\]\\\^_`//{|}~]+'
 6                         info_data_name = re.sub(rstr, "", namepath[0][1])
 7                         name = time.strftime('%Y%m%d%H%S', time.localtime())  # 当时时间
 8 
 9                         ##得到图片网址
10                         jpgpath = get_jpg(getHtml(
11                             'http://www.vip.com/detail-' + info_data_id + '-' + info_data_new[j] + '.html').decode(
12                             'UTF-8', 'ignore'))
13 
14                         # 图片放大
15                         try:
16                             info_html_jpg = jpgpath[0][1].replace('95x120', '720x720')
17                         except:
18                             info_html_jpg = jpgpath[0][1]
19 
20                         pic = urllib.request.urlopen(info_html_jpg)  # 解析图片网址
21 
22                         ##下面是保存图片
23                         file = 'C:\\Users\\Administrator\\Desktop\\monitor\\' + time.strftime('%Y%m%d',
24                                                                                               time.localtime()) + '-' + info_data_id + '\\'
25                         filess = open(file + name + info_data_name + info_data_new[j] + '异常.jpg', 'wb')
26                         filess.write(pic.read())
27                         filess.close()

图片的名字为:当时下载的时间+图片本来的名称+product_id

上面代码没什么特别,无非就是

去掉名字里面的不合字符

把图片变大一点

存入生成的文件夹里面,搞定

上面是异常售罄的情况

后面要写正常售罄的代码

代码语言:javascript
复制
 1             else:
 2                 info_data_linshi = []
 3                 info_data_linshi = info_data[0][1].split(',')
 4                 for i in range(0, len(info_data[0][1].split(','))):
 5                     info_data_name = []
 6                     info_html_jpg = []
 7                     if info_data_linshi[i] in info_data_new:
 8                         pass
 9                     else:
10                         print('新增售罄商品:' + info_data_linshi[i])
11                         ##图片名字,包括专场名称、商品名称
12                         namepath = get_data(getHtml(
13                             'http://www.vip.com/detail-' + info_data_id + '-' + info_data_linshi[i] + '.html').decode(
14                             'UTF-8', 'ignore'))
15                         rstr = '[’!"#$///%&\'*+,./:;<=>?@[\\]\\\^_`//{|}~]+'
16                         info_data_name = re.sub(rstr, "", namepath[0][1])
17                         name = time.strftime('%Y%m%d%H%S', time.localtime())  # 当时时间
18 
19                         ##得到图片网址
20                         jpgpath = get_jpg(getHtml(
21                             'http://www.vip.com/detail-' + info_data_id + '-' + info_data_linshi[i] + '.html').decode(
22                             'UTF-8', 'ignore'))
23 
24                         # 图片放大
25                         try:
26                             info_html_jpg = jpgpath[0][1].replace('95x120', '720x720')
27                         except:
28                             info_html_jpg = jpgpath[0][1]
29 
30                         pic = urllib.request.urlopen(info_html_jpg)  # 解析图片网址
31 
32                         ##下面是保存图片
33                         file = 'C:\\Users\\Administrator\\Desktop\\monitor\\' + time.strftime('%Y%m%d',
34                                                                                               time.localtime()) + '-' + info_data_id + '\\'
35                         filess = open(file + name + info_data_name + info_data_linshi[i] + '.jpg', 'wb')
36                         filess.write(pic.read())
37                         filess.close()
38 
39                         info_data_new.append(info_data_linshi[i])  ##更新数组    

其实和上面是一样的,这样就算搞定了,附上全部代码:

代码语言:javascript
复制
  1 #print('python 的空白页,用来打开PyCharm')
  2 # -*- coding:utf-8 -*-
  3 import re
  4 import urllib.request, urllib.parse, http.cookiejar
  5 import os, time, re
  6 import http.cookies
  7 import time
  8 import xlsxwriter
  9 import datetime
 10 
 11 
 12 ############################################################这里是解析网址的东西###################################################################
 13 ##    说明
 14 ##     安装包
 15 ##  pip3 install bs4
 16 ##  pip3 install -U selenium
 17 ## 抓取不会变的网址用getHtml,否则getFirefox()
 18 
 19 ## 这个函数可以用Post,Get等方式获取网页内容
 20 ## 例子一:
 21 ## 如果网站有使用cookie登录的话可以加载cookie,或者如果网站反爬虫可以加头部
 22 ## 例子二:
 23 ## 被封了Ip,你就无法抓取了,此时你可以设置代理ip,下面那个‘’表示不使用代理,代理可以去网上找,很多
 24 ## 例子三:
 25 ## 有些抓取需要发送一些数据过去,才能获取到内容,此时下面的{}表示数据
 26 
 27 ## 一般使用就是 url=”xxxxxxx“ getHtml(url)   其他不用管
 28 ## 得到原始网页
 29 def getHtml(url, daili='', postdata={}):
 30     """
 31     抓取网页:支持cookie
 32     第一个参数为网址,第二个为POST的数据(这句话看得懂吧)
 33     """
 34     # COOKIE文件保存路径
 35     filename = 'cookie.txt'
 36 
 37     # 声明一个MozillaCookieJar对象实例保存在文件中
 38     cj = http.cookiejar.MozillaCookieJar(filename)
 39     # cj =http.cookiejar.LWPCookieJar(filename)
 40 
 41     # 从文件中读取cookie内容到变量
 42     # ignore_discard的意思是即使cookies将被丢弃也将它保存下来
 43     # ignore_expires的意思是如果在该文件中 cookies已经存在,则覆盖原文件写
 44     # 如果存在,则读取主要COOKIE
 45     if os.path.exists(filename):
 46         cj.load(filename, ignore_discard=True, ignore_expires=True)
 47     # 建造带有COOKIE处理器的打开专家
 48     proxy_support = urllib.request.ProxyHandler({'http': 'http://' + daili})
 49     # 开启代理支持
 50     if daili:
 51         print('代理:' + daili + '启动')
 52         opener = urllib.request.build_opener(proxy_support, urllib.request.HTTPCookieProcessor(cj),
 53                                              urllib.request.HTTPHandler)
 54     else:
 55         opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
 56 
 57     # 打开专家加头部----与post的数据格式一样,下面是头部,表示我用ipad浏览器!
 58     opener.addheaders = [('User-Agent',
 59                           'Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5'),
 60                          ]
 61 
 62     # 分配专家
 63     urllib.request.install_opener(opener)
 64     # 有数据需要POST
 65     if postdata:
 66         # 数据URL编码
 67         postdata = urllib.parse.urlencode(postdata)
 68 
 69         # 抓取网页
 70         html_bytes = urllib.request.urlopen(url, postdata.encode(), timeout=30).read()
 71     else:
 72         html_bytes = urllib.request.urlopen(url, timeout=30).read()
 73 
 74     # 保存COOKIE到文件中
 75     cj.save(ignore_discard=True, ignore_expires=True)
 76     return html_bytes
 77 
 78 
 79 ############################################################这里是函数,也是正则表达式###################################################################
 80 ##解析网址的正则表达式,将售罄的product_id搞出来
 81 def get_all(html_all):
 82     reg = r'(sold_out":")(.+?)(","sold_chance)'
 83     all = re.compile(reg);
 84     alllist = re.findall(all, html_all)
 85     return alllist
 86 
 87 
 88 ##解析网址的正则表达式,将变动商品的专场以及名称搞出来
 89 def get_data(html_all):
 90     reg = r'(keywords" content=")(.+?)(" />)'
 91     all = re.compile(reg);
 92     alllist = re.findall(all, html_all)
 93     return alllist
 94 
 95 
 96 def get_jpg(html_all):
 97     reg = r'(<img src=")(.+?)(" width=)'
 98     all = re.compile(reg);
 99     alllist = re.findall(all, html_all)
100     return alllist
101 
102 
103 ###########################################################这里是杂七杂八的东西###################################################################
104 def timetochina(longtime, formats='{}天{}小时{}分钟{}秒'):
105     day = 0
106     hour = 0
107     minutue = 0
108     second = 0
109     try:
110         if longtime > 60:
111             second = longtime % 60
112             minutue = longtime // 60
113         else:
114             second = longtime
115         if minutue > 60:
116             hour = minutue // 60
117             minutue = minutue % 60
118         if hour > 24:
119             day = hour // 24
120             hour = hour % 24
121         return formats.format(day, hour, minutue, second)
122     except:
123         raise Exception('时间非法')
124 
125 ############################################################这里是主函数###################################################################
126 if __name__ == '__main__':
127 
128     a = time.clock()  # 程序测速,后面会有个b = time.clock(),那么b-a就是时间
129 
130     info_data_id = input('请输入需要监控专场的ID:')
131 
132     ##设置间隔时长
133     try:
134         info_time_interval = int(input('请输入监控时间间隔分钟(min)(默认3分钟):'))
135         if info_time_interval < 0:
136             print('间隔太短')
137             info_time_interval = 3 * 60
138         else:
139             info_time_interval = info_time_interval * 60
140     except:
141         info_time_interval = 3 * 60
142 
143     ##设置监控次数
144     try:
145         info_time_frequency = int(input('请输入监控次数(默认2次):'))
146         if info_time_frequency > 50:
147             print('不要监控那么久,不能超过50次')
148             info_time_frequency = 2
149     except:
150         info_time_frequency = 2
151 
152     frequency = 0
153     info_data_new = []
154 
155     if os.path.exists(r'C:\\Users\\Administrator\\Desktop\\monitor'):  # 建立一个文件夹在桌面,文件夹为monitor
156         print('monitor文件夹已经在桌面存在,继续运行程序……')
157     else:
158         print('monitor文件夹不在桌面,新建文件夹monitor')
159         os.mkdir(r'C:\\Users\\Administrator\\Desktop\\monitor')
160         print('文件夹建立成功,继续运行程序')
161 
162     if os.path.exists(r'C:\\Users\\Administrator\\Desktop\\monitor\\' + time.strftime('%Y%m%d',
163                                                                                       time.localtime()) + '-' + info_data_id):
164         print(time.strftime('%Y%m%d', time.localtime()) + '-' + info_data_id + '文件夹已经在桌面存在,继续运行程序……')
165     else:
166         print(time.strftime('%Y%m%d', time.localtime()) + '-' + info_data_id + '文件夹不在桌面,新建文件夹' + time.strftime(
167             '%Y%m%d', time.localtime()) + '-' + info_data_id)
168         os.mkdir(r'C:\\Users\\Administrator\\Desktop\\monitor\\' + time.strftime('%Y%m%d',
169                                                                                  time.localtime()) + '-' + info_data_id)
170         print('文件夹建立成功,继续运行程序')
171 
172     while frequency < info_time_frequency:
173         url = 'http://stock.vip.com/list/?callback=te_list&brandId=' + info_data_id
174         info_data = (get_all(getHtml(url).decode('UTF-8', 'ignore')))  # ('UTF-8')('unicode_escape')('gbk','ignore')
175 
176         ##下面是判断
177         if frequency == 0:
178             info_data_new = info_data[0][1].split(',')
179             print('######导入售罄情况开始监控######')
180         elif len(info_data_new) == len(info_data[0][1].split(',')):
181             print('######售罄情况没什么变化######')
182         elif len(info_data_new) > len(info_data[0][1].split(',')):
183             for j in range(0, len(info_data_new)):
184                 info_data_name = []
185                 info_html_jpg = []
186                 if info_data_new[j] in info_data[0][1].split(','):
187                     pass
188                 else:
189                     print('该商品异常,估计被下了订单或者被取消付款:' + info_data_new[j])
190 
191                     ##图片名字,包括专场名称、商品名称
192                     namepath = get_data(getHtml(
193                         'http://www.vip.com/detail-' + info_data_id + '-' + info_data_new[j] + '.html').decode(
194                         'UTF-8', 'ignore'))
195                     rstr = '[’!"#$///%&\'*+,./:;<=>?@[\\]\\\^_`//{|}~]+'
196                     info_data_name = re.sub(rstr, "", namepath[0][1])
197                     name = time.strftime('%Y%m%d%H%S', time.localtime())  # 当时时间
198 
199                     ##得到图片网址
200                     jpgpath = get_jpg(getHtml(
201                         'http://www.vip.com/detail-' + info_data_id + '-' + info_data_new[j] + '.html').decode(
202                         'UTF-8', 'ignore'))
203 
204                     # 图片放大
205                     try:
206                         info_html_jpg = jpgpath[0][1].replace('95x120', '720x720')
207                     except:
208                         info_html_jpg = jpgpath[0][1]
209 
210                     pic = urllib.request.urlopen(info_html_jpg)  # 解析图片网址
211 
212                     ##下面是保存图片
213                     file = 'C:\\Users\\Administrator\\Desktop\\monitor\\' + time.strftime('%Y%m%d',
214                                                                                           time.localtime()) + '-' + info_data_id + '\\'
215                     filess = open(file + name + info_data_name + info_data_new[j] + '异常.jpg', 'wb')
216                     filess.write(pic.read())
217                     filess.close()
218 
219             info_data_new = info_data[0][1].split(',')  ##更新数组
220             continue
221 
222 
223         else:
224             info_data_linshi = []
225             info_data_linshi = info_data[0][1].split(',')
226             for i in range(0, len(info_data[0][1].split(','))):
227                 info_data_name = []
228                 info_html_jpg = []
229                 if info_data_linshi[i] in info_data_new:
230                     pass
231                 else:
232                     print('新增售罄商品:' + info_data_linshi[i])
233                     ##图片名字,包括专场名称、商品名称
234                     namepath = get_data(getHtml(
235                         'http://www.vip.com/detail-' + info_data_id + '-' + info_data_linshi[i] + '.html').decode(
236                         'UTF-8', 'ignore'))
237                     rstr = '[’!"#$///%&\'*+,./:;<=>?@[\\]\\\^_`//{|}~]+'
238                     info_data_name = re.sub(rstr, "", namepath[0][1])
239                     name = time.strftime('%Y%m%d%H%S', time.localtime())  # 当时时间
240 
241                     ##得到图片网址
242                     jpgpath = get_jpg(getHtml(
243                         'http://www.vip.com/detail-' + info_data_id + '-' + info_data_linshi[i] + '.html').decode(
244                         'UTF-8', 'ignore'))
245 
246                     # 图片放大
247                     try:
248                         info_html_jpg = jpgpath[0][1].replace('95x120', '720x720')
249                     except:
250                         info_html_jpg = jpgpath[0][1]
251 
252                     pic = urllib.request.urlopen(info_html_jpg)  # 解析图片网址
253 
254                     ##下面是保存图片
255                     file = 'C:\\Users\\Administrator\\Desktop\\monitor\\' + time.strftime('%Y%m%d',
256                                                                                           time.localtime()) + '-' + info_data_id + '\\'
257                     filess = open(file + name + info_data_name + info_data_linshi[i] + '.jpg', 'wb')
258                     filess.write(pic.read())
259                     filess.close()
260 
261                     info_data_new.append(info_data_linshi[i])  ##更新数组
262 
263         # print(len(info_data_new))
264         print('暂停' + str(info_time_interval / 60) + '分钟')
265         print('\n')
266         print('请等待...')
267 
268         time.sleep(info_time_interval)
269         frequency = frequency + 1
270 
271     b = time.clock()
272     print('运行时间:' + timetochina(b - a))
273     input('请关闭窗口')  ##防止运行完毕后窗口直接关闭而看不到运行时间
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-07-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档