前言:
上一篇已經提到了實現單網頁下載圖片,本篇將繼續講解如何通過爬蟲來實現全網站的下載。
任務分析:
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、明哥會陪着你陪你一起共同進步!
手打不易,有用的話,請記得關注轉發。