Python requests庫如何下載一個圖片資源


原文地址https://blog.csdn.net/u011541946/article/details/77700074

          前面一篇文章介紹了response對象的一些常用API,也已經提到,我們的重點是對response對象的操作。主要的操作就是數據分析和提取,一般來說,數據有很多種,有字段,有圖片,有視頻,有音頻,凡是html頁面能支持的content-type都是數據。只是不同場景下,有不同目的。例如,加入你需要在一個圖片網站,爬取一些你敢興趣的圖片。或者你需要在一些招聘網站爬取職位信息,或者,你需要從服務器端下載一個文件。這些事情requests都可以幫你做到。本文,就是簡單介紹,如何從網頁獲取一個圖片的過程。

1. 設置我們的場景

打開百度圖片搜索,輸入selenium,然后找到一個selenium的圖片,我們需要把這個圖片通過requests下載到本地,圖片如下。

這里我們假如說要下載第一張圖片。

2. 手動獲取圖片在服務器上的url

點擊打開上面紅圈這個圖片,記錄下這個圖片在服務器上的路徑。你可以右鍵這個圖片-查看圖片,獲取到這個路徑:https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504662907&di=2bf9d214dfdc9b0243163fb0a20f1228&imgtype=jpg&er=1&src=http%3A%2F%2Fpic.baike.soso.com%2Fp%2F20140415%2Fbki-20140415104220-671149140.jpg

3. 利用requests.get()方法和response.content方法是否能夠打印出圖片

import requests
 
def download_image():
 
    url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504068152047&di=8b53bf6b8e5deb64c8ac726e260091aa&imgtype=0&src=http%3A%2F%2Fpic.baike.soso.com%2Fp%2F20140415%2Fbki-20140415104220-671149140.jpg'
 
    response = requests.get(url)
    print(response.status_code)
    print(response.content)
 
if __name__ == '__main__':
    download_image()

運行一下,發現請求正確,但是用response.content打印出來是一堆亂碼。
200 OK
b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xff\xd....后面跟着很多類似的亂碼一樣的數據


現在問題來了,我們怎么樣才能把圖片下載到本地,用response.content方法是行不通的。我們知道,圖片也是文件格式,圖片也是一些二進制代碼組成。我們把圖片當做普通的文件,然后通過字節流的方法,把圖片保存到本地。


4.通過字節流方式保存圖片

       大概的原理是,一個圖片是由字節流數據組成,我們可以把圖片分層多個字節流數據,加載到內存,然后復制字節流到一個本地路徑,最后組合成一張圖片。

import requests
 
def download_image():
 
    url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504068152047&di=8b53bf6b8e5deb64c8ac726e260091aa&imgtype=0&src=http%3A%2F%2Fpic.baike.soso.com%2Fp%2F20140415%2Fbki-20140415104220-671149140.jpg'
 
    response = requests.get(url, stream = True)
 
    # 這里打開一個空的png文件,相當於創建一個空的txt文件,wb表示寫文件
    with open('selenium.png', 'wb') as file:
        # 每128個流遍歷一次
        for data in response.iter_content(128):
            # 把流寫入到文件,這個文件最后寫入完成就是,selenium.png
            file.write(data) # data相當於一塊一塊數據寫入到我們的圖片文件中
 
    print(response.status_code)
 
 
if __name__ == '__main__':
    download_image()

       運行之后,得到請求狀態碼是200,而且會在當前這個腳本文件同級目錄下生成一個selenium.png的圖片。如果你要指定圖片保存路徑,你可以在open('圖片完整路徑','wb'),通過這樣方式,把圖片保存到你想要保存的磁盤路徑。上面雖然實現了我們的下載圖片的目的,但是有一個問題就是,我們使用完了stream之后,沒有立馬去關閉,這樣會造成內存資源緊張,如果是批量下載很多圖片,這個方式是不可取的。


5.換一種方式,及時關閉stream

import requests
from contextlib import closing
 
def download_image_improve():
 
    url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504068152047&di=8b53bf6b8e5deb64c8ac726e260091aa&imgtype=0&src=http%3A%2F%2Fpic.baike.soso.com%2Fp%2F20140415%2Fbki-20140415104220-671149140.jpg'
 
    response = requests.get(url, stream = True)
    with closing(requests.get(url, stream = True)) as response:
        # 這里打開一個空的png文件,相當於創建一個空的txt文件,wb表示寫文件
        with open('selenium1.png', 'wb') as file:
            # 每128個流遍歷一次
            for data in response.iter_content(128):
                # 把流寫入到文件,這個文件最后寫入完成就是,selenium.png
                file.write(data)
 
if __name__ == '__main__':
    download_image_improve()

       運行之后,也會在當前腳本文件所在目錄生成一個selenium1.png文件。contextlib.closing()函數是實現在一個代碼塊之后自動關閉,這里的代碼塊,就是我們請求下載圖片的過程。這篇,已經實現了限定的圖片url下載,如果是爬蟲,肯定是大量圖片下載。上面圖片下載可以提取出來,重構成一個方法,在實際爬蟲中調用。當然,爬蟲中,很多是變量,圖片請求url是變量,圖片名稱和保存路徑也是變量。這里不繼續討論,爬蟲實現的過程了。

 


免責聲明!

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



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