170313-pyGUI爬虫和正则回溯陷阱

1625-5 王子昂 总结《2017年3月13日》 【连续第163天总结】

A.Python 爬虫

B.昨天做好了CUI的愿望单爬虫,但是由于命令行的编码默认是GB2312的,与python的utf-8不匹配,所以萌生了制作GUI的想法

很简单,因为以前用过Tk的控制,在这个显示程序中完全不需要交互,而只是显示即可

刚开始是爬取完成以后进入mainloop()显示,测试了一下觉得有些迟滞,如果网络环境不好的话显示想必会更加慢

那先显示界面,再进行爬取,然后输出到文本框中不就行了吗。

尝试了一下,直接在mainloop()后添加text.insert()方法,发现没有反应

百思不得其解,明明之前做五子棋的时候也是开始mainloop()以后再更新文本的。检查了代码半天发现,之前的五子棋中的所有insert()方法都是绑定在某个函数,由事件驱动的;而这次是直接一条命令,因此无法执行。

遂查询使用after()(延时器)方法,仍然不行。思考了一下,这次绑定after方法是在mainloop开始之后的,所以绑定失败。于是把after()方法放在mainloop()之前,终于成功。

光秃秃的界面有些丑,再加上如果出现了不熟悉的游戏名字,没有图片来配合会认不出来。于是尝试爬取游戏图标地址并显示在界面中。查了一通,应该先用urllib2模块把图片以二进制下载下来,然后转换成gif格式用label控件显示在界面上

但是第一步,爬取图片链接就出现了问题:在线正则测试的网站对于python似乎有什么看法,在截取的一小段文本中php的正则只需要几百步,python却要几万步。把整个网页的源码放入以后,Python显示timeout,php则是catastrophic backtracking。

查询得知,正则回溯陷阱---由于正则表达式的写法,使得系统需要花费过多的时间和步数去查询。

举一个栗子:

考虑这样一个正则

/(a*)*b/

 ,用它来匹配”aaaaaaaaaa”(10个a组成的字符串)

花费了6143步才完成!如果再加上一个a呢,变成11个a组成的字符串会怎么样?

变成12287步了,翻了一倍。事实就是这样,当出现以上这种量词嵌套时,如果遭遇最坏情况(最后一个字符才能确实匹配不成功),那么这时正则引擎陷入灾难性回溯,时间复杂度为指数级)。  如果你试着再嵌套一层,9个a组成的字符串就能突破100万步了……


这才是正则表达式的难点和精髓:优化算法。

\d表示数字,\w表示字母,明明用.就可以全部通配,为什么要加以限制呢?---为了节省时间和资源

回溯算法非常方便,但也非常可怕。一旦落入回溯陷阱将会花费大量的时间。


于是图片的地址就爬不下来了,因为它的标识不易提取

其实我觉得使用尾部匹配应该可以快捷一点的,不过不知道为什么在线正则测试的网站似乎出了问题,python完全处理不了整页的源码。

附上代码:

#encoding:utf-8
import urllib2
import re
import Tkinter
top=Tkinter.Tk()
text=Tkinter.Text(width=100)
text.pack()

def spider():
    url='http://steamcommunity.com/id/whklhh/wishlist'
    request=urllib2.Request(url)
    response=urllib2.urlopen(request)
    data=response.read()
#    reg=r'<div class="gameListRowLogo">(?:.+?\n.+?){2}src="(.+?)">(?:.*?\n.+?){5}'+\
    reg=r'<div class="discount_block discount_block_inline">.+?\n.+?>(-\d+%)(?:.+?\n.+?){2}¥ (\d+).+?\n.+?¥ (\d+)'+\
        r'(?:.+?\n.+?){4}href="(.+?)"(?:.+?\n.+?){6}>(.+?)<'
    imgre=re.compile(reg)
    imglist=re.findall(imgre,data)
    for pro in imglist:
        text.insert('end',("%s\n\t现价:%s,原价:%s,折扣:%s,商品页面:%s\n")%(pro[4],pro[2],pro[1],pro[0],pro[3]))
text.after(1,spider)
Tkinter.mainloop()

C. 明日计划

Java 日志

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值