Python學習筆記 - 下載圖片

MADAO是不會開花的發表於2019-01-19

一. requests.Session()

上一篇總結爬蟲的文章裡,有說道一個cookie的問題。當時我都是手動解析,手動新增的。後來才知道requests模組居然有一個Session功能,可以保持cookie。這裡記錄一下:

import requests

base_url = 'https://www.zhihu.com'

# 未登入裝態
r_session = requests.Session()
r_session.headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
zhihu = r_session.get(base_url)
print(zhihu.request.headers)

# 登入
data = {'username': 'username', 'password': 'password'}
zhihu_sign_in = r_session.post('https://www.zhihu.com/api/v3/oauth/sign_in', data=data)
print(zhihu_sign_in.request.headers)
複製程式碼

結果:

Python學習筆記 - 下載圖片

用了Session就會自動帶上cookie了。

二. 如何下載一個圖片

  • urlretrieve

    在Python自帶的模組urllib中提供了一個方法urlretrieve,可以用這個方法下載一個圖片:

    from urllib.request import urlretrieve
    import os
    
    img_url = 'https://wx4.sinaimg.cn/mw690/70396e5agy1fxlqvsv93sj20ku0yu42u.jpg'
    urlretrieve(img_url, './image.jpg')
    複製程式碼

    傳入圖片地址和圖片要存放的地址即可。

  • requests模組

    import requests
    
    img_url = 'https://wx4.sinaimg.cn/mw690/70396e5agy1fxlqvsv93sj20ku0yu42u.jpg'
    img = requests.get(img_url)
    with open('./image2.jpg', 'wb') as f:
      f.write(img.content)
    複製程式碼

    使用requests模組也可以下載圖片,通過open方法將下載下來的圖片通過二進位制方式寫入檔案中

    如果下載的圖片(除了圖片其他資源也一樣,比如視訊)特別大,那麼還可以用

    import requests
    
    img_url = 'https://wx4.sinaimg.cn/mw690/70396e5agy1fxlqvsv93sj20ku0yu42u.jpg'
    
    img = requests.get(img_url, stream=True)
    with open('./image3.jpg', 'wb') as f:
        for chunk in img.iter_content(chunk_size=10):
            f.write(chunk)
    複製程式碼

    這種方式,加上steam=True引數,可以讓requests下載一點儲存一點,而不是等全部下載完成再進行儲存,然後通過chunk_size控制chunk的大小

  • 實現一個下載桌布的爬蟲

import requests
import time
import random
from bs4 import BeautifulSoup
import os
from functools import reduce


base_url = 'https://alpha.wallhaven.cc/' # 桌布網址
req_session = requests.Session()
req_session.headers['user-agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'


def get_store_path(dir_name):
    '''
    建立存放桌布檔案目錄
    '''
    current_path = os.path.abspath('.')
    target_path = os.path.join(current_path, 'wallpaper/%s' % dir_name)
    folder = os.path.exists(target_path)
    if not folder:
        os.makedirs(target_path)

    return target_path


def get_img_html(page_size):
    '''
    獲取桌布的html資源
    '''
    htmls = []
    for i in range(1, page_size):
        params = {
            'q': keyword,
        }
        # 由於該網站page是從2開始的,如果帶了小於2的值就會找不到桌布
        if i >= 2:
            params['page'] = i
        html = req_session.get('%s/search' % base_url, params=params)
        htmls.append(html)
        time.sleep(random.random())
    return htmls


def parse_html(html):
    '''
    從html中將桌布地址解析出來
    '''
    imgs_src = []
    bs_html = BeautifulSoup(html.text, 'lxml')
    img_tags = bs_html.find_all('img', {'class': 'lazyload'})
    if len(img_tags):
        for img in img_tags:
            imgs_src.append(img['data-src'])
    return imgs_src


def download_imgs(imgs_src):
    '''
    下載桌布
    '''
    if len(imgs_src):
        for index, src in enumerate(imgs_src):
            img = req_session.get(src, stream=True)
            img_name = src.split('/')[-1]
            store_path = '%s/%s' % (get_store_path(keyword), img_name)
            with open(store_path, 'wb') as f:
                for chunk in img.iter_content(chunk_size=128):
                    f.write(chunk)
                print('下載進度:%d/%d' % (index + 1, len(imgs_src)))
        print('下載完成,圖片已存放在:%s' % store_path)
    else:
        print('沒有找到相關主題的桌布')


keyword = input('請輸入你想要下載的桌布主題:')
page_size = int(input('請輸入下載桌布的頁數,每頁24張:'))
print('開始查詢桌布....')
html_list = get_img_html(page_size)
img_src_list = []
if len(html_list):
    print('查詢完成')
    print('開始爬取桌布地址...')
    for html in html_list:
        img_src_list.append(parse_html(html))
    img_src_list = reduce(lambda x, y: x+y, img_src_list)
    print('爬取完成')
    print('開始下載桌布...')
    download_imgs(img_src_list)
else:
    print('沒有找到相關主題的桌布')

複製程式碼

結果:

Python學習筆記 - 下載圖片

Python學習筆記 - 下載圖片

相關文章