python爬蟲(chóng)入門(mén)(1):爬萬(wàn)本書(shū)籍

最近閑的無(wú)聊,想爬點(diǎn)書(shū)看看。 于是我選擇了這個(gè)網(wǎng)站雨楓軒。

STEP1.分析網(wǎng)站


一開(kāi)始我想通過(guò)一篇文章引用的鏈接,將書(shū)爬完,后來(lái)發(fā)現(xiàn)并不需要這樣做。比如我們可以打開(kāi)人生哲學(xué)這個(gè)欄目。


如圖1所示,會(huì)把頁(yè)面數(shù)全列出來(lái)。
并且這個(gè)url

http://txt.rain8.com/txtzx/list_93_1.html

也非常的有規(guī)律。
可以看出是由

'http://txt.rain8.com/txt'+'欄目名稱(chēng)'+'list_欄目編號(hào)_頁(yè)數(shù).html'

組成的。
知道了這點(diǎn)后,我們就能輕松的把網(wǎng)站爬完了。

STEP2.初始化

首先我們來(lái)理清思路。

這是我們需要的庫(kù)

import requests
import re
import os

其實(shí)這個(gè)項(xiàng)目用urllib2也能完成。
我們首先來(lái)初始化,在self.urls里,我們定義一些需要fetch的欄目。(比如言情,恐怖仙俠之類(lèi)的書(shū)就可以跳過(guò))。然后寫(xiě)一些正則表達(dá)式,供其他的method使用。

class fetchBook:
    def __init__(self):
        self.header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0'}
        self.urls = [
                     'http://txt.rain8.com/txtgw/',
                     'http://txt.rain8.com/txtzj/',
                     'http://txt.rain8.com/txtzx/',
                     'http://txt.rain8.com/txtsh/'
                     ]
        self.rePageIndex = re.compile('list_\d+_\d+.html')#得到欄目編號(hào)
        self.rePageCount = re.compile('<strong>\d+</strong>')#得到頁(yè)面數(shù)目
        self.reDownloadGet1 = re.compile('href=.http://txt.rain8.com/plus/xiazai_yfx.php?[^>]+')#得到下載鏈接
        self.reGetTitle = re.compile('<title>.+</title>')#得到標(biāo)題
        self.reGetAuthor = re.compile("</small><span>[^>]+")#得到作者名稱(chēng)
        self.reBookGetNew = re.compile('')#得到書(shū)籍鏈接
        self.reBookGetOld = re.compile('')
        self.cnt = 0

STEP3.獲取所有的頁(yè)面

我們可以查看人生哲學(xué)源代碼??梢哉业娇偣驳捻?yè)數(shù)。


然后我們就能得到每一頁(yè)的數(shù)據(jù)。
代碼如下

    def viewAllPage(self,url):
        """
        函數(shù)功能為把該欄目下所有頁(yè)面全過(guò)一遍。
        """
        req = requests.get(url,headers = self.header)
        pageIndex = self.rePageIndex.findall(req.text)[0][5:7]
        pageCount = int(self.rePageCount.findall(req.text)[0][8:-9])
        urlToFetch = [url,'list_',pageIndex,'_','1','.html']
        foldname = self.reGetTitle.findall(req.text)[0][7:]
        foldname = foldname.encode('unicode_escape').decode('string_escape')
        foldname = foldname.split('|')[0]
        self.createDir(foldname)
        for page in range(1,pageCount+1):
            urlToFetch[4] = str(page)
            url_to_get = ''.join(urlToFetch)#得到所有頁(yè)面的url

STEP4.得到下載鏈接

然后我們用上面寫(xiě)好的正則表達(dá)式,來(lái)匹配她的下載鏈接。

    def fetchDownloadUrl(self,bookurl):
        req = requests.get(bookurl,headers = self.header)
        result = self.reDownloadGet1.findall(req.text)
        result = result[0][6:-17]
        authorname = self.reGetAuthor.findall(req.text)[0][14:-6].encode('unicode_escape').decode('string_escape')
        req = requests.get(result,headers = self.header)
        bookname = self.reGetTitle.findall(req.text)[0][7:-24]
        downloadurl = self.reDownloadGet1.findall(req.text)[0][6:-17]
        return downloadurl,bookname,authorname

STEP5.下載

下載的時(shí)候,由于該網(wǎng)站下載的書(shū)都是rar格式的。所以我們只要用二進(jìn)制的方式寫(xiě)就可以了。
我們調(diào)用

self.req = requests.get(downloadUrl,headers = self.header)

然后

f = open(posi+'/'+bookname+'.rar','wb')

就可以寫(xiě)進(jìn)去了。

STEP6.編碼問(wèn)題

之前一直被python的編碼問(wèn)題搞的頭大,這次又遇見(jiàn)了。于是找了點(diǎn)資料看了看。
因?yàn)閜ython工作使用的編碼是unicode,如果要在編碼間進(jìn)行轉(zhuǎn)化,推薦要先decode成unicode,然后再encode成別的編碼。
然后我在爬內(nèi)容的過(guò)程中碰到了這個(gè)問(wèn)題:

s = u'\xb9\xc5\xca\xab\xb4\xca\xc3\xfb\xd6\xf8'

\xb9這樣的很明顯應(yīng)該是gbk編碼。而python卻在字符串前加了個(gè)u。然后我對(duì)這串字符encode還是decode都會(huì)報(bào)錯(cuò)。或者打印出來(lái)亂碼。
經(jīng)過(guò)查閱資料,我找到了一種解決辦法

s.encode('unicode_escape').decode('string_escape')

經(jīng)過(guò)這樣處理后

>>> print repr(s)
>>> '\xb9\xc5\xca\xab\xb4\xca\xc3\xfb\xd6\xf8'

很明顯就恢復(fù)了正常。這時(shí)我們只要decode('gb2312')就能轉(zhuǎn)換成unicode編碼了。

STEP7.結(jié)果展示

github地址
喜歡的可以點(diǎn)一下喜歡。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 可以看我的博客 lmwen.top 或者訂閱我的公眾號(hào) 簡(jiǎn)介有稍微接觸python的人就會(huì)知道,python中...
    ayuLiao閱讀 3,388評(píng)論 1 5
  • 字符集和編碼簡(jiǎn)介 在編程中常??梢砸?jiàn)到各種字符集和編碼,包括ASCII,MBCS,Unicode等字符集。確切的說(shuō)...
    蘭山小亭閱讀 9,079評(píng)論 0 13
  • Python 二三事 面向初學(xué)者介紹Python相關(guān)的一些工具,以及可能遇到的常見(jiàn)問(wèn)題。 最后更新 2013.5....
    hzyido閱讀 67,871評(píng)論 2 42
  • 引言 在這里我假設(shè)你已經(jīng)看完了一篇Python教程,基本熟悉了Python的結(jié)構(gòu)和語(yǔ)法,在命令行下的Python互...
    Programmer客棧閱讀 65,193評(píng)論 0 17

友情鏈接更多精彩內(nèi)容