唔.....這個程序是這么多天來寫的最麻煩,最費(fèi)時間精力的一個程序,大概花了兩天時間
下面講講心酸歷程。。。
-
看看運(yùn)行結(jié)果:
image.png
初始界面是這樣,,而且我還只實(shí)現(xiàn)了小說部分,圖片部分甚至視頻部分都沒得精力搞下去了,,,就光實(shí)現(xiàn)這個小說部分,總共代碼長度就800多行了,image.png
點(diǎn)進(jìn)去之后的一部分是這樣的:image.png
最上面是它們網(wǎng)站所有小說的分類 ,然后中間是用戶可以進(jìn)行的操作。
功能還是挺不錯的,細(xì)節(jié)方面都調(diào)試過n遍了,現(xiàn)在bug應(yīng)該沒有,,吧。。

路徑下如果已經(jīng)存在就不會重復(fù)下載。
-
看起來簡單的一個程序,要實(shí)現(xiàn)出它完整的功能還是挺麻煩的。具體我才用了oop思想,也就是面向?qū)ο缶幊蹋巡煌δ艿膶?shí)現(xiàn)代碼分開編寫,可能會清楚些,封裝好后大概是這樣:image.png
很清晰明了,My_thread是線程,用來并行處理gui和爬蟲的任務(wù);
Gui就是我們的tkinter主界面;Spider就是我們的爬蟲部分。最下面調(diào)用下。
大體步驟:
(一):實(shí)現(xiàn)Spider類的部分功能:


大概一共就這么多個函數(shù),注釋已經(jīng)給的很詳細(xì)了。
注意內(nèi)容:
① number是類屬性,目的是判斷當(dāng)前是第幾只爬蟲(比如小說,圖片,甚至視頻需要不同的爬蟲來爬,這里記錄總共有幾只。)

這里面很多都是我在后期調(diào)試,然后實(shí)現(xiàn)新功能的時候慢慢加的,都是很有必要的。
③ 在實(shí)現(xiàn)get_etree的時候我也嘗試了很多次,剛開始一直修改timeout,因?yàn)橛袝r候網(wǎng)絡(luò)訪問會很慢(表現(xiàn)出卡死的樣子),所以我設(shè)置只要timeout后就退出;后來我發(fā)現(xiàn)很多時候根本爬不到數(shù)據(jù)。然后我給timeout設(shè)置很短,直接啥也沒有,設(shè)置很大,它爬半天也沒結(jié)果。

注意一些類屬性的判斷啥的都是后期加上去的,為了讓程序更完善。


它返回一個解析后所有數(shù)據(jù)的列表。
⑤ 下載文件的函數(shù)我為了和gui結(jié)合起來還是搞的挺復(fù)雜的:
但是主體思想如果不用gui的話還是很簡單,沒什么變化,給的待下載列表里面就是一個個的字典,每個字典都是一本小說,字典有兩個鍵,一個是小說名字,還一個是小說url。
⑥ deal_novel大概就是專門處理與gui交互的準(zhǔn)備過程,將一些必要的參數(shù)爬取下來,比如給⑤的參數(shù)列表,就在這里面實(shí)現(xiàn),這里我也把所有頁的所有小說都爬下來了(當(dāng)然用戶可以在gui界面手動停止。)大概這樣:
很多東西我都注釋了的,還挺容易看懂的。
⑦ start方法大概就是統(tǒng)籌下,做預(yù)處理工作等等:
大概內(nèi)容就這么多,很多東西不是一開始就能構(gòu)思完的,函數(shù)框架可以在剛開始構(gòu)建出來,但是內(nèi)容確實(shí)要根據(jù)程序的需要不斷變化。
(二):實(shí)現(xiàn)Gui類的部分功能:
這個gui是整個程序最復(fù)雜的一部分了(大概占了4,500行代碼),gui是用python 標(biāo)準(zhǔn)庫tkinter開發(fā)的, 如果沒有tkinter基礎(chǔ)可能難看懂 。gui實(shí)現(xiàn)過程大概有以下幾步:1. 創(chuàng)建主窗口,同時在主窗口的里面創(chuàng)建很多需要的組件。
- 給不同的組件綁定不同的事件。
- 當(dāng)觸發(fā)gui的事件后就設(shè)計(jì)函數(shù)去處理事件。
- gui的mainloop, 也就是一個永真循環(huán)。但是可以被阻塞,也可以在里面創(chuàng)建子進(jìn)程。





一個個大致講下:


其中frames是所有的框架組件,buttons是所有的按鈕組件,labels是所有的標(biāo)簽組件,它們都是列表,為什么要用列表呢?原因是方便管理,當(dāng)我處理同一類的組件時它們放在一起會很好處理,所以這是個好習(xí)慣,把所有同類型的組件放在同一個列表里。
③ 放置主窗體所有組件:
像這樣,有的用gird,有的用pack,看實(shí)際需求。
④ 處理主窗體的所有事件:
這里注意個細(xì)節(jié):我把按鍵響應(yīng)與按鈕綁定在一起,而不是單獨(dú)處理,這樣會很方便,f1和f2就是把按鍵響應(yīng)和按鈕綁定在一起的:

我把用戶點(diǎn)擊右上角的退出事件和離開事件也綁定在一起了,可以方便處理。 ⑤ 設(shè)置字體沒啥說的,用tkinter.font庫生成一個字體列表,用的時候從里面取就好了:


⑦ 當(dāng)用戶點(diǎn)擊“小說”后會觸發(fā)一個很重要的事件(主要代碼也在里面),結(jié)果是會生成一個子窗體,然后各種操作也是在子窗體里面去完成,這樣做的好處,就是可以靈活的處理不同類型的主事件,比如圖片啊,視頻啊,小說啊什么,點(diǎn)擊后會有更多的靈活處理的空間。

放置這些組件也是在響應(yīng)函數(shù)里完成的。同時還需要在里面完成處理子窗體的組件綁定的各種事件:

這里重要的點(diǎn)也是:將按鍵事件與按鈕綁定在一起,方便一起處理。
⑧ 各種響應(yīng)事件的實(shí)現(xiàn):我都放在類里面,作為類的成員函數(shù),這樣一是方便,二是方便與spider爬蟲類交互。比如這個關(guān)閉子窗口的事件:
需要把用戶點(diǎn)擊右上角退出和esc離開事件都綁定成了它。
。。。大概就說這么多,有tkinter基礎(chǔ)的好搞些,慢慢搞總是能搞出來的。
這里我再著重說下幾個我之前不太會的:
- 創(chuàng)建frame框架時要手動設(shè)置它的長和寬, 創(chuàng)建各種組件時如果你需要按照你的規(guī)則拜訪好,最好也給他們設(shè)置長和寬, 但是這個長和寬和主窗體設(shè)置時候的長和寬是不同的, 差不多組件的長和寬代表它在”一面“一個可視范圍內(nèi)能占多數(shù)條(例如 listbox組件)
- 將組件與拉條綁定, 需要將拉條的command綁定成組件的yview函數(shù), 將組件的yscrollcommand綁定成拉條的set函數(shù)。
- grid的sticky 將組件放好后邊緣對齊很重要。 pack的fill將組件沿著x或者y或者兩者填充滿, side表示將組件放在窗體的哪個邊上。
(三):實(shí)現(xiàn)Thread類的功能:
我實(shí)現(xiàn)的thread類繼承threading.Thread類,這樣我只要重寫它的run方法,那么run方法里面的內(nèi)容就是在子線程中會執(zhí)行的方法。這里為什么要用thread開線程? 因?yàn)間ui界面是一個死循環(huán), 你要在死循環(huán)里面暫停后去處理別的事件(這里比如爬蟲事件), 那么主窗體會卡死, 未響應(yīng), 所以你必須要開線程去處理那些處理完需要很長時間的代碼。

我加了個code, 這個用來實(shí)現(xiàn)不同的處理, target_list則是傳遞過來的待下載的目標(biāo)列表, 然后用線程去下載。
run方法就是線程的主題,線程會做這里面的事情:

我像這樣用不同的code來識別處理不同的事件,這樣很方便,不用寫額外的線程代碼啥的。
(四):慢慢一步一步debug,統(tǒng)領(lǐng)協(xié)調(diào)整個程序,處理類之間的交互:
然后最后這步才是最重要的,我們需要把自己想象成用戶,去嘗試運(yùn)行自己的程序,然后處理程序的bug,或者哪些需要改進(jìn)的也要自己去改進(jìn),反正都到了這步了,慢慢來就好了,我也是花了很長時間在這步,有時候運(yùn)行的時候想到了怎么改進(jìn),但是正在處理別的,就用記事本把事情記下來之后再處理,一步步完善,直到最后把程序做好,總之,用戶的體驗(yàn)才是最重要的,你程序?qū)懙脑俸脹]有用戶喜歡也是白搭,所以跟著用戶的喜好走很重要的。
其中我在這步里面就加了n個類的成員屬性去完成不同的事情,處理各種bug。。
總之很煎熬,但只要你堅(jiān)持下來了,你就能勝利。
大概。。。就寫這么多吧,,,這個做完自己還是有很大的成長, 但是也看到了很多自己的不足, 要學(xué)習(xí)的東西還是太多了, ,希望大家好好學(xué)習(xí),, 知識是最棒的。。 ?
(如果想要源碼或者exe文件或者有想要討論的地方可以私信我。??吹奖鼗亍Vx謝)



