Python爬蟲中文小說網點查找小說並且保存到txt(含中文亂碼處理方法)


從某些網站看小說的時候經常出現垃圾廣告,一氣之下寫個爬蟲,把小說鏈接抓取下來保存到txt,用requests_html全部搞定,代碼簡單,容易上手.

中間遇到最大的問題就是編碼問題,第一抓取下來的小說內容保持到txt時出現亂碼,第二url編碼問題,第三UnicodeEncodeError

先貼源代碼,后邊再把思路還有遇到的問題詳細說明。

 

from requests_html import HTMLSession as hs

def get_story(url):
    global f
    session=hs()
    r=session.get(url,headers=headers)
    r.html.encoding='GBK'
    title=list(r.html.find('title'))[0].text#獲取小說標題
    nr=list(r.html.find('.nr_nr'))[0].text#獲取小說內容
    nextpage=list(r.html.find('#pb_next'))[0].absolute_links#獲取下一章節絕對鏈接
    nextpage=list(nextpage)[0]
    if(nr[0:10]=="_Middle();"):
        nr=nr[11:]
    if(nr[-14:]=='本章未完,點擊下一頁繼續閱讀'):
        nr=nr[:-15]
    print(title,r.url)
    f.write(title)
    f.write('\n\n')
    f.write(nr)
    f.write('\n\n')
    return nextpage


def search_story():
    global BOOKURL
    global BOOKNAME
    haveno=[]
    booklist=[]
    bookname=input("請輸入要查找的小說名:\n")
    session=hs()
    payload={'searchtype':'articlename','searchkey':bookname.encode('GBK'),'t_btnsearch':''}
    r=session.get(url,headers=headers,params=payload)
    haveno=list(r.html.find('.havno'))#haveno有值,則查找結果如果為空
    booklist=list(r.html.find('.list-item'))#booklist有值,則有多本查找結果
    while(True):
        if(haveno!=[] and booklist==[]):
            print('Sorry~!暫時沒有搜索到您需要的內容!請重新輸入')
            search_story()
            break
        elif(haveno==[] and booklist!=[]):
            print("查找到{}本小說".format(len(booklist)))
            for book in booklist:
                print(book.text,book.absolute_links)
            search_story()
            break
        else:
            print("查找到結果,小說鏈接:",r.url)
            BOOKURL=r.url
            BOOKNAME=bookname
            break


global BOOKURL
global BOOKNAME
url='http://m.50zw.net/modules/article/waps.php'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36 OPR/53.0.2907.99'
}

search_story()
chapterurl=BOOKURL.replace("book","chapters")
session=hs()
r=session.get(chapterurl,headers=headers)
ch1url=list(r.html.find('.even'))[0].absolute_links#獲取第一章節絕對鏈接
ch1url=list(ch1url)[0]
global f
f=open(BOOKNAME+'.txt', 'a',encoding='gb18030',errors='ignore')
print("開始下載,每一章節都需要爬到,速度快不了,請等候。。。。\n")
nextpage=get_story(ch1url)
while(nextpage!=BOOKURL):
    nextpage=get_story(nextpage)
f.close
    

 

爬蟲思路及遇到的問題分析如下:

先查找小說,並且把小說鏈接抓取下來,以網站http://m.50zw.net/modules/article/waps.php為例,首先在瀏覽器中打開鏈接並且右鍵點檢查,選擇Network標簽,我用的是chrome瀏覽器,按F1設置把Network底下的Preserve log勾選上,方便接下來查找log,以搜索‘帝后世無雙’為例,搜索到結果后直接跳到了此本小說的url:http://m.50zw.net/book_86004/

 

查看到請求方式是GET,Request URL是 http://m.50zw.net/modules/article/waps.php?searchtype=articlename&searchkey=%B5%DB%BA%F3%CA%C0%CE%DE%CB%AB&t_btnsearch=

然后分析出請求參數有三個,searchtype先固定用圖書名來查找,而searchkey我們輸入的是”敵后世無雙“,url encoding成了%B5%DB%BA%F3%CA%C0%CE%DE%CB%AB,我們在python ide里邊分別輸入:

"敵后世無雙".encode('GBK'):b'\xb5\xd0\xba\xf3\xca\xc0\xce\xde\xcb\xab'

"敵后世無雙".encode('utf-8'):b'\xe6\x95\x8c\xe5\x90\x8e\xe4\xb8\x96\xe6\x97\xa0\xe5\x8f\x8c'

對照輸出結果我們知道這里url編碼采用的是GBK

接下來我們用代碼來驗證我們分析的結果

from requests_html import HTMLSession as hs
url='http://m.50zw.net/modules/article/waps.php'
payload={'searchtype':'articlename','searchkey':'帝后世無雙','t_btnsearch':''}
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36 OPR/53.0.2907.99'
}
session=hs()
r=session.get(url,headers=headers,params=payload)
print(r.url)

 

 運行結果:

http://m.50zw.net/modules/article/waps.php?searchtype=articlename&searchkey=%E5%B8%9D%E5%90%8E%E4%B8%96%E6%97%A0%E5%8F%8C&t_btnsearch=

比較得到的url跟我們剛才手動輸入后得到的url有出入,代碼里邊如果沒有指定編碼格式的話了這里url編碼默認是urf-8,因為編碼問題我們沒有得到我們想要的結果,那接下來我們修改代碼指定編碼試試

payload={'searchtype':'articlename','searchkey':'帝后世無雙'.encode('GBK'),'t_btnsearch':''}

 

這回運行結果得到我們想要的url:

 http://m.50zw.net/book_86004/

好,成功了!!!

那接下來我們要獲取第一章節的鏈接,中間用到了requests_html來抓取絕對鏈接

bookurl='http://m.50zw.net/book_86004/'
chapterurl=bookurl.replace("book","chapters")
session=hs()
r=session.get(chapterurl,headers=headers)
ch1url=list(r.html.find('.even'))[0].absolute_links
ch1url=list(ch1url)[0]
print(ch1url)

 

 運行結果:

http://m.50zw.net/book_86004/26127777.html

成功取得第一章節鏈接

接下來我們開始獲取小說內容並且獲取下一章鏈接直到把整本小說下載下來為止,

在這個部分遇到UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position 46:illegal multibyte sequence,這個問題最終在用open函數打開txt時加兩個參數解決encoding='gb18030',errors='ignore'.

在之前也用過另外一種方案,就是把u'\xa0'替換成跟它等效的u' ',雖然解決了'\xa0'的error,可是后來又出現了’\xb0'的error,總不能出現一個類似的rror就修改代碼替換一次,所以這個方案被放棄掉.

 

session=hs()
r=session.get(ch1url,headers=headers)
title=list(r.html.find('title'))[0].text
nr=list(r.html.find('.nr_nr'))[0].text
##nr=nr.replace(u'\xa0',u' ')
nextpage=list(r.html.find('#pb_next'))[0].absolute_links
nextpage=list(nextpage)[0]
if(nr[0:10]=="_Middle();"):
    nr=nr[11:]
if(nr[-14:]=='本章未完,點擊下一頁繼續閱讀'):
    nr=nr[:-15]
print(title,r.url)
print(nextpage)
f=open('帝后世無雙.txt', 'a',encoding='gb18030',errors='ignore')
f.write(title)
f.write('\n\n')
f.write(nr)
f.write('\n\n')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM