Python爬蟲零基礎(chǔ)實(shí)例---爬取小說吧小說內(nèi)容到本地

Python爬蟲實(shí)例--爬取百度貼吧小說

寫在前面

本篇文章是我在簡書上寫的第一篇技術(shù)文章,作為一個(gè)理科生,能把僅剩的一點(diǎn)文筆拿出來獻(xiàn)丑已是不易,希望大家能在指教我的同時(shí)給予我一點(diǎn)點(diǎn)鼓勵(lì),謝謝。


一.介紹

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

這個(gè)項(xiàng)目是我曾初學(xué)python之時(shí)做的一個(gè)練習(xí)項(xiàng)目,現(xiàn)在再重新拿出來作為一篇開篇簡作獻(xiàn)給大家。閱讀本文不需要有很高的python技術(shù)或者爬蟲知識(shí),只要略微有些python基礎(chǔ)就可以,在一些地方,我會(huì)盡量給大家詳細(xì)備注。

二.環(huán)境

Python版本:Python2.7

IDE:Pycharm2017

第三方庫:
urllib2 模塊:urllib2是python的一個(gè)獲取url(Uniform ResourceLocators,統(tǒng)一資源定址器)的模塊。
re模塊:Python 的 re模塊(Regular Expression 正則表達(dá)式)提供各種正則表達(dá)式的匹配操作

注:以上兩個(gè)第三方庫在Python2.7中自帶,因此不用再安裝。本案例在使用第三方庫函數(shù)時(shí)會(huì)詳細(xì)介紹用法與功能。

三.案例

1.導(dǎo)入模塊

首先創(chuàng)建一個(gè)python文件,我這里為main.py(文件名隨意取,本案例只使用一個(gè)py文件)。本案例中我們使用兩個(gè)模塊urllib2re,因此首先導(dǎo)入模塊.

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

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

# coding = utf-8

2.理解思路

我個(gè)人在做項(xiàng)目前習(xí)慣先分析項(xiàng)目,將步驟一步一步的寫出來,然后去慢慢實(shí)現(xiàn)。

  1. 找到目標(biāo)網(wǎng)頁,獲取源碼
  2. 匹配標(biāo)題,獲取標(biāo)題內(nèi)容
  3. 匹配正文,獲取正文內(nèi)容
  4. 去除或者替換雜項(xiàng)

OK,這里思路就是這樣的一個(gè)四部曲。現(xiàn)在來看一下代碼框架。

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


#這是本案例的類
class Novel:

    baseUrl = '' #這里是你要爬取的小說的鏈接
    #這個(gè)方法用來獲取網(wǎng)頁源碼
    def getPage(self):
        pass
    #這個(gè)方法用來獲取小說標(biāo)題并保存
    def getTitle(self):
        pass
    #這個(gè)方法用來獲取小說文本并保存
    def getText(self):
        pass

#這是一個(gè)測試模塊,執(zhí)行本文件時(shí)的入口
if __name__ == '__main__':
    n = Novel() #實(shí)例化一個(gè)類
    #print n.getPage() #獲取網(wǎng)頁源碼
    n.getTitle()#獲取小說題目
    n.getText() #獲取小說內(nèi)容

現(xiàn)在開始一步步實(shí)現(xiàn)功能:

1.找到目標(biāo)網(wǎng)頁,獲取網(wǎng)頁源碼

我在小說吧精品貼里面隨便翻了一個(gè)帖子,就以這個(gè)帖子為案例。
【原創(chuàng)】《貧僧為什么不可以談戀愛》(古言,長篇)
現(xiàn)在我們需要爬取這個(gè)帖子中小說內(nèi)容,我們需要直接將它的鏈接地址給baseUrl嗎?當(dāng)然不是
爬取一個(gè)帖子上的小說,實(shí)際上是去爬取該小說作者的所發(fā)表的內(nèi)容,所以我們還需要進(jìn)行一步操作,只看樓主

這里寫圖片描述

我們所需要的鏈接地址,就是當(dāng)前這個(gè)了

https://tieba.baidu.com/p/4973334088?see_lz=1
注意一定是要只看樓主后的鏈接,比之前的會(huì)多出個(gè)?see_lz=1

現(xiàn)在就將你得到的鏈接地址賦值給baseUrl

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

接下來我們來獲取這個(gè)網(wǎng)頁的源碼,也就是實(shí)現(xiàn)getPage函數(shù):

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

本函數(shù)現(xiàn)實(shí)通過以基本鏈接baseUrl為參數(shù)實(shí)現(xiàn)了一個(gè)Request請(qǐng)求類的對(duì)象request。接著通過urlopen去執(zhí)行request請(qǐng)求對(duì)象打開目標(biāo)網(wǎng)頁。接著通過調(diào)用read`函數(shù)獲取目標(biāo)網(wǎng)頁的源碼,并作為函數(shù)返回值返回.
返回的網(wǎng)頁源碼,可在測試代碼塊中通過調(diào)用輸出本函數(shù)查看。
例:

if __name__ == '__main__':
    n = Novel() #實(shí)例化一個(gè)類
    print n.getPage() #獲取網(wǎng)頁源碼

2.匹配標(biāo)題,獲取標(biāo)題內(nèi)容

首先先亮出我的代碼:

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

注意:代碼錯(cuò)行要在行末加\號(hào)
例如:

print 'hello   \
          world'

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

在正則表達(dá)式中的含義:
.:匹配任意字符,除了換行符
:匹配前面的子表達(dá)式零次或多次
?:匹配前面的子表達(dá)式零次或一次
():標(biāo)記一個(gè)子表達(dá)式的開始和結(jié)束位置。子表達(dá)式可以獲取供以后使用
(.>)
:匹配所有滿足條件的表達(dá)式并作為結(jié)果集返回

re.compile函數(shù)是將正則表達(dá)式的字符串形式編譯為Pattern實(shí)例,然后使用Pattern實(shí)例處理文本并獲得匹配結(jié)果,其中字符串前的r是為了防止轉(zhuǎn)義
findall(正則表達(dá)式,文本) ------將滿足的匹配結(jié)果以list列表返回
用迭代拿到items中的主題名后在將之寫入名為novel.txt的文件中

3.匹配正文,獲取小說正文內(nèi)容

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

class="d_post_content j_d_post_content "> (.*?)</div><br>
實(shí)現(xiàn)函數(shù)如下:

    #這個(gè)方法用來獲取小說文本并保存
    def getText(self):
        html = self.getPage()
        reg = re.compile(r'class="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('\n'+i)
            f.close()

如同匹配主題一樣的步驟匹配正文,但是并沒有結(jié)束,因?yàn)槟銜?huì)在你的結(jié)果中看到這樣


雜亂無章

對(duì)沒錯(cuò)。雜亂無章的正文,中間還有HTML中的<a>,<img>,<br>等標(biāo)簽
我們接著來處理

4.替換或者去出雜項(xiàng)

re模塊中有sub函數(shù)

sub(被替換的內(nèi)容,替換的內(nèi)容,需要處理的文本) ---- 返回處理后的文本

現(xiàn)在我們將雜項(xiàng)全部給替換成空字符吧""
當(dāng)然<br>標(biāo)簽可以直接調(diào)用字符串中的replace函數(shù)替換成換行符\n

修改后的函數(shù)模塊如下:

    def getText(self):
        html = self.getPage()
        reg = re.compile(r'class="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>','\n')
            print i
            f = open('novel.txt','a') #a 追加模式
            f.write('\n'+i)
            f.close()

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

案例結(jié)束:
將完整代碼貼給大家:

# -*- coding: utf-8 -*-

import urllib2 , re

#這是本案例的類
class Novel:
    baseUrl = 'https://tieba.baidu.com/p/4973334088?see_lz=1' #這里是你要爬取的小說的鏈接
    #這個(gè)方法用來獲取網(wǎng)頁源碼
    def getPage(self):
        request = urllib2.Request(self.baseUrl) 
        response = urllib2.urlopen(request).read()
        return response
    #這個(gè)方法用來獲取小說標(biāo)題并保存
    def getTitle(self):
        html = self.getPage() #調(diào)用獲取源碼
        #r防止轉(zhuǎn)義
        reg = re.compile(r'<h3 class="core_title_txt pull-left text-overflow  " title="(.*?)" style=')
        items = re.findall(reg,html)
        for item in items:
            print item
            f = open('novel.txt','w')
            f.write('標(biāo)題===>>>'+item)
            f.close()

    #這個(gè)方法用來獲取小說文本并保存
    def getText(self):
        html = self.getPage()
        reg = re.compile(r'class="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>','\n')
            print i
            f = open('novel.txt','a') #a 追加模式
            f.write('\n'+i)
            f.close()
#這是一個(gè)測試代碼塊,執(zhí)行本文件時(shí)的入口
if __name__ == '__main__':
    n = Novel() #實(shí)例化一個(gè)類
    #print n.getPage() #獲取網(wǎng)頁源碼
    n.getTitle()#獲取小說題目
    n.getText() #獲取小說內(nèi)容

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




撒花撒花撒花,從11點(diǎn)寫到了將近2點(diǎn),終于搞定了。
因?yàn)槭堑谝淮螌懠夹g(shù)文寫這么長時(shí)間,所以,,后面耐心不太好,導(dǎo)致后半篇文章質(zhì)量太差勁。
不過,終究是先搞完了一篇哪,簡書處女技術(shù)作。。
至于文章瑕疵,我在白天會(huì)花時(shí)間去修改,也希望大家給我多多提意見。我呢~爭取展現(xiàn)給大家的是一篇更加完美的文章。

夜了,晚安。


看在作者君這么辛苦的份上,求您點(diǎn)個(gè)喜歡吧!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,420評(píng)論 25 708
  • # Python 資源大全中文版 我想很多程序員應(yīng)該記得 GitHub 上有一個(gè) Awesome - XXX 系列...
    aimaile閱讀 26,578評(píng)論 6 427
  • 那一院靜默的僧人 在我眼中是一本平裝的故事書 每件青衣之下 都曾是深邃而遙遠(yuǎn)的故事 走出廟門 我看見滾滾紅塵 那是...
    徐曙光閱讀 268評(píng)論 0 2
  • 各位爸爸媽媽們,大家好! 先表揚(yáng)孩子們今天的表現(xiàn),今天孩子們?nèi)紟Я思t領(lǐng)巾了,這真是開學(xué)以來第一回啊,值得表揚(yáng),說...
    陽光溫溫閱讀 296評(píng)論 2 4
  • 原文鏈接:http://wyb0.com/posts/docker-image-and-container 操作系...
    cws閱讀 774評(píng)論 0 0