標籤:errors arc 圖片 arch reserve ade url 亂碼 編碼問題
從某些網站看小說的時候經常出現垃圾廣告,一氣之下寫個爬蟲,把小說連結抓取下來儲存到txt,用requests_html全部搞定,代碼簡單,容易上手.
中間遇到最大的問題就是編碼問題,第一抓取下來的小說內容保持到txt時出現亂碼,第二url編碼問題,第三UnicodeEncodeError
先貼原始碼,後邊再把思路還有遇到的問題詳細說明。
from requests_html import HTMLSession as hsdef 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 nextpagedef 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 breakglobal BOOKURLglobal BOOKNAMEurl=‘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 ff=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 hsurl=‘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_linksch1url=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].textnr=list(r.html.find(‘.nr_nr‘))[0].text##nr=nr.replace(u‘\xa0‘,u‘ ‘)nextpage=list(r.html.find(‘#pb_next‘))[0].absolute_linksnextpage=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‘)
Python爬蟲中文小說網點尋找小說並且儲存到txt(含中文亂碼處理方法)