Python爬蟲(四)——小說下載器

既然我們之前已經講了BeautifulSoup的使用,那麼我們今天就來實戰下,用BeautifulSoup解析小說網站,做一個小說下載器;

首先,先分析一下網站:

  1. 我們的目標是一個叫全小說的網站:https://qxs.la/

    我們可以看見右上角的位置有一個搜索框,我們可以將想要搜索的關鍵詞鍵入,然後搜索我們想要的內容,我們來分析下這個網站的結構;
  2. 我們在搜索框輸入“唐家三少”,看看網頁會發生怎麼樣的變化:

    網頁把站內所有唐三的小說都搜索出來了,最新的小說都有,看來這個網站還是更新挺勤的;回過頭來分析下頁面,沒有打開新的網頁,但是打開了一個新的頁面:我們發現變化的是在原網址後面加上了 "/s_***"
    我們搜索另外一個,看看這個發現成不成立:
    我們發現這個想法貌似是對的,搜索的內容頁面就是在原址的基礎上加上了 "/s_***"
  3. 我們隨便點開一個,看看對應的頁面內容是怎麼樣的:

    我們發現小說的所有章節都在這裏面了,我們來檢查一下源碼,看下網頁的結構是怎麼設計的:

    發現所有的章節都在 <div class="chapters"> 標籤下面,但是客氣的是竟然有幾章湊數的章節,這個我們先不管,我們打開第一章,看看裏面的分佈;
  4. 小說的內容已經有了,我們可以看見最下面有下一章,那麼我們是不是可以通過這個下一章鏈接進行翻頁,這樣就不用獲取所有頁面的網址了

好了,我們現在已經分析好了,接下來就是開始來寫代碼了,既然是小說下載器,那麼肯定要有一個界面是不是:

  1. 有一個輸入框,接收我們想要搜索的關鍵字
  2. 要有一個列表框,顯示我們搜索出來的結果
  3. 當我們選擇小說,單擊下載按鈕的時候,就開始下載這本小說,生成txt文檔

設計小說下載器界面:

from tkinter import *

window = Tk()
window.geometry('300x500')
window.title('小說下載器')

Label(window,text='請輸入你想搜索的內容:',font=('楷體',12)).place(x=10,y=10)
# 輸入框
key_word = Entry(window,font=('楷體',16),width=25)
key_word.place(x=10,y=35)

# 顯示列表
show = Listbox(window,width=25,height=15,font=('楷體',16))
show.place(x=10,y=80)

# 搜索按鈕
def seek():
    print('')
Button(window,text='搜索',font=('楷體',16),command=seek).place(x=10,y=430)

# 下載按鈕
def download():
    print('')
Button(window,text='下載',font=('楷體',16),command=download).place(x=120,y=430)

# 退出按鈕
Button(window,text='退出',font=('楷體',16),command=quit).place(x=228,y=430)

window.mainloop()

第二步,實現小說搜索的功能

def seek():
    global info
    book = []
    author = []
    add = []
    word = key_word.get()    # 獲取輸入框的內容
    url = 'https://qxs.la/s_' + word    # 拼接搜索地址
    bs = get_html_bs(url)    # 獲取源碼並返回bs對象
    data_all = bs.find_all('ul',class_='list_content')    # 搜索所有的小說
    for data in data_all:    # 遍歷提取信息
        book.append(data.find_all('a')[0].string)        # 提取小說名字
        add.append(data.find_all('a')[0]['href'])        # 提取小說地址
        author.append(data.find_all('a')[2].string)      # 提取小說作者
    info = list(zip(book,author,add))    # 將提取出來的信息打包
    for i in range(show.size()):    # 清空所有的列表項
        show.delete(0)
    for data in info:    # 將信息插入到列表中,顯示內容
        show.insert('end','{}({})'.format(data[0],data[1]))
Button(window,text='搜索',font=('楷體',16),command=seek).place(x=10,y=430)

第三步,實現小說下載功能:

def download():
    global info    # 導入全局變量
    txt = ''       # 存放小說內容
    index = show.curselection()[0]    # 獲取選中列表項的下標
    book_name = info[index][0]        # 提取書名
    url = 'https://qxs.la' + info[index][2]    # 合成小說詳情頁面地址
    bs = get_html_bs(url)        # 獲取源碼並返回bs對象
    first = bs.find('div',class_="chapter")    # 提取出第一篇小說的地址
    url = 'https://qxs.la' + first.find('a')['href']    # 合成地址
    while True:
        try:
            bs = get_html_bs(url)    # 獲取小說內容頁面
            txt = txt + bs.find('div',class_="text t_c").h1.text + '\n'    # 保存章節題目
            data = bs.find('div', id="content")    # 提取小說內容
            data = data.find_all(text=True)        # 因爲這個頁面比較特殊,大標籤內包括小標籤和文本內容
                                                   # 所以要經過進一步的處理,先獲取全部文本內容
            for d in data:    # 遍歷所有獲取到的內容
                if d[0:2] == u'\u3000\u3000':      # 發現小說內容都有兩個空格開頭
                    txt = txt + d.strip() + '\n'   # 將小說內容拼起來
            print('{}下載完畢!'.format(url))       # 輸出下載結果
            next_url = bs.find('a', id="nextLink")['href']    # 獲取下一章的地址
            if next_url[0:5] == '//qxs':    # 發現最後一張還是有下一章的,但是下一章的地址是以“//qxs”開頭
                print('下載完畢!')
                break
            url = 'https://qxs.la' + next_url    # 拼接下一章的地址

        except:
            print('下載錯誤!')

    txt.encode('utf-8')    # 設置文字編碼
    with open('{}.txt'.format(book_name),'w') as f:    # 保存小說,生成txt文檔
        f.write(txt)
Button(window,text='下載',font=('楷體',16),command=download).place(x=120,y=430)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章