Python中装饰器的一个妙用


Posted in Python onFebruary 08, 2015

好吧,我知道是大半夜……,但我还是觉得赶紧花上半个小时,把这最新的想法分享出来是值得的~直接进入正题~

我们来模拟一个场景,需要你去抓去一个页面,然后这个页面有好多url也要分别去抓取,而进入这些子url后,还有数据要抓取。简单点,我们就按照三层来看,那我们的代码就是如下:

def func_top(url):

    data_dict= {}

 

    #在页面上获取到子url

    sub_urls = xxxx

 

    data_list = []

    for it in sub_urls:

        data_list.append(func_sub(it))

 

    data_dict[\'data\'] = data_list

 

    return data_dict

 

def func_sub(url):

    data_dict= {}

 

    #在页面上获取到子url

    bottom_urls = xxxx

 

    data_list = []

    for it in bottom_urls:

        data_list.append(func_bottom(it))

 

    data_dict[\'data\'] = data_list

 

    return data_dict

 

def func_bottom(url):

    #获取数据

    data = xxxx

    return data

func_top是上层页面的处理函数,func_sub是子页面的处理函数,func_bottom是最深层页面的处理函数,func_top会在取到子页面url后遍历调用func_sub,func_sub也是同样。

如果正常情况下,这样确实已经满足需求了,但是偏偏这个你要抓取的网站可能极不稳定,经常链接不上,导致数据拿不到。

于是这个时候你有两个选择:

1.遇到错误就停止,之后重新从断掉的位置开始重新跑
2.遇到错误继续,但是要在之后重新跑一遍,这个时候已经有的数据不希望再去网站拉一次,而只去拉没有取到的数据

对第一种方案基本无法实现,因为如果别人网站的url调整顺序,那么你记录的位置就无效了。那么只有第二种方案,说白了,就是要把已经拿到的数据cache下来,等需要的时候,直接从cache里面取。

OK,目标已经有了,怎么实现呢?

如果是在C++中的,这是个很麻烦的事情,而且写出来的代码必定丑陋无比,然而庆幸的是,我们用的是python,而python对函数有装饰器。

所以实现方案也就有了:

定义一个装饰器,如果之前取到数据,就直接取cache的数据;如果之前没有取到,那么就从网站拉取,并且存入cache中.

代码如下:

def get_dump_data(dir_name, url):

    m = hashlib.md5(url)

    filename = m.hexdigest()

    full_file_name = \'dumps/%s/%s\' % (dir_name,filename)

 

    if os.path.isfile(full_file_name):

        return eval(file(full_file_name,\'r\').read())

    else:

        return None

 

 

def set_dump_data(dir_name, url, data):

    if not os.path.isdir(\'dumps/\'+dir_name):

        os.makedirs(\'dumps/\'+dir_name)

 

    m = hashlib.md5(url)

    filename = m.hexdigest()

    full_file_name = \'dumps/%s/%s\' % (dir_name,filename)

 

    f = file(full_file_name, \'w+\')

    f.write(repr(data))

    f.close()

 

 

def deco_dump_data(func):

    def func_wrapper(url):

        data = get_dump_data(func.__name__,url)

        if data is not None:

            return data

 

        data = func(url)

        if data is not None:

            set_dump_data(func.__name__,url,data)

        return data

 

    return func_wrapper

然后,我们只需要在每个func_top,func_sub,func_bottom都加上deco_dump_data这个装饰器即可~~

搞定!这样做最大的好处在于,因为top,sub,bottom,每一层都会dump数据,所以比如某个sub层数据dump之后,是根本不会走到他所对应的bottom层的,减少了大量的开销!

OK,就这样~ 人生苦短,我用python!

Python 相关文章推荐
PHP网页抓取之抓取百度贴吧邮箱数据代码分享
Apr 13 Python
说一说Python logging
Apr 15 Python
Python搭建FTP服务器的方法示例
Jan 19 Python
python pandas dataframe 按列或者按行合并的方法
Apr 12 Python
Python中交换两个元素的实现方法
Jun 29 Python
python Pandas库基础分析之时间序列的处理详解
Jul 13 Python
Django模板Templates使用方法详解
Jul 19 Python
python数据处理之如何选取csv文件中某几行的数据
Sep 02 Python
Pycharm如何运行.py文件的方法步骤
Mar 03 Python
python nohup 实现远程运行不宕机操作
Apr 16 Python
在python image 中实现安装中文字体
May 16 Python
keras 指定程序在某块卡上训练实例
Jun 22 Python
Python中使用HTMLParser解析html实例
Feb 08 #Python
Pyhton中防止SQL注入的方法
Feb 05 #Python
Windows系统下安装Python的SSH模块教程
Feb 05 #Python
Python 冒泡,选择,插入排序使用实例
Feb 05 #Python
Python中使用Flask、MongoDB搭建简易图片服务器
Feb 04 #Python
Python os模块中的isfile()和isdir()函数均返回false问题解决方法
Feb 04 #Python
Python中使用socket发送HTTP请求数据接收不完整问题解决方法
Feb 04 #Python
You might like
PHP 中英文混合排版中处理字符串常用的函数
2007/04/12 PHP
PHP HTML代码串截取代码
2008/12/29 PHP
解析php DOMElement 操作xml 文档的实现代码
2013/05/10 PHP
PHP中的表达式简述
2016/05/29 PHP
js正文内容高亮效果的实现方法
2013/06/30 Javascript
jquery处理页面弹出层查询数据等待操作实例
2015/03/25 Javascript
jQuery替换textarea中换行的方法
2015/06/10 Javascript
JS实现仿苹果底部任务栏菜单效果代码
2015/08/28 Javascript
jQuery实现指定区域外单击关闭指定层的方法【经典】
2016/06/22 Javascript
很棒的js Tab选项卡切换效果
2016/08/30 Javascript
前端开发必知的15个jQuery小技巧
2017/01/22 Javascript
在使用JSON格式处理数据时应该注意的问题小结
2017/05/20 Javascript
使用Python判断IP地址合法性的方法实例
2014/03/13 Python
Python实现程序的单一实例用法分析
2015/06/03 Python
Python 实现 贪吃蛇大作战 代码分享
2016/09/07 Python
Django卸载之后重新安装的方法
2017/03/15 Python
python+opencv实现动态物体识别
2018/01/09 Python
基于Django用户认证系统详解
2018/02/21 Python
对Python中gensim库word2vec的使用详解
2018/05/08 Python
padas 生成excel 增加sheet表的实例
2018/12/11 Python
Python列表常见操作详解(获取,增加,删除,修改,排序等)
2019/02/18 Python
python-tkinter之按钮的使用,开关方法
2019/06/11 Python
TensorFlow2.0矩阵与向量的加减乘实例
2020/02/07 Python
Python selenium抓取虎牙短视频代码实例
2020/03/02 Python
Python进行统计建模
2020/08/10 Python
CSS3基础(RGBa、text-shadow、box-shadow、border-radius)
2012/11/13 HTML / CSS
英国最大的电子零件及配件零售商:Partmaster
2017/04/24 全球购物
贝尔帐篷精品店:Bell Tent Boutique
2019/06/12 全球购物
英智兴达软件测试笔试题
2016/10/12 面试题
受欢迎的大学生自我评价
2013/12/05 职场文书
商务主管岗位职责
2013/12/08 职场文书
《蝙蝠和雷达》教学反思
2014/04/23 职场文书
信用社主任竞聘演讲稿
2014/05/23 职场文书
葬礼主持词
2015/07/02 职场文书
幼儿园秋季开学通知
2015/07/16 职场文书
Java8中Stream的一些神操作
2021/11/02 Java/Android