標籤:

Python爬蟲零基礎實例---爬取小說吧小說內容到本地

Python爬蟲實例--爬取百度貼吧小說

寫在前面

本篇文章是我在簡書上寫的第一篇技術文章,作為一個理科生,能把僅剩的一點文筆拿出來獻醜已是不易,希望大家能在指教我的同時給予我一點點鼓勵,謝謝。

一.介紹

小說吧:顧名思義,是一個小說愛好者的一個聚集地。當然這不是重點,重點是,我們要做的事情便是將小說吧中以帖子連載形式的小說用爬蟲給拿下來保存到本地

這個項目是我曾初學python之時做的一個練習項目,現在再重新拿出來作為一篇開篇簡作獻給大家。閱讀本文不需要有很高的python技術或者爬蟲知識,只要略微有些python基礎就可以,在一些地方,我會盡量給大家詳細備註。

二.環境:

Python版本:Python2.7

IDE:Pycharm2017

第三方庫:

urllib2 模塊:urllib2是python的一個獲取url(Uniform ResourceLocators,統一資源定址器)的模塊。

re模塊:Python 的 re模塊(Regular Expression 正則表達式)提供各種正則表達式的匹配操作

註:以上兩個第三方庫在Python2.7中自帶,因此不用再安裝。本案例在使用第三方庫函數時會詳細介紹用法與功能。

三.案例

1.導入模塊

首先創建一個python文件,我這裡為main.py(文件名隨意取,本案例只使用一個py文件)。本案例中我們使用兩個模塊urllib2和re,因此首先導入模塊.

# -*- coding:utf-8 -*-import urllib2 , re

當然,python2版本需要在開頭聲明編碼格式。除了上述代碼的寫法以外,也可以這樣聲明

# coding = utf-8

2.理解思路

我個人在做項目前習慣先分析項目,將步驟一步一步的寫出來,然後去慢慢實現。

  1. 找到目標網頁,獲取源碼

  2. 匹配標題,獲取標題內容

  3. 匹配正文,獲取正文內容

  4. 去除或者替換雜項

OK,這裡思路就是這樣的一個四部曲。現在來看一下代碼框架。

# -*- coding:utf-8 -*-import urllib2 , re#這是本案例的類class Novel: baseUrl = #這裡是你要爬取的小說的鏈接 #這個方法用來獲取網頁源碼 def getPage(self): pass #這個方法用來獲取小說標題並保存 def getTitle(self): pass #這個方法用來獲取小說文本並保存 def getText(self): pass#這是一個測試模塊,執行本文件時的入口if __name__ == __main__: n = Novel() #實例化一個類 #print n.getPage() #獲取網頁源碼 n.getTitle()#獲取小說題目 n.getText() #獲取小說內容

現在開始一步步實現功能:

1.找到目標網頁,獲取網頁源碼

我在小說吧精品貼裡面隨便翻了一個帖子,就以這個帖子為案例。

【原創】《貧僧為什麼不可以談戀愛》(古言,長篇)

現在我們需要爬取這個帖子中小說內容,我們需要直接將它的鏈接地址給baseUrl嗎?當然不是

爬取一個帖子上的小說,實際上是去爬取該小說作者的所發表的內容,所以我們還需要進行一步操作,只看樓主

這裡寫圖片描述

我們所需要的鏈接地址,就是當前這個了

【圖片】【原創】《貧僧為什麼不可以談戀愛》(古言,長篇)≮江山【小說吧】_百度貼吧

注意一定是要只看樓主後的鏈接,比之前的會多出個?see_lz=1

現在就將你得到的鏈接地址賦值給baseUrl

baseUrl = https://tieba.baidu.com/p/4973334088?see_lz=1

接下來我們來獲取這個網頁的源碼,也就是實現getPage函數:

def getPage(self): request = urllib2.Request(self.baseUrl) response = urllib2.urlopen(request).read() return response

本函數現實通過以基本鏈接baseUrl為參數實現了一個Request請求類的對象request。接著通過urlopen去執行request請求對象打開目標網頁。接著通過調用read`函數獲取目標網頁的源碼,並作為函數返回值返回.

返回的網頁源碼,可在測試代碼塊中通過調用輸出本函數查看。

例:

if __name__ == __main__: n = Novel() #實例化一個類 print n.getPage() #獲取網頁源碼

2.匹配標題,獲取標題內容

首先先亮出我的代碼:

def getTitle(self): html = self.getPage() #調用獲取源碼 #r防止轉義 reg = re.compile(r<h3 class="core_title_txt pull-left text-overflow " title="(.*?)" stylex=) items = re.findall(reg,html) for item in items: print item f = open(novel.txt,w) f.write(標題===>>>+item) f.close()

注意:代碼錯行要在行末加``號

例如:

print hello world

首先我們在網頁源碼中尋找包含小說主題部分的源碼,可以通過Ctrl+F搜索。查找到<div>^=……中間包含小說主題<.div>這麼一長串的包含小說主題的代碼。只要將主題部分全部置換為(.*?)號就可以了。

在正則表達式中的含義:

.:匹配任意字元,除了換行符

:匹配前面的子表達式零次或多次

*
?:匹配前面的子表達式零次或一次 ():標記一個子表達式的開始和結束位置。子表達式可以獲取供以後使用 (.>)*:匹配所有滿足條件的表達式並作為結果集返回

re.compile函數是將正則表達式的字元串形式編譯為Pattern實例,然後使用Pattern實例處理文本並獲得匹配結果,其中字元串前的r是為了防止轉義。

findall(正則表達式,文本) ------將滿足的匹配結果以list列表返回

用迭代拿到items中的主題名後在將之寫入名為novel.txt的文件中

3.匹配正文,獲取小說正文內容

匹配正文,與匹配標題相差無幾,首先是尋找以樓主發表的第一層為例的代碼<div>段,從中獲取可以作為正則匹配的語句。並將正文部分改為(.*?)

如下

class="d_post_content j_d_post_content "> (.*?)</div><br>

實現函數如下:

#這個方法用來獲取小說文本並保存 def getText(self): html = self.getPage() reg = re.compile(rclass="d_post_content j_d_post_content "> (.*?)</div><br>,re.S)#匹配換行符 req = re.findall(reg,html) for i in req: print i f = open(novel.txt,a) #a 追加模式 f.write(
+i) f.close()

如同匹配主題一樣的步驟匹配正文,但是並沒有結束,因為你會在你的結果中看到這樣

雜亂無章

對沒錯。雜亂無章的正文,中間還有HTML中的<a>,<img>,<br>等標籤

我們接著來處理

4.替換或者去出雜項

re模塊中有sub函數

sub(被替換的內容,替換的內容,需要處理的文本) ---- 返回處理後的文本

現在我們將雜項全部給替換成空字元吧""吧

當然<br>標籤可以直接調用字元串中的replace函數替換成換行符

修改後的函數模塊如下:

def getText(self): html = self.getPage() reg = re.compile(rclass="d_post_content j_d_post_content "> (.*?)</div><br>,re.S)#匹配換行符 req = re.findall(reg,html) for i in req: removeA = re.compile(<a.*?>|</a>) removeIMG = re.compile(<img.*?>) removeHTTP = re.compile(<http.*?.html>) i = re.sub(removeA,"",i) i = re.sub(removeIMG,"",i) i = re.sub(removeHTTP,"",i) i = i.replace(<br>,
) print i f = open(novel.txt,a) #a 追加模式 f.write(
+i) f.close()

注意:記得在打開文件函數中,對文件的操作方式為a追加模式

案例結束:

將完整代碼貼給大家:

# -*- coding: utf-8 -*-import urllib2 , re#這是本案例的類class Novel: baseUrl = https://tieba.baidu.com/p/4973334088?see_lz=1 #這裡是你要爬取的小說的鏈接 #這個方法用來獲取網頁源碼 def getPage(self): request = urllib2.Request(self.baseUrl) response = urllib2.urlopen(request).read() return response #這個方法用來獲取小說標題並保存 def getTitle(self): html = self.getPage() #調用獲取源碼 #r防止轉義 reg = re.compile(r<h3 class="core_title_txt pull-left text-overflow " title="(.*?)" stylex=) items = re.findall(reg,html) for item in items: print item f = open(novel.txt,w) f.write(標題===>>>+item) f.close() #這個方法用來獲取小說文本並保存 def getText(self): html = self.getPage() reg = re.compile(rclass="d_post_content j_d_post_content "> (.*?)</div><br>,re.S)#匹配換行符 req = re.findall(reg,html) for i in req: removeA = re.compile(<a.*?>|</a>) removeIMG = re.compile(<img.*?>) removeHTTP = re.compile(<http.*?.html>) i = re.sub(removeA,"",i) i = re.sub(removeIMG,"",i) i = re.sub(removeHTTP,"",i) i = i.replace(<br>,
) print i f = open(novel.txt,a) #a 追加模式 f.write(
+i) f.close()#這是一個測試代碼塊,執行本文件時的入口if __name__ == __main__: n = Novel() #實例化一個類 #print n.getPage() #獲取網頁源碼 n.getTitle()#獲取小說題目 n.getText() #獲取小說內容

以後想要獲取小說吧哪個小說,只要將baseUrl的地址修改一下就好咯。

推薦閱讀:

Python裡面 str[::-1] 使得字元串翻轉的原理是什麼,為什麼是兩個冒號放一起?
現在做python web開發一個小項目,無從下手,望各位老師和同學給引導一下,提提意見,謝謝!?
隨機數生成
python里函數作為返回值如何進行比較?
從零開始寫Python爬蟲 --- 2.3 爬蟲實踐:天氣預報&數據存儲

TAG:Python |