python 爬蟲之requests爬取頁面圖片的url,並將圖片下載到本地


大家好我叫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):
    if not image_url:
        return False
    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('./',url):
        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']
    pattern = 'image/([a-zA-Z]+)'
    suffix = re.findall(pattern,image_attr,re.IGNORECASE)
    if not suffix:
        suffix = 'png'
    else :
        suffix = suffix[0]
    # 獲取后綴
    if re.search('jpeg',suffix,re.IGNORECASE):
        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://blog.csdn.net/kindroid/article/details'
    #域名,用來下載"/"開頭的圖片地址
    #感興趣的朋友請幫我完善一下這個自動完成圖片url的補充
    website_name = 'https://blog.csdn.net'
    url = 'https://blog.csdn.net/kindroid/article/details/52095833'
    html_url(url)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM