【爬蟲】Yhen手把手帶你用python爬小說網站,全網打盡,想看就看!(這可能會是你看過最詳細的教程)

以下內容爲本人原創,歡迎大家觀看學習,禁止用於商業用途,轉載請說明出處,謝謝合作!

  大噶好!我是python練習時長一個月的Yhen,今天我學習了爬取小說網站,特別感謝六星教育python學院,我就是在這裏學的,老師講的挺好挺仔細的,以下內容都是基於我在課堂上學到的,大家有興趣可以到騰訊課堂報名聽課,都是免費的。
  接下來我把經驗分享給大家,作爲小白的我們,在寫代碼時肯定會遇到一些bug,下面有我敲代碼過程中出現的錯誤以及我的解決方法,希望可以幫助到大家!最後的源碼也會給大家!因爲比較詳細所以內容可能較多,大家如果只想知道結果,可以直接看源碼。
  好啦咱們說幹就幹,敲起來!


今天我們我們要爬取的小說網站是“千千小說網”
url :https://www.qqxsw.co/


我們今天就做的是把首頁第一本書《牧龍師》裏面的內容爬下來
在這裏插入圖片描述
ok,清楚了需求,那我們馬上開動起來吧!

我們首先先對小說的主頁頁面進行請求

# 導入爬蟲包
import requests
# 小說頁面的url
url = 'https://www.qqxsw.co/book_107838/'
# 對小說頁面進行請求
response =requests.get(url).text
# 打印小說頁面源碼信息
print(response)

我們滿心歡喜地執行上面的代碼
我們得到了一堆數據,說明我們請求成功啦!
在這裏插入圖片描述
但是…有沒有發現上面的數據有點奇怪呢?
是的…他出現了亂碼

像這樣的數據,就是出現了中文亂碼
在這裏插入圖片描述

出現這種情況的原因是因爲頁面的編碼格式是“GBK”格式,而我們爬下來的數據默認是“utf-8”,所以和我們頁面編碼不一致而導致的。
關於“ignore”一開始我也不懂,
百度得知:因爲decode的函數原型是decode([encoding], [errors=‘strict’]),可以用第二個參數控制錯誤處理的策略,默認的參數就是strict,代表遇到非法字符時拋出異常;如果設置爲ignore,則會忽略非法字符;
在這裏插入圖片描述
所以我只要把請求的頁面數據解碼成“gbk”格式即可
修改後的代碼如下

response =requests.get(url).content.decode("gbk","ignore")

我們再來看看解碼後的打印結果
在這裏插入圖片描述
登登登登!是不是一切正常呢!嘻嘻嘻

我們已經成功獲取了頁面的數據
接下來就要定位到頁面裏的每一個章節的按鈕

首先我們按f12進入我們的開發者頁面
按照下圖操作
在這裏插入圖片描述
再點擊定位到這裏
在這裏插入圖片描述
於是我們就得知了這個元素在頁面中的位置
在這裏插入圖片描述
然後我們要用到一個叫做xpath的擴展工具,我用的是谷歌瀏覽器,xpath的安裝是需要導入的。
可參考:https://blog.csdn.net/yhnobody/article/details/81030436

安裝後以後,我們打開xpath
在這裏插入圖片描述
首先我們看控制檯
剛剛我們定位到第一章的按鈕位置是在
div標籤下的dl標籤下的dd標籤下面的a
所以對應我們在xpath上輸入//div/dl/dd/a
這裏解釋一下//是跨節點操作
然後在右邊看到我們的resuits,嘿嘿,成功得到我們想要的所有入口章節的信息

得到了這個位置信息後
接下來繼續敲代碼

首先導入etree包,因爲我們python是不能識別xpath的,所以要導包
注意這個包是自己要安裝的哦

# 從lxml中導入etree包
from lxml import etree

獲取HTML數據和通過xpath提取數據

# 獲取HTML數據
dom =etree.HTML(response)
# 通過xpath提取數據
html =dom.xpath("//div/dl/dd/a/")

我們把結果html打印一下
在這裏插入圖片描述
得到了這麼一大串的對象數據
但是現在的數據都擠在了一塊了,我們要把數據一 一取出來怎麼辦呢?
用到for 循環

for x in html:
    print(x)

這個循環的意思就是,從html中把數據一 一提取到x裏面去

我們來看下打印結果
在這裏插入圖片描述
看!現在是不是我們的對象都乖乖的排好隊了呢

我們剛剛獲取的是對象數據,如果想進一步獲取網址
要再用一次xpath
還記得這個頁面嘛?
我們的小說的章節都在這個href裏面了
在這裏插入圖片描述
我們再用一次xpath獲取

# 獲取小說頁面網址
    a=["url"] = x.xpath("./@href")[0]

打印下結果看看
在這裏插入圖片描述
歐耶,成功獲取了
emm…不過怎麼怪怪的,和我們平時看到的網址不太一樣啊
嗯,沒錯,少了前面的一段
我們來把他們拼接起來

a = url + x.xpath("./@href")[0]

打印一下
在這裏插入圖片描述
perfect!

然後我們要把這些數據裝進字典裏

# 創建一個新字典
    dic = {}   
    # 獲取小說頁面網址
    dic["url"] = url + x.xpath("./@href")[0]

接下來提取章節名也是同樣的方法,
./text()的作用是提取數據裏的文本數據

# 提取章節名
    dic["name"] = x.xpath("./text()")[0]

看看成果
在這裏插入圖片描述
我們想要的數據已經一一對應起來啦

到這裏我們已經完成一大半啦
接下來要做的就是對章節網址進行請求
然後提取裏面的小說數據

我們來對章節的網址進行請求
並查看請求信息

response = requests.get(dic["url"]).content.decode("gbk", "ignore")
    print(response)

在這裏插入圖片描述
成功獲得章節頁裏面的數據啦

那麼我們要怎樣才能把我們網頁裏面的小說文字提取出來呢
還是要用到我們的老朋友xpath
在這裏插入圖片描述
一樣的方法,先定位到小說文字元素,找到元素所在的位置
然後在我們的xpath上輸入//div[@class=‘zhangjieTXT’]
需要注意的一個就是別忘了 'zhangjieTXT’這裏是有個引號的,如果沒有了,就會定位不準確,導致得到很多我們不想要的數據哦…

這裏的操作和第一次時一樣的

doc = etree.HTML(response)
    HTML = doc.xpath('//div[@class="zhangjieTXT"]/text()')
    print(HTML)

在這裏插入圖片描述
到這裏就快要完成了

遍歷小說數據

    for v in HTML:
        print(v)

在這裏插入圖片描述
成功爬到了我們的小說文字
但是文字間的間隔太大了
不知道你看着爽不爽,反正我看着是很不爽
所以,安排!

先上圖
在這裏插入圖片描述
哈哈哈哈哈這樣的是不是舒服多了
怎麼實現呢

    for v in HTML:
        # 頭尾去空格
        novel = v.strip()

strip()把頭尾的空格去掉就可以啦!

這裏給大家拓展一下:
去左邊的空格lstrip()
去右邊的空格rstrip()

接下來我們把爬到的數據保存到本地,就完成啦!

# 打開“小說”文件夾,將小說的章節名作爲保存的文件名,以“a”追加的方式,編碼成“utf-8”
        f = open("小說/" + dic['name'] + ".txt", "a", encoding="utf-8")
        # 寫入小說數據,\n是換行符
        f.write(novel + "\n")
        #關閉讀寫文件
        f.close()

來看看運行的結果
在這裏插入圖片描述
在這裏插入圖片描述
大功告成!撒花完結!!!

最後附上源碼

import requests
from lxml import etree

# 章節菜單網址
url = "https://www.qqxs.cc/xs/116/116087/"
response = requests.get(url).content.decode("gbk", "ignore")

# 獲取頁面的HTML數據
dom = etree.HTML(response)
html = dom.xpath("//div/dl/dd/a")

for x in html:
    # 創建一個新字典
    dic = {}
    # 獲取小說章節名
    dic["name"] = x.xpath("./text()")[0]
    # 提取小說章節url
    dic["url"] = url + x.xpath("./@href")[0]
    # print(dic)
    # 對章節網址進行請求
    response = requests.get(dic["url"]).content.decode("gbk", "ignore")
    # print(response)


    # 提取頁面中的HTML數據
    doc = etree.HTML(response)
    # 提取小說文字數據
    HTML = doc.xpath('//div[@class="zhangjieTXT"]/text()')

    # 遍歷小說數據
    for v in HTML:
        # 頭尾去空格
        novel = v.strip()
        # 打開“小說”文件夾,將小說的章節名作爲保存的文件名,以“a”追加的方式,編碼成“utf-8”
        f = open("小說/" + dic['name'] + ".txt", "a", encoding="utf-8")
        # 寫入小說數據,\n是換行符
        f.write(novel + "\n")
        #關閉讀寫文件
        f.close()

Yhen有感

  說實話,寫教程還真挺累的哈哈哈,也深切體會到之前大佬們寫教程的不易了。但當我寫完之後,我是真的滿滿的成就感,原來我也能自己寫這種博客,也能把我的知識和大家分享,雖然我懂的不多,但是我願意把我會的都和大家分享!
  寫這個教程時,我也發現了很多問題,我自己嘗試解決問題時就是我在學習的一個過程。比如老師演示的時候,爬下來的數據是沒有空行的,但是我爬下來卻有很多空行,我就得想辦法解決,上網查到的消除空行的方法都是要寫入後再對txt文件進行處理,很麻煩。我把問題發到羣上後,有同學說可以用strip()去空行的方法,我試了一下,果然OK!感謝!
  我在寫代碼時也和老師上課講的代碼作比較,想想老師用的方法我能否換個方法來實現同樣的效果呢,比如說網址拼接那裏我是直接拼接的…老師有沒有一些步驟是不必要的呢?有,比如老師上課時把字典裏的數據再裝進列表裏,然後再用for循環遍歷…我把結果打印出來,其實就是字典裏的數據,所以還何必多此一舉,裝進去再拿出來呢?而且後面完全是用不到這個列表裏的數據的。
  很開心能在這裏給大家分享我的經驗
我還只是個小白,如果有什麼寫的不好,寫錯了的地方歡迎大家指正,有什麼問題都可以在評論區提出哦!我們一起共同進步!
  希望大家能夠喜歡這篇文章,以後我也會繼續出其他的教程,把我的經驗分享給大家!謝謝
  如果可以的話,可以點個贊鼓勵下小弟嘛?加個關注更好哦哈哈嘻嘻
  我是Yhen,我們下次見

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章