python爬虫爬取某学习网站并用tkinter将整个程序封装成完整的界面

唔.....这个程序是这么多天来写的最麻烦,最费时间精力的一个程序,大概花了两天时间
下面讲讲心酸历程。。。

  1. 看看运行结果:


    image.png

    初始界面是这样,,而且我还只实现了小说部分,图片部分甚至视频部分都没得精力搞下去了,,,就光实现这个小说部分,总共代码长度就800多行了,
    image.png

    点进去之后的一部分是这样的:
    image.png

最上面是它们网站所有小说的分类 ,然后中间是用户可以进行的操作。
功能还是挺不错的,细节方面都调试过n遍了,现在bug应该没有,,吧。。

下载界面是这样的:
image.png

路径下如果已经存在就不会重复下载。

  1. 看起来简单的一个程序,要实现出它完整的功能还是挺麻烦的。具体我才用了oop思想,也就是面向对象编程,把不同功能的实现代码分开编写,可能会清楚些,封装好后大概是这样:
    image.png

    很清晰明了,My_thread是线程,用来并行处理gui和爬虫的任务;
    Gui就是我们的tkinter主界面;Spider就是我们的爬虫部分。最下面调用下。

大体步骤:
(一):实现Spider类的部分功能:


image.png

image.png

大概一共就这么多个函数,注释已经给的很详细了。
注意内容:
① number是类属性,目的是判断当前是第几只爬虫(比如小说,图片,甚至视频需要不同的爬虫来爬,这里记录总共有几只。)

② 构造函数大概初始化了:
image.png

这里面很多都是我在后期调试,然后实现新功能的时候慢慢加的,都是很有必要的。

③ 在实现get_etree的时候我也尝试了很多次,刚开始一直修改timeout,因为有时候网络访问会很慢(表现出卡死的样子),所以我设置只要timeout后就退出;后来我发现很多时候根本爬不到数据。然后我给timeout设置很短,直接啥也没有,设置很大,它爬半天也没结果。

我最后才想了个好办法:就是开循环,timeout尽可能设置小,如果超时了先不退出,循环个10几次总时间也不长,因为每次的时间timeout挺短的,这样几乎每次都可以短时间内爬取到数据:超时后的处理大概像这样,先捕捉异常然后再处理它:
image.png

注意一些类属性的判断啥的都是后期加上去的,为了让程序更完善。

这里循环完了还没访问到数据的话就退出了,认定网络不好或者原网站出了问题:
image.png

④ 解析函数大概就这么简单:
image.png

它返回一个解析后所有数据的列表。

⑤ 下载文件的函数我为了和gui结合起来还是搞的挺复杂的:
image.png

但是主体思想如果不用gui的话还是很简单,没什么变化,给的待下载列表里面就是一个个的字典,每个字典都是一本小说,字典有两个键,一个是小说名字,还一个是小说url。

⑥ deal_novel大概就是专门处理与gui交互的准备过程,将一些必要的参数爬取下来,比如给⑤的参数列表,就在这里面实现,这里我也把所有页的所有小说都爬下来了(当然用户可以在gui界面手动停止。)大概这样:
image.png

很多东西我都注释了的,还挺容易看懂的。

⑦ start方法大概就是统筹下,做预处理工作等等:
image.png

大概内容就这么多,很多东西不是一开始就能构思完的,函数框架可以在刚开始构建出来,但是内容确实要根据程序的需要不断变化。

(二):实现Gui类的部分功能:
这个gui是整个程序最复杂的一部分了(大概占了4,500行代码),gui是用python 标准库tkinter开发的, 如果没有tkinter基础可能难看懂 。gui实现过程大概有以下几步:1. 创建主窗口,同时在主窗口的里面创建很多需要的组件。

  1. 给不同的组件绑定不同的事件。
  2. 当触发gui的事件后就设计函数去处理事件。
  3. gui的mainloop, 也就是一个永真循环。但是可以被阻塞,也可以在里面创建子进程。

我设计了这些函数:
image.png
image.png
image.png
image.png
image.png

一个个大致讲下:

① 构造函数:创建主窗体,设置标题啥的,设置很多个和spider类通信的实例属性:
image.png

② 生成主窗体所有组件:
image.png

其中frames是所有的框架组件,buttons是所有的按钮组件,labels是所有的标签组件,它们都是列表,为什么要用列表呢?原因是方便管理,当我处理同一类的组件时它们放在一起会很好处理,所以这是个好习惯,把所有同类型的组件放在同一个列表里。

③ 放置主窗体所有组件:
image.png

像这样,有的用gird,有的用pack,看实际需求。

④ 处理主窗体的所有事件:
image.png

这里注意个细节:我把按键响应与按钮绑定在一起,而不是单独处理,这样会很方便,f1和f2就是把按键响应和按钮绑定在一起的:
image.png

我把用户点击右上角的退出事件和离开事件也绑定在一起了,可以方便处理。

⑤ 设置字体没啥说的,用tkinter.font库生成一个字体列表,用的时候从里面取就好了:
image.png

⑥ 主体和start就是做初始工作,程序从start开始,依次调用所有的函数:主体是一个永真循环:
image.png

⑦ 当用户点击“小说”后会触发一个很重要的事件(主要代码也在里面),结果是会生成一个子窗体,然后各种操作也是在子窗体里面去完成,这样做的好处,就是可以灵活的处理不同类型的主事件,比如图片啊,视频啊,小说啊什么,点击后会有更多的灵活处理的空间。

这是子窗体的所有组件:
image.png

放置这些组件也是在响应函数里完成的。同时还需要在里面完成处理子窗体的组件绑定的各种事件:
image.png

这里重要的点也是:将按键事件与按钮绑定在一起,方便一起处理。

⑧ 各种响应事件的实现:我都放在类里面,作为类的成员函数,这样一是方便,二是方便与spider爬虫类交互。比如这个关闭子窗口的事件:
image.png

需要把用户点击右上角退出和esc离开事件都绑定成了它。

。。。大概就说这么多,有tkinter基础的好搞些,慢慢搞总是能搞出来的。

这里我再着重说下几个我之前不太会的:

  1. 创建frame框架时要手动设置它的长和宽, 创建各种组件时如果你需要按照你的规则拜访好,最好也给他们设置长和宽, 但是这个长和宽和主窗体设置时候的长和宽是不同的, 差不多组件的长和宽代表它在”一面“一个可视范围内能占多数条(例如 listbox组件)
  2. 将组件与拉条绑定, 需要将拉条的command绑定成组件的yview函数, 将组件的yscrollcommand绑定成拉条的set函数。
  3. grid的sticky 将组件放好后边缘对齐很重要。 pack的fill将组件沿着x或者y或者两者填充满, side表示将组件放在窗体的哪个边上。

(三):实现Thread类的功能:
我实现的thread类继承threading.Thread类,这样我只要重写它的run方法,那么run方法里面的内容就是在子线程中会执行的方法。这里为什么要用thread开线程? 因为gui界面是一个死循环, 你要在死循环里面暂停后去处理别的事件(这里比如爬虫事件), 那么主窗体会卡死, 未响应, 所以你必须要开线程去处理那些处理完需要很长时间的代码。

thread继承自标准库 。
image.png

我加了个code, 这个用来实现不同的处理, target_list则是传递过来的待下载的目标列表, 然后用线程去下载。
run方法就是线程的主题,线程会做这里面的事情:
image.png

我像这样用不同的code来识别处理不同的事件,这样很方便,不用写额外的线程代码啥的。

(四):慢慢一步一步debug,统领协调整个程序,处理类之间的交互:
然后最后这步才是最重要的,我们需要把自己想象成用户,去尝试运行自己的程序,然后处理程序的bug,或者哪些需要改进的也要自己去改进,反正都到了这步了,慢慢来就好了,我也是花了很长时间在这步,有时候运行的时候想到了怎么改进,但是正在处理别的,就用记事本把事情记下来之后再处理,一步步完善,直到最后把程序做好,总之,用户的体验才是最重要的,你程序写的再好没有用户喜欢也是白搭,所以跟着用户的喜好走很重要的。
其中我在这步里面就加了n个类的成员属性去完成不同的事情,处理各种bug。。
总之很煎熬,但只要你坚持下来了,你就能胜利。

大概。。。就写这么多吧,,,这个做完自己还是有很大的成长, 但是也看到了很多自己的不足, 要学习的东西还是太多了, ,希望大家好好学习,, 知识是最棒的。。 ✌

(如果想要源码或者exe文件或者有想要讨论的地方可以私信我。。看到必回。谢谢)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容