起因:最近兴起一个 App 叫好近,专做 SOHO 附近小食,每日推出 1 分钱抢购或一些特价下午茶之类的活动,很难抢,不是错过就是被秒抢,遂想出个办法来提高抢购率!
最直接的需求是相对即时通知,让你快人一步。此类工具用 Python 来实现再合适不过了
提醒方式
工作期间不能老盯着手机,考虑通过 OSX 的 Notification 实现,让它带着音乐蹦出来~
调用 OSX 接口需要依赖 PyObjC 模块,通过 pip 装之(时间比较长,装一堆 OC 相关的包):
pip install PyObjC
调用的代码示例(python2.7+适用):
import objc
import Foundation
//py2.5可以通过 from Foundation import NSUserNotification 方式引入
NSUserNotification = objc.lookUpClass('NSUserNotification')
NSUserNotificationCenter = objc.lookUpClass('NSUserNotificationCenter')
def notify(title, subtitle, info_text, delay=0, sound=False, userInfo={}):
notification = NSUserNotification.alloc().init()
notification.setTitle_(title)
notification.setSubtitle_(subtitle)
notification.setInformativeText_(info_text)
notification.setUserInfo_(userInfo)
if sound:
notification.setSoundName_("NSUserNotificationDefaultSoundName")
notification.setDeliveryDate_(Foundation.NSDate.dateWithTimeInterval_sinceDate_(delay, Foundation.NSDate.date()))
NSUserNotificationCenter.defaultUserNotificationCenter().scheduleNotification_(notification)
截获相关 Api
利用 Charles 可以很方便的抓取,经观察一些优惠信息只有移动端才有,构造相应的 headers,使用 requests 模块(pip 装之):
def queryNotification():
url = "http://api.haojin.in/takeout_item_list?atag_id=0&offset=0&pagesize=10®ion_id=55b9c9d4c69575999049b2b4"
headers = {'content-type': 'application/json', 'User-Agent':'User-Agent: QMMWD/1.3.6 iPhone/9.1 AFNetwork/1.1'}
req = requests.get(url, headers=headers)
content = json.loads(req.content)
items = content['data']['sale_items']
for item in items:
price = item['price']
title = item['title']
origin_price = item['origin_price']
end_time = item['end_time']
quantity = item['quantity']
e = datetime.datetime.strptime(end_time, "%Y-%m-%d %H:%M:%S")
if float(price) < 2 and e > datetime.datetime.now() and quantity > 0:
notify(u"特价提醒!!", title, u"原价"+origin_price+u",现价:"+price, sound=True)
if __name__=='__main__':
while True:
queryHomeNotification()
time.sleep(30)
每 30 秒查询一次,没结束的活动中价格低于 2 元且还有库存的优惠信息,一共不到 50 行代码,运行成功。但看起来使用方式并不友好,没办法分享给小伙伴们呢。
打包
想到把代码包装成一个 OSX 的应用,这样就方便任何人用了。使用 py2app 打包(pip 装之):
新建 setup.py,可以自定义 icon(icns 格式)
from setuptools import setup APP = ['nearRemind.py'] APP_NAME = "NearRemind" DATA_FILES = [] OPTIONS = {'argv_emulation': True, 'iconfile': 'ico.icns'} setup( name=APP_NAME, app=APP, data_files=DATA_FILES, options={'py2app': OPTIONS}, setup_requires=['py2app'],
打包,默认当前路径下 dist 目录:
Python setup.py py2app
可以分享给小伙伴啦,启动就好,效果如下:
其他
虽然有了提示但还是未必能抢到,所以后面还给自己做了自动下单版本,因为需要 session_id 和 sid 及收货地址之类的个人信息,做公用版比较麻烦些,就当是自己的私人福利了~
有兴趣自己玩的话代码在 Github
如此简易的 App 缺陷有很多,例如启动后没有合理的关闭方式,只能右键强制退出;无限重复通知等。
顺便发现「好近」的一些问题:
- 接口访问频率似乎没有限制
- 重复下单(一秒十单没问题~再快也没试了)
- 活动状态好像是根据手机当前时间与接口里 end_time 对比来判断活动是否结束,且所有时间格式如下 “end_time”: “2015-12-21 23:59:00”,这种实现貌似不够好
Notification 刚移植到 OSX 上时就觉得这东西可以有很多种玩法,比如自己实现类似番茄工作法这样的小工具,这次也算试水成功了