簡易python爬蟲--修真四萬年

前言

小說一章一章看,多麻煩啊,還是一次性看全本比較順暢。但是網絡上小說全本下載很少,是不是很苦惱呢?沒關係,開動雙手,讓我們用python寫一個爬蟲程序獲得我們想讀的小說全文吧!

準備

簡易爬蟲涉及到的東西不多,這裏推薦python的兩個庫:requestsBeautifulSoup。requests用於請求網頁內容,相當於把整個網頁下載下來。python也有標準庫urllib2、urllib3等,但是沒有requests簡單易用。BeautifulSoup是python一個解析html、lxml的一個非常強大的庫。這裏我們就用這兩個庫就可以完成我們的小爬蟲。
當然一點Html和CSS選擇器的知識也是必要的。大家可以去這個網站上查詢,現學現賣!

動手!

偵查敵情

知己知彼,百戰不殆。我選擇了筆趣島作爲我的目標網站。大家也可以去尋找其他的網站,原理相同。我選擇我最近在追的一本小說修真四萬年
打開這個小說的首頁後,我們用瀏覽器的開發者工具。Chrome的快捷鍵是F12。打開之後可以看到下圖:
修真四萬年首頁+F12
右邊窗口就是這個網頁的代碼!由於這是一個比較簡單的網頁,所有都在裏面了,包括《修真四萬年》所有章節的目錄,以及我們之後要用到的每章節目錄對應的url。
點擊右邊窗口左上角的那個箭頭箭頭。點擊之後鼠標鍵頭走到哪裏,右邊窗口就會跟着變化。這是因爲之前的按鈕可以根據鼠標定位頁面代碼。定位到目錄所在的區塊(目錄所在的區塊全部變藍),點擊一下固定右邊定位的代碼位置:
目錄的位置
div、dl、dt、dd這些叫做標籤,class、id這些叫做屬性。不明白的同學們可以去看一下CSS選擇器的內容。之後我們要用BeautifulSoup通過這些標籤和屬性獲得我們想要的內容。點開一個dd的標籤(黑色三角),會出來一個a標籤,a裏面的內容有一個網址(不全)和一個章節的名字:
第2125章 有誰能夠阻擋我!
這就是我們在這個頁面需要的內容了。細心的會發現,這一章是最新章節,我們可以找到第一章所在的位置:
第一章
我們回到網頁裏,點擊進入第一章,同樣用F12調出代碼窗口,再用同樣的方法定位正文所在的代碼位置:
這裏寫圖片描述
整章內容都在這個div的標籤裏面。
好了,敵情我們已經偵查得差不多了。可以構思我們的策略了。

爬蟲思路

思路非常簡單。我們首先獲得每章節的url,然後根據url訪問每章節頁面,進而抓取正文,最後把所有章節拼接起來。

代碼實現

這裏推薦一個python的開發環境Anaconda。它集成很多python的庫,我們可以少造輪子。而且Anaconda自帶了一個比較不錯的IDE,名字叫做Spyder,界面和Matlab差不多,用來邊寫邊調試腳本非常方便。Pycharm也很不錯,但是變量查看太麻煩,所以我暫時還是用Spyder。
打開Spyder,新建一個python file。
首先引入我們需要的庫:

import requests
from bs4 import BeautifulSoup
import codecs

這裏引入了requests庫,從bs4這個庫裏引入了BeautifulSoup這個類,還引入了一個用來編解碼的codecs庫。

第一步:請求目錄頁內容

response = requests.get('http://www.biqudao.com/bqge7946/')
respone.encoding = 'utf-8'
response = response.text
page = BeautifulSoup(response,'lxml')

第一行是用requests的get方法請求目錄頁。在console裏輸入response會得到Response [200],這是請求成功的意思。如果是別的數字,一般來說是請求失敗。第二行是把response編碼爲utf-8,用以支持中文。第三行的.text把response的內容返回爲文本,第四行用BeautifulSoup把response解析成lxml格式的文檔。

第二步:獲取各章節url

pages = page.select('dd')
links=[]
for p in pages:
    url = 'http://www.biqudao.com'+p['href']
    name = u':'.join(p.text.split())
    chapter = [url,name]
    links.append(chapter)

Beautiful Soup支持大部分的CSS選擇器。在標籤(Tag)或 BeautifulSoup 對象的 .select() 方法中傳入字符串參數,可以獲得我們想要的內容。關於.select的用法,可以參考這裏。這裏我們傳入的參數是’a[style]’,獲得了一個list,這個list裏就是我們感興趣的所有章節的url和章節名!良心站長!
輸出pages的前3個元素

In:pages[:3]
Out: 
[<a href="/bqge7946/4377585.html" style="">第一章 法寶墳墓</a>,
 <a href="/bqge7946/4377586.html" style="">第二章 光幕儀</a>,
 <a href="/bqge7946/4377587.html" style="">第三章 異夢</a>]

接下來提取出每章節的url

links=[ ['http://www.biqudao.com'+p['href'],u':'.join(p.text.split())] for p in pages]

這是一個列表推導式,等同於下面這一大段代碼:

links=[]
for p in pages:
    url = 'http://www.biqudao.com'+p['href']
    name = u':'.join(p.text.split())
    links.append([url,name])

現在我們已經的得到從第一章到最新一章的所有url和對應的章節名稱了。接下來我們就用這些url來獲取我們想要的正文吧。

第三步:獲取章節正文並合併爲全本

首先我們建一個空字符串,用於存儲小說正文。

novel  = u''

然後我們用一個for循環獲取所有章節並拼接在一起。

for link in links:
    response = requests.get(link[0])
    response.encoding = 'utf-8'
    response = response.text
    soup = BeautifulSoup(response)
    content = soup.select('#content')[0].get_text()    
    #由於正文末尾有一些我們不需要的字符,用這種切片的方式去除
    content=link[1]+content[:-16]
    novel = novel+content
    #去除正文中破壞結構的轉義字符\n和\t
    novel=u'\n\t'.join(novel.split())

這段代碼就不再多做解釋了。不清楚的可以參看bs4的教程

最後一步:保存

上面那段代碼會運行一段時間。最終獲得的nuvel就是我們所要的小說全文。接下來我們就把它保存下來:

txt = codecs.open(u'PATH/修真四萬年.txt','wb','utf-8')
txt.write(novel)
txt.close()

PATH是我們希望小說保存在哪裏的路徑。

大功告成!

完整代碼

見我的Github

import requests
from bs4 import BeautifulSoup
import codecs
#讀取目錄頁url和data
cont = requests.get('http://www.biqudao.com/bqge7946/')
cont.encoding = 'utf-8'
cont = cont.text
page = BeautifulSoup(cont,'lxml')

pages = page.select('a[style]')
links=[ ['http://www.biqudao.com'+p['href'],u':'.join(p.text.split())] for p in pages]
novel=u''
for link in links:
    response = requests.get(link[0])
    response.encoding = 'utf-8'
    response = response.text
    soup = BeautifulSoup(response)
    content = soup.select('#content')[0].get_text()
    content=lins[1]+content[:-16]
    novel = novel+content
    novel=u'\n\t'.join(novel.split())
txt = codecs.open(u'修真四萬年.txt','wb','utf-8')
txt.write(novel)
txt.close()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章