爬蟲養成記——先跨進這個精彩的世界(女生定製篇)

圖雀社群發表於2020-03-05

爬蟲養成記——先跨進這個精彩的世界(女生定製篇)

本文由圖雀社群成員 燦若星空 寫作而成,歡迎加入圖雀社群,一起創作精彩的免費技術教程,予力程式設計行業發展。

如果您覺得我們寫得還不錯,記得 點贊 + 關注 + 評論 三連???,鼓勵我們寫出更好的教程?

發刊詞

這是一套基於實戰的系列教程,從最簡單的爬蟲程式開始,授人予漁,詳細剖析程式設計的思路,完整展現爬蟲是如何一步步除錯到最終完成。分享關於爬蟲的各種知識、技巧,旨在幫助大家認識爬蟲、設計爬蟲、使用爬蟲最後享受爬蟲帶給我們在工作和生活上的各種便利。

預備知識

  1. 基本的python程式設計知識
    1. 這裡使用 Python3 作為開發環境
    2. 同時具備基本的裝包知識
  2. 基本的網頁程式設計知識
  3. 初步瞭解HTTP協議

這是最簡單的計算機程式

說起爬蟲每個人都或多或少的聽過與之相關的內容,覺得它或高深、或有趣。作為一名寫程式碼四五年的初級碼農來看,爬蟲程式是計算機程式裡面最簡單也是最有趣的程式。只要會上網衝浪就有寫爬蟲程式的天賦

爬蟲為什麼是蟲呢?因為蟲子的頭腦比較簡單,爬蟲程式也是 ++“一根筋”++ ,不需要諱莫如深的數學知識,也不用設計精巧的各類演算法。我們只需要用計算機能聽懂的“大白話”平鋪直敘就可以啦。

開發爬蟲的基本套路

一句話總結所有爬蟲程式的作用: 模擬人類上網的操作,以此來查詢、下載、儲存資料。 接下來我要以 男人圖這個網站為例,分享套路。

step 1: 開啟目標網址

此處強烈推薦Chrome

首先開啟這個網址:www.nanrentu.cc/sgtp/, 會看到以下介面

3I7ph6.png

現在我們只是用瀏覽器手動開啟了這個頁面,接下來我們要用程式碼,讓程式也開啟這個頁面。這就要分析一下瀏覽器是如何開啟這個頁面的了,請看簡易流程圖。

3IHqeJ.png

在python中,可以使用 requests 這一工具包來傳送HTTP請求。為了瞭解程式所“看到” 頁面是什麼樣子的,我們需要把程式所得到HTML檔案儲存到本地,然後再用瀏覽器開啟,就能和程式感同身受了。從而達到“人機合一”的境界。

光說不練假把式,讓我們馬上來新建一個 index.py 檔案,然後在其中編寫如下內容:

import requests
url = "https://www.nanrentu.cc/sgtp/"
response = requests.get(url)
if response.status_code == 200:
    with open("result.html",'a',encoding="utf-8") as f:
        f.write(response.text)
複製程式碼

在瀏覽器開啟寫入的HTML檔案是這樣的

3IqM36.png

3IqK9x.png

這怎麼和在瀏覽器中看到的不一樣呢?

這個時候我就要亮出一件絕世寶貝————Chrome除錯臺(按F12)來給您分析一波了。

3ILhFA.png

其實我們在瀏覽器中看到的頁面並不僅僅是HTML頁面,而是css、js、html以及各種媒體資源綜合在一起並有瀏覽器最終渲染而出頁面,紅框的部分,標出了在這個過程中所載入的各個資源。

當我們用程式去請求伺服器時,得到僅僅是HTML頁面,所以程式和我們所看到的頁面就大相徑庭了。不過沒關係HTML是主幹,抓住了主幹其他的只需要順藤摸瓜就可以了。

step2:找到目標資源

開啟這個網址以後,各位小仙女就可以各取所需咯,想體驗蕭亞軒的快樂嘛?那目標就是小鮮肉;饞彭于晏的那樣的身子了?那肌肉帥哥就是你的菜。此外韓國歐巴,歐美型男也是應有盡有。

人類是高階生物,眼睛會自動聚焦的目標身上,但是爬蟲是“一根筋”啊,它可不會自動聚焦,我們還得幫它指引道路。

寫過前端頁面的朋友都知道CSS樣式用過各種選擇器來繫結到對應的節點上,那麼我們也可以通過CSS的選擇器來選中我們想要的元素,從而提取資訊。Chrome中已經準備了CSS選擇器神器,可以生成我們想要元素的選擇器。

具體過程如下:第三步為好好欣賞小哥哥們~

3o8dJg.png

step3:解析頁面

這個時候要介紹頁面解析神器pyquery,這個工具庫可以通過我們所複製的CSS選擇器,在 HTML 頁面中查詢對應元素,並且能很便捷地提取各種屬性。那麼接下來我們就把這個小哥哥解析出來吧。

我們首先安裝 PyQuery 這個包,具體可以使用 pip 包管理器安裝,然後將程式碼修改成如下這樣:

import requests
from pyquery import PyQuery as pq
url = "https://www.nanrentu.cc/sgtp/"
response = requests.get(url)
if response.status_code == 200:
    with open("result.html",'w',encoding="utf-8") as f:
        f.write(response.text)
    # 開始解析
    doc = pq(response.text)
    # 把複製的選擇器貼上進去
    # 選擇對應的節點
    imgElement = doc('body > div:nth-child(5) > div > div > div:nth-child(2) > ul > li:nth-child(3) > a > img')
    # 提取屬性,獲取圖片連結
    imgSrc = imgElement.attr('src')
    # 將圖片連結輸出在螢幕上
    print(imgSrc)

複製程式碼

step4:儲存目標

這麼好看的小哥哥怎麼能只讓他在網際網路上呆著呢?把他放進硬碟裡的學習資料資料夾裡才是最安全的。接下來,我們就把小哥哥放到碗裡來。

下載圖片的過程其實和抓取HTML頁面的流程是一樣的,也是利用 requests 傳送請求從而獲取到資料流再儲存到本地。

import requests
from pyquery import PyQuery as pq
url = "https://www.nanrentu.cc/sgtp/"
response = requests.get(url)
if response.status_code == 200:
    with open("result.html",'w',encoding="utf-8") as f:
        f.write(response.text)
    doc = pq(response.text)
    imgElement = doc('body > div:nth-child(5) > div > div > div:nth-child(2) > ul > li:nth-child(3) > a > img')
    imgSrc = imgElement.attr('src')
    print(imgSrc)
    # 下載圖片
    imgResponse = requests.get(imgSrc)
    if imgResponse.status_code == 200:
        # 填寫檔案路徑 以二進位制的形式寫入檔案
        with open('學習檔案/boy.jpg', 'wb') as f:
            f.write(imgResponse.content)
            f.close()

複製程式碼

此時先來看看效果

3odp8K.png

四步蟲

至此僅僅十多行程式碼就完成了一個小爬蟲,是不是很簡單。其實爬蟲的基本思路就這四步,所謂複雜的爬蟲就是在這個四步的基礎上不斷演化而來的。爬蟲最終的目的是為了獲取各種資源(文字或圖片),所有的操作都是以資源為核心的。

  1. 開啟資源
  2. 定位資源
  3. 解析資源
  4. 下載資源

更多的小哥哥

通過上述步驟我們只能獲取到一個小哥哥,集美們就說了,我直接右擊滑鼠下載也可以啊,幹嘛費勁寫爬蟲呢?那接下來,我們就升級一波選擇器,把小哥哥們裝進陣列,統統搞到碗裡來。

重構程式碼

為了以後寫程式碼更方便,要先進行一個簡單的重構,讓程式碼調理清晰。

  1. 增加入口函式
  2. 封裝對於圖片的操作

重構後的程式碼如下:

import requests
from pyquery import PyQuery as pq

def saveImage(imgUrl,name):
    imgResponse = requests.get(imgUrl)
    fileName = "學習檔案/%s.jpg" % name
    if imgResponse.status_code == 200:
        with open(fileName, 'wb') as f:
            f.write(imgResponse.content)
            f.close()

def main():
    baseUrl = "https://www.nanrentu.cc/sgtp/"
    response = requests.get(baseUrl)
    if response.status_code == 200:
        with open("result.html",'w',encoding="utf-8") as f:
            f.write(response.text)
        doc = pq(response.text)
        imgElement = doc('body > div:nth-child(5) > div > div > div:nth-child(2) > ul > li:nth-child(3) > a > img')
        imgSrc = imgElement.attr('src')
        print(imgSrc)
        saveImage(imgSrc,'boy')
        
if __name__ == "__main__":
    main()
複製程式碼

升級選擇器

有過前端程式設計經驗的同學們可以看出來,Chrome自動生成的選擇器指定了具體的某個子元素,所以就只選中了一個小哥哥,那麼接下來我們要分析出通用的選擇器,把臭弟弟們一鍋端。

3oy7nK.png

多拿著滑鼠點點這個除錯臺,一層層地看這個HTML檔案的元素層級,找到其中相同重複的地方,這就是我們的突破口所在。

我們可以看出圖片都在一個類名為 h-piclist 的 <ul> 標籤中,那麼我們可寫出以下的選擇器 .h-piclist > li > a > img。這樣就選中了這一頁所有的圖片元素。接著用一個 for 迴圈遍歷就可以了。

import requests
from pyquery import PyQuery as pq

# 引入UUID為圖片命名
import uuid

def saveImage(imgUrl,name):
    imgResponse = requests.get(imgUrl)
    fileName = "學習檔案/%s.jpg" % name
    if imgResponse.status_code == 200:
        with open(fileName, 'wb') as f:
            f.write(imgResponse.content)
            f.close()

def main():
    baseUrl = "https://www.nanrentu.cc/sgtp/"
    response = requests.get(baseUrl)
    if response.status_code == 200:
        with open("result.html",'w',encoding="utf-8") as f:
            f.write(response.text)
        doc = pq(response.text)
        # 選則這一頁中所有的目標圖片元素
        imgElements = doc('.h-piclist > li > a > img').items()
        # 遍歷這些圖片元素
        for i in imgElements:
            imgSrc = i.attr('src')
            print(imgSrc)
            saveImage(imgSrc,uuid.uuid1().hex)

if __name__ == "__main__":
    main()
複製程式碼

無法下載的圖片

3o2Ygs.png

可以看出圖片的連線已經全部拿到了,但是當去下載圖片時卻發生了一些意外,請求圖片竟然沒有反應。這是哪裡出了問題呢?圖片連線全部拿到,證明程式碼沒毛病,把圖片連結放到瀏覽器里正常開啟,證明連線沒毛病,那現在可能就是網路有毛病了。

  1. 網速慢
  2. 網路波動
  3. 對方網站有防爬措施
  4. ……

這時候因素很多,我們首先用最簡單的方法來解決問題,斷線重連。把筆記本WIFI重啟,重新加入網路,再執行程式。

驚喜來了,臭弟弟們成功入庫。

3o2T8H.png

當然啦,這種方式並不是銀彈,我們需要有更多的技巧來提升爬蟲程式的“演技”,我們的爬蟲程式表現的越像個人,那我們獲取資源的成功率就會越高。

看到這裡,應該跨進爬蟲世界的大門了,如果這個世界有主題曲的話那麼一定是薛之謙的《演員》接下來的教程中會一遍磨礪“演技”,一遍獲取更多的小哥哥。

如果您覺得我們寫得還不錯,記得 點贊 + 關注 + 評論 三連???,鼓勵我們寫出更好的教程?

想要學習更多精彩的實戰技術教程?來圖雀社群逛逛吧。

爬蟲養成記——先跨進這個精彩的世界(女生定製篇)

相關文章