专栏首页数据挖掘唯品会专场监控系统

唯品会专场监控系统

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

一片空白!!!

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

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

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

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

打开页面:

 很醒目的:sold_out

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

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

你们在我眼里是没有秘密的!

代码解析:

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

 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

由于

time.sleep(second)

所以要乘以60变成分钟

给定频率最开始的代码是

frequency = 0
while frequency < info_time_frequency:
    time.sleep(info_time_interval)
    frequency = frequency + 1

在睡眠里面加入代码:

 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

分段解释:

getHtml#解析头,爬虫的都知道

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

 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解析情况:

 那么正则写为:

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

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

 那么正则写为:

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

info_data_new = info_data[0][1].split(',')

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

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

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

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

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

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

再把判断数组更新就行

info_data_new = info_data[0][1].split(',')

这一段的代码如下:

 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])

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

 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

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

去掉名字里面的不合字符

把图片变大一点

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

上面是异常售罄的情况

后面要写正常售罄的代码

 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])  ##更新数组    

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

  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('请关闭窗口')  ##防止运行完毕后窗口直接关闭而看不到运行时间

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一次、二次、三次指数平滑计算思想及代码

    一般常用到的指数平滑法为一次指数平滑、二次指数平滑和三次指数平滑,高次指数平滑一般比较难见到,因此本文着重介绍了一次、二次和三次指数平滑的特点与不同。

    机器学习和大数据挖掘
  • python批量制作雷达图

    老板要画雷达图,但是数据好多组怎么办?不能一个一个点excel去画吧,那么可以利用python进行批量制作,得到样式如下:

    机器学习和大数据挖掘
  • 基于马尔科夫链的产品评估预测

      马尔可夫链是一种时间离散、状态离散、带有记忆功能情况的随机过程,是预测中常用到的一种数学模型。如果数据的本身的每一时刻的状态仅仅取决于紧接在他前面的随机变量...

    机器学习和大数据挖掘
  • 详解微信小程序如何实现流程进度功能

    最近正在做微信小程序,需要实现一个流程进度的图样式如下面

    疯狂的小程序
  • 如何最骚气得在linux下聊qq(mojoqq)

    有一天老板让我安装qq,说电脑上没有qq影响工作效率,但是作为 一个热爱linux的人怎么愿意去在linux上安装wine这个挨千刀的东西呢。不过解决办法还是有...

    bboysoul
  • 【福利】TAPD 5.0 蓄势待发,首批体验官限量招募中……

    不知不觉,TAPD已经陪伴大家走过一年半时间啦~ 在这段时间,非常感谢大家给我们提了很多宝贵的建议,我们也都一一记在了小本本上,并且默默憋了个大招——  TA...

    TAPD敏捷研发
  • mysql数据类型

    mysql数据的数据类型,指定了字段的类型,不符合指定的字段类型,传入的值则会提示错误;

    十月梦想
  • 一次"艰难"的XSS Bypass之旅

    这绝对是我玩过的最乏味的一次XSS。 我使用Burp进行枚举,用高级选项来控制测试范围。

    周俊辉
  • R语言画地图的文章记录2

    第一部分的数据集 PopulationDensity.csv 大家如果需要直接给我留言 Popu 即可

    用户7010445
  • 为了追到小姐姐,我用 Python 制作了一个机器人

    最近发现有一个微信好友,我的每一条朋友圈动态,无论什么时候发布,发布的什么内容,点赞列表总有它的身影。

    AirPython

扫码关注云+社区

领取腾讯云代金券