前言 近来无意中看到一些Python的应用场景——抢购。这的确是一个恰当的应用,因此本文从一个开源项目库来入手分析项目是如何运行的。
结构 解析
入口 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 if __name__ == '__main__' : a = """ oooo oooooooooo. .oooooo..o oooo o8o oooo oooo `888 `888' `Y8b d8P' `Y8 `888 `"' `888 `888 888 888 888 Y88bo. .ooooo. .ooooo. 888 oooo oooo 888 888 888 888 888 `"Y8888o. d88' `88b d88' `"Y8 888 .8P' `888 888 888 888 888 888 8888888 `"Y88b 888ooo888 888 888888. 888 888 888 888 888 d88' oo .d8P 888 .o 888 .o8 888 `88b. 888 888 888 .o. 88P o888bood8P' 8""88888P' `Y8bod8P' `Y8bod8P' o888o o888o o888o o888o o888o `Y888P 功能列表: 1.预约商品 2.秒杀抢购商品 """ print (a) jd_seckill = JdSeckill() choice_function = input ('请选择:' ) if choice_function == '1' : jd_seckill.reserve() elif choice_function == '2' : jd_seckill.seckill_by_proc_pool() else : print ('没有此功能' ) sys.exit(1 )
这一段代码很简单:
首先输出一段提示,让用户稍后选择预约还送抢购; 然后实例化jd_seckill = JdSeckill()
; 根据输入选择功能 主功能(预约) 接下来先看一下预约功能,调用了reserve()
,这段代码使用了装饰器,判断是否登录。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @check_login def reserve (self ): """ 预约 """ self._reserve() @check_login def seckill (self ): """ 抢购 """ self._seckill() @check_login def seckill_by_proc_pool (self, work_count=5 ): """ 多进程进行抢购 work_count:进程数量 """ with ProcessPoolExecutor(work_count) as pool: for i in range (work_count): pool.submit(self.seckill)
可以看到预约、抢购和多线程抢购这些功能都使用了装饰器。
登录判断 1 2 3 4 5 6 7 8 9 10 11 def check_login (func ): """ 用户登陆态校验装饰器。若用户未登陆,则调用扫码登陆 """ @functools.wraps(func ) def new_func (self, *args, **kwargs ): if not self.qrlogin.is_login: logger.info("{0} 需登陆后调用,开始扫码登陆" .format (func.__name__)) self.login_by_qrcode() return func(self, *args, **kwargs) return new_func
这里记录一下@functools.wraps(fun)
的作用,主要因为增加了装饰器的函数其实就变成了另外一个函数,____name__
和__doc__
都发生了变化。因此增加了@functools.wraps(fun)
之后就可以防止此类情况的发生。
执行步骤:
首先判断self.qrlogin.is_login
是否True
,默认为False
。self.qrlogin = QrLogin(self.spider_session)
会调用QrLogin -> SpiderSession
.
QrLogin()
功能:
初始化扫码目录定义二维码文件名称 设置session 设置默认登录状态为False
刷新登录状态 刷新是否登录的状态 验证cookie(是否登录) 获取登录页面 缓存并展示登录二维码 通过token获取ticket 校验ticket 使用二维码登录 session处理 SpiderSession()
这个类功能是为了处理session:
初始化定义cookie目录 从配置文件获取user-agent
初始化session。 初始化session 获取并设置header 获取user_agent
获取cookie 设置cookie 从本地加载cookie 保存cookie到本地 session的处理这一段代码不太熟悉,之前没有接触过,下面分析一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def _init_session (self ): session = requests.session() session.headers = self.get_headers() return session def get_headers (self ): return {"User-Agent" : self.user_agent, "Accept" : "text/html,application/xhtml+xml,application/xml;" "q=0.9,image/webp,image/apng,*/*;" "q=0.8,application/signed-exchange;" "v=b3" , "Connection" : "keep-alive" }