Python教程:網絡爬蟲快速入門實戰解析

建議: 請在電腦的陪同下,閱讀本文。本文以實戰為主,閱讀過程如稍有不適,還望多加練習。

網絡爬蟲簡介

網絡爬蟲,也叫網絡蜘蛛(Web Spider)。它根據網頁地址(URL)爬取網頁內容,而網頁地址(URL)就是我們在瀏覽器中輸入的網站鏈接。比如:https://www.baidu.com/,它就是一個 URL。

在講解爬蟲內容之前,我們需要先學習一項寫爬蟲的必備技能: 審查元素(如果已掌握,可跳過此部分內容)


1、審查元素

在瀏覽器的地址欄輸入 URL 地址,在網頁處右鍵單擊,找到檢查。(不同瀏覽器的叫法不同,Chrome 瀏覽器叫做檢查,Firefox 瀏覽器叫做查看元素,但是功能都是相同的)


Python教程:網絡爬蟲快速入門實戰解析


Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

我們可以看到,右側出現了一大推代碼,這些代碼就叫做 HTML。什麼是 HTML?舉個容易理解的例子: 我們的基因決定了我們的原始容貌,服務器返回的 HTML 決定了網站的原始容貌。

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

為啥說是 原始容貌

呢?因為人可以整容啊!扎心了,有木有? 那網站也可以"整容"嗎?可以!請看下圖:

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

我能有這麼多錢嗎?顯然不可能。我是怎麼給網站"整容"的呢?就是通過修改服務器返回的 HTML 信息。我們每個人都是"整容大師",可以修改頁面信息。 我們在頁面的哪個位置點擊審查元素,瀏覽器就會為我們定位到相應的 HTML 位置,進而就可以在本地更改 HTML 信息。

再舉個小例子:我們都知道,使用瀏覽器"記住密碼"的功能,密碼會變成一堆小黑點,是不可見的。可以讓密碼顯示出來嗎?可以,只需給頁面"動個小手術"!以淘寶為例,在輸入密碼框處右鍵,點擊檢查。

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

可以看到,瀏覽器為我們自動定位到了相應的 HTML 位置。將下圖中的 password 屬性值改為 text 屬性值(

直接在右側代碼處修改 ):

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

我們讓瀏覽器記住的密碼就這樣顯現出來了:

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

說這麼多,什麼意思呢? 瀏覽器就是作為客戶端從服務器端獲取信息,然後將信息解析,並展示給我們的。 我們可以在本地修改 HTML 信息,為網頁"整容",但是我們修改的信息不會回傳到服務器,服務器存儲的 HTML 信息不會改變。刷新一下界面,頁面還會回到原本的樣子。 這就跟人整容一樣,我們能改變一些表面的東西,但是不能改變我們的基因。

2、簡單實例

網絡爬蟲的第一步就是根據 URL,獲取網頁的 HTML 信息。在 Python3 中,可以使用 urllib.requestrequests 進行網頁爬取。

urllib 庫是 python 內置的,無需我們額外安裝,只要安裝了 Python 就可以使用這個庫。

requests 庫是第三方庫,需要我們自己安裝。這個庫強大好用,所以本文使用 requests 庫獲取網頁的 HTML 信息。requests 庫的 github 地址:https://github.com/requests/requests

(1)requests 安裝

在 cmd 中,使用如下指令安裝 requests:

<code>1pip install requests/<code>

requests 庫的基礎方法如下:

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

官方中文教程地址:http://docs.python-requests.org/zh_CN/latest/user/quickstart.html

requests 庫的開發者為我們提供了詳細的中文教程,查詢起來很方便。本文不會對其所有內容進行講解,摘取其部分使用到的內容,進行實戰說明。

首先,讓我們看下 requests.get()方法,它用於向服務器發起 GET 請求,不瞭解 GET 請求沒有關係。我們可以這樣理解:get 的中文意思是得到、抓住,那這個 requests.get()方法就是從服務器得到、抓住數據,也就是獲取數據。讓我們看一個例子(以 www.gitbook.cn 為例)來加深理解:

<code>1# -*- coding:UTF-8 -*-
2import requests
3
4if __name__ == '__main__':
5 target = 'http://gitbook.cn/'
6 req = requests.get(url=target)
7 print(req.text)/<code>

requests.get()方法必須設置的一個參數就是 url,因為我們得告訴 GET 請求,我們的目標是誰,我們要獲取誰的信息。運行程序看下結果:

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

左側是我們程序獲得的結果,右側是我們在 www.gitbook.cn 網站審查元素獲得的信息。我們可以看到,我們已經順利獲得了該網頁的 HTML 信息。這就是一個最簡單的爬蟲實例,可能你會問,我只是爬取了這個網頁的 HTML 信息,有什麼用呢?客官稍安勿躁,接下來進入我們的實戰正文。

爬蟲實戰

接下來我們來一次爬蟲實戰,爬取中網小說網站「筆趣看」上的文字。

(1)實戰背景

小說網站-筆趣看:

URL:http://www.biqukan.com/

筆趣看是一個盜版小說網站,這裡有很多起點中文網的小說,該網站小說的更新速度稍滯後於起點中文網正版小說的更新速度。並且該網站只支持在線瀏覽,不支持小說打包下載。因此,本次實戰就是從該網站爬取並保存一本名為《一念永恆》的小說,該小說是耳根正在連載中的一部玄幻小說。PS:本實例僅為交流學習,支持耳根大大,請上起點中文網訂閱。

(2)小試牛刀

我們先看下《一念永恆》小說的第一章內容,URL:http://www.biqukan.com/1_1094/5403177.html

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

我們先用已經學到的知識獲取 HTML 信息試一試,編寫代碼如下:

<code>1# -*- coding:UTF-8 -*-
2import requests
3
4if __name__ == '__main__':
5 target = 'http://www.biqukan.com/1_1094/5403177.html'
6 req = requests.get(url=target)
7 print(req.text)/<code>

運行代碼,可以看到如下結果:

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

可以看到,我們很輕鬆地獲取了 HTML 信息。但是,很顯然,很多信息是我們不想看到的,我們只想獲得如右側所示的正文內容,我們不關心 div、br 這些 html 標籤。 如何把正文內容從這些眾多的 html 標籤中提取出來呢?這就是本次實戰的主要內容。

(3)Beautiful Soup

爬蟲的第一步,獲取整個網頁的 HTML 信息,我們已經完成。接下來就是爬蟲的第二步,解析 HTML 信息,提取我們感興趣的內容。對於本小節的實戰,我們感興趣的內容就是文章的正文。提取的方法有很多,例如使用正則表達式、Xpath、Beautiful Soup 等。對於初學者而言,最容易理解,並且使用簡單的方法就是使用 Beautiful Soup 提取感興趣內容。

Beautiful Soup 的安裝方法和 requests 一樣,使用如下指令安裝(也是二選一):

  1. pip install beautifulsoup4
  2. easy_install beautifulsoup4

一個強大的第三方庫,都會有一個詳細的官方文檔。我們很幸運,Beautiful Soup 也是有中文的官方文檔。URL:

http://beautifulsoup.readthedocs.io/zh_CN/latest/

同理,我會根據實戰需求,講解 Beautiful Soup 庫的部分使用方法,更詳細的內容,請查看官方文檔。

現在,我們使用已經掌握的審查元素方法,查看一下我們的目標頁面,你會看到如下內容:

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

不難發現,文章的所有內容都放在了一個名為 div 的“東西下面”,這個"東西"就是 html 標籤。HTML 標籤是 HTML 語言中最基本的單位,HTML 標籤是 HTML 最重要的組成部分。不理解,沒關係,我們再舉個簡單的例子:

一個女人的包包裡,會有很多東西,她們會根據自己的習慣將自己的東西進行分類放好。鏡子和口紅這些會經常用到的東西,會歸放到容易拿到的外側口袋裡。那些不經常用到,需要注意安全存放的證件會放到不容易拿到的裡側口袋裡。

html 標籤就像一個個“口袋”,每個“口袋”都有自己的特定功能,負責存放不同的內容。顯然,上述例子中的 div 標籤下存放了我們關心的正文內容。這個 div 標籤是這樣的:

<code>1

細心的朋友可能已經發現,除了 div 字樣外,還有 id 和 class。id 和 class 就是 div 標籤的屬性,content 和 showtxt 是屬性值,一個屬性對應一個屬性值。這東西有什麼用?它是用來區分不同的 div 標籤的,因為 div 標籤可以有很多,我們怎麼加以區分不同的 div 標籤呢?就是通過不同的屬性值。

仔細觀察目標網站一番,我們會發現這樣一個事實: class 屬性為 showtxt 的 div 標籤,獨一份!這個標籤裡面存放的內容,是我們關心的正文部分。

知道這個信息,我們就可以使用 Beautiful Soup 提取我們想要的內容了,編寫代碼如下:

<code> 1# -*- coding:UTF-8 -*-
2from bs4 import BeautifulSoup
3import requests
4if __name__ == "__main__":
5 target = 'http://www.biqukan.com/1_1094/5403177.html'
6 req = requests.get(url = target)
7 html = req.text
8 bf = BeautifulSoup(html)
9 texts = bf.find_all('div', class_ = 'showtxt')
10 print(texts)/<code>

在解析 html 之前,我們需要創建一個 Beautiful Soup 對象。BeautifulSoup 函數里的參數就是我們已經獲得的 html 信息。然後我們使用 find_all 方法,獲得 html 信息中所有 class 屬性為 showtxt 的 div 標籤。 find_all 方法的第一個參數是獲取的標籤名,第二個參數 class_ 是標籤的屬性,為什麼不是 class,而帶了一個下劃線呢?因為 python 中 class 是關鍵字,為了防止衝突,這裡使用 class_ 表示標籤的 class 屬性, class_ 後面跟著的 showtxt 就是屬性值了。看下我們要匹配的標籤格式:

<code>1

這樣對應的看一下,是不是就懂了?可能有人會問了,為什麼不是 find_all('div', id = 'content', class_ = 'showtxt') ?這樣其實也是可以的,屬性是作為查詢時候的約束條件,添加一個 class_='showtxt' 條件,我們就已經能夠準確匹配到我們想要的標籤了,所以我們就不必再添加 id 這個屬性了。運行代碼查看我們匹配的結果:

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

我們可以看到,我們已經順利匹配到我們關心的正文內容,但是還有一些我們不想要的東西。比如 div 標籤名,br 標籤,以及各種空格。怎麼去除這些東西呢?我們繼續編寫代碼:

<code> 1# -*- coding:UTF-8 -*-
2from bs4 import BeautifulSoup
3import requests
4if __name__ == "__main__":
5 target = 'http://www.biqukan.com/1_1094/5403177.html'
6 req = requests.get(url = target)
7 html = req.text
8 bf = BeautifulSoup(html)
9 texts = bf.find_all('div', class_ = 'showtxt')
10 print(texts[0].text.replace('\\\\xa0'*8,'\\n\\n'))/<code>

find_all 匹配的返回的結果是一個列表。提取匹配結果後,使用 text 屬性,提取文本內容,濾除 br 標籤。隨後使用 replace 方法,剔除空格,替換為回車進行分段。 在 html 中是用來表示空格的。 replace('\\\\xa0'*8,'\\n\\n') 就是去掉下圖的八個空格符號,並用回車代替:

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

程序運行結果如下:

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

可以看到,我們很自然的匹配到了所有正文內容,並進行了分段。我們已經順利獲得了一個章節的內容,要想下載正本小說,我們就要獲取每個章節的鏈接。我們先分析下小說目錄:URL:http://www.biqukan.com/1_1094/

Python教程:網絡爬蟲快速入門實戰解析

Python3 網絡爬蟲快速入門實戰解析

通過審查元素,我們發現可以發現,這些章節都存放在了 class 屬性為 listmain 的 div 標籤下,選取部分 html 代碼如下:

<code> 1

2

3
《一念永恆》最新章節列表

4

5

6

7

8

9

10

11

12

13

14

15

16
《一念永恆》正文卷

17

18

19

20

21
/<code>

在分析之前,讓我們先介紹一個概念:父節點、子節點、孫節點。

限定了
標籤的開始和結束的位置,他們是成對出現的,有開始位置,就有結束位置。我們可以看到,在
標籤包含
標籤,那這個
標籤就是
標籤的子節點,
標籤又包含
標籤和
標籤,那麼
標籤和
標籤就是
標籤的孫節點。有點繞?那你記住這句話: 誰包含誰,誰就是誰兒子!

他們之間的關係都是相對的。比如對於

標籤,它的子節點是
/<code>
/<code>


分享到:


相關文章: