大家好我叫hardy
需求:爬取某個頁面,並把該頁面的圖片下載到本地
思考:
img標籤一個有多少種型別的src值?四種:1、以http開頭的網路連結。2、以“//”開頭網路地址。3、以“/”開頭絕對路徑。4、以“./”開頭相對路徑。當然還有其他型別,不過這個不做考慮,能力有限呀。
使用什麼工具?我用requests、xpth
都有那些步驟:1、爬取網頁
2、分析html並獲取img中的src的值
3、獲取圖片
4、儲存
具體實現
import requests from lxml import etree import time import os import re requests = requests.session() website_url = '' website_name = '' ''' 爬取的頁面 ''' def html_url(url): try: head = set_headers() text = requests.get(url,headers=head) # print(text) html = etree.HTML(text.text) img = html.xpath('//img/@src') # 儲存圖片 for src in img: src = auto_completion(src) file_path = save_image(src) if file_path == False: print('請求的圖片路徑出錯,url地址為:%s'%src) else : print('儲存圖片的地址為:%s'%file_path) except requests.exceptions.ConnectionError as e: print('網路地址無法訪問,請檢查') print(e) except requests.exceptions.RequestException as e: print('訪問異常:') print(e) ''' 儲存圖片 ''' def save_image(image_url): size = 0 number = 0 while size == 0: try: img_file = requests.get(image_url) except requests.exceptions.RequestException as e: raise e # 不是圖片跳過 if check_image(img_file.headers['Content-Type']): return False file_path = image_path(img_file.headers) # 儲存 with open(file_path, 'wb') as f: f.write(img_file.content) # 判斷是否正確儲存圖片 size = os.path.getsize(file_path) if size == 0: os.remove(file_path) # 如果該圖片獲取超過十次則跳過 number += 1 if number >= 10: break return (file_path if (size > 0) else False) ''' 自動完成url的補充 ''' def auto_completion(url): global website_name,website_url #如果是http://或者https://開頭直接返回 if re.match('http://|https://',url): return url elif re.match('//',url): if 'https://' in website_name: return 'https:'+url elif 'http://' in website_name: return 'http:' + url elif re.match('/',url): return website_name+url elif re.match('./'): return website_url+url[1::] ''' 圖片儲存的路徑 ''' def image_path(header): # 資料夾 file_dir = './save_image/' if not os.path.exists(file_dir): os.makedirs(file_dir) # 檔名 file_name = str(time.time()) # 檔案字尾 suffix = img_type(header) return file_dir + file_name + suffix ''' 獲取圖片字尾名 ''' def img_type(header): # 獲取檔案屬性 image_attr = header['Content-Type'] # 獲取字尾 suffix = image_attr.split('/')[1] if suffix == 'jpeg': suffix = 'jpg' return '.' + suffix # 檢查是否為圖片型別 def check_image(content_type): if 'image' in content_type: return False else: return True #設定頭部 def set_headers(): global website_name, website_url head = { 'Host':website_name.split('//')[1], 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36', } return head if __name__ == '__main__': #當前的url,不包含檔名的比如index.html,用來下載當前頁的頁面圖片(./) website_url = 'https://dig.chouti.com/all/hot/recent' #域名,用來下載"/"開頭的圖片地址 #感興趣的朋友請幫我完善一下這個自動完成圖片url的補充 website_name = 'https://dig.chouti.com' url = 'https://dig.chouti.com/all/hot/recent/1' html_url(url)