爬蟲實戰:一鍵爬取指定網站所有圖片(二)

前言:

​ 上一篇已經提到了實現單網頁下載圖片,本篇將繼續講解如何通過爬蟲來實現全網站的下載。

任務分析:

​ 1、已實現指定某一網頁的圖片下載

​ 2、通過獲取頁面的url,進行href元素值的讀取,並寫入到下一個Job當中,並執行讀出。

直接進入題:

這次的功能其實比較簡單,只用通過xml的值,採用xpath的方式進入讀取就行了。

上一篇我們定義了一個DownloadImage類,這次我們新建一個download_image.py文件,當然,這次文件不用在其它文件中調用,所以直接放到了執行腳本當中,我們定義一個類,這個類當中包含幾個屬性:

1、待下載的url,我們定義爲ready_list,已處理完的url,定義爲finish_list,類型都爲set()。即然是url,那麼我們的頭信息必不可少,好了,直接上代碼:

class ImageList(object):
    finish_list = set()
    ready_list= set()

    headers = {
        # 用戶代理
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
    def __init__(self):
    		pass
}

思路:

1、每次訪問一個Url,我們將列表從待處理列表中移出,寫入到已處理的列表。

2、繼續讀取頁面中的內鏈,判斷內鏈在待處理的和已處理的列表中是否存在,如果不在,那麼加入到待處理當中。如果已存在,則不處理,

3、將這個頁面推送給DownloadImage類進行圖片採集。

先上代碼:

import argparse
from DownloadImage import DownloadImage
from lxml import etree as et
from urllib.parse import *
import requests
import os
class ImageList(object):
    finish_list = set()
    ready_list= set()

    headers = {
        # 用戶代理
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
    }
    def __init__(self,url,runCount=20):
        self.runCount=int(runCount)
        self.start=0
        self.url = url
        self.urlParse=urlparse(self.url)
        self.ready_list.add(url)
    def run(self):
        while len(self.ready_list)>0:
            url = self.ready_list.pop()
            self.ready_list.discard(url)
            self.getUrls(url)
            self.downloadImage(url)
        #
    def getUrls(self,url):
        response = requests.get(url, headers=self.headers)
        if(response.status_code==200):
            html = et.HTML(response.text)
            urls = html.xpath('//a/@href')
            for newUrl in urls:
                if not self.isRootUrls(urljoin(self.url,newUrl)):
                    continue
                if newUrl not in self.ready_list and newUrl not in self.finish_list:
                    self.ready_list.add(urljoin(self.url,newUrl))
    def downloadImage(self,url):
        #執行download_page
        obj = DownloadImage(url, None)
        # 過濾格式
        obj.run()
        self.start =self.start+1
        #判斷是否爲同一域名下
    def isRootUrls(self,url):
        newUrl=urljoin(self.url,url)
        urlp=urlparse(newUrl)
        if urlp.netloc == self.urlParse.netloc:
            return True
        else:
            return False

直接解讀代碼:

Self.runCount,控制頁面的處理次數,因爲如果頁面較多,將進入死循環。這裏只是簡單控制了一下,代碼還待優化。

self.getUrls 讀取頁面中所有的url列表,按邏輯判斷是否加入到reday_list列表當中

self.isRootUrls 判斷是否內鏈,如果不加此行,會成外鏈爬蟲,程序會無限讀取。

self.downloadImage ,啓動單頁圖片下載腳本

self.run 循環器,判斷ready_list是否存在,如果存在,繼續執行,直到網站中無新鏈接進來。

相信有爬蟲基礎的一眼能看明白。

但是,這裏面存在幾個問題,因爲時間的關係,和我自己本身的訴求,我未進行修復。

1.採集的URL未進行持久化保存,在結束進程後,下一次會重新採集

2.對與圖片採集記錄也沒有進行持久化保存

3.循環一開始,會出現線程鎖死,如果併發太多,無法直接結束進程

4.未實現多線程的控制

以上幾點我後面有時間會再進行優化處理。只是對爬蟲的處理方案進行了說明,希望對大家有所幫助,如果有什麼問題可以留言諮詢。

代碼地址:https://gitee.com/python_play/download_image

本文是“明哥陪你學Python”系列章節之一,如果你對Python有更多興趣,或有問題,可以私信與明哥聯繫,我會陪你一起解決,其它相關章節可以從首頁中的“明哥陪你學Python”列表進行查看。

本系列教程及源碼地址:點擊訪問

最後:如果你正在學習Python的路上,或者準備打算學習Python、明哥會陪着你陪你一起共同進步!

手打不易,有用的話,請記得關注轉發。

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