1. 程式人生 > 程式設計 >python自動下載圖片的方法示例

python自動下載圖片的方法示例

近日閒來無事,總有一種無形的力量縈繞在朕身邊,讓朕精神渙散,昏昏欲睡。

python自動下載圖片的方法示例

可是,像朕這麼有職業操守的社畜怎麼能在上班期間睡瞌睡呢,我不禁陷入了沉思。。。。

python自動下載圖片的方法示例

突然旁邊的IOS同事問:‘嘿,兄弟,我發現一個網站的圖片很有意思啊,能不能幫我儲存下來提升我的開發靈感?'
作為一個堅強的社畜怎麼能說自己不行呢,當時朕就不假思索的答應:‘oh, It's simple. Wait for me a few minute.'

python自動下載圖片的方法示例

點開同事給的圖片網站,

網站大概長這樣:

python自動下載圖片的方法示例

在朕翻看了幾十頁之後,朕突然覺得有點上頭。心中一想'不對啊,朕不是來學習的嗎?可是看美女圖片這個事情怎麼才可以和學習關聯起來呢‘

python自動下載圖片的方法示例

冥思苦想一番之後,突然腦中靈光一閃,'要不用python寫個爬蟲吧,將此網站的圖片一網打盡‘。

python自動下載圖片的方法示例

說幹就幹,身體力行,要問爬蟲哪家強,‘人生苦短,我用python'。

首先找到我的電腦裡面半年前下載的python安裝包,無情的點選了安裝,環境裝好之後,略一分析網頁結構。先擼一個簡易版爬蟲

#抓取愛小姐姐網圖片儲存到本地
import requests
from lxml import etree as et
import os

#請求頭
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'
}

#待抓取網頁基地址
base_url = ''
#儲存圖片基本路徑
base_dir = 'D:/python/code/aixjj/'
#儲存圖片
def savePic(pic_url):
  #如果目錄不存在,則新建
  if not os.path.exists(base_dir):
    os.makedirs(base_dir)
  
  arr = pic_url.split('/')
  file_name = base_dir+arr[-2]+arr[-1]
  print(file_name)
  #獲取圖片內容
  response = requests.get(pic_url,headers = headers)
  #寫入圖片
  with open(file_name,'wb') as fp:
    for data in response.iter_content(128):
      fp.write(data)

#觀察此網站總共只有62頁,所以迴圈62次
for k in range(1,63):
  #請求頁面地址
  url = base_url+str(k)
  response = requests.get(url = url,headers = headers)
  #請求狀態碼
  code = response.status_code
  if code == 200:
    html = et.HTML(response.text)
    #獲取頁面所有圖片地址
    r = html.xpath('//li/a/img/@src')
    #獲取下一頁url
    #t = html.xpath('//div[@class="page"]/a[@class="ch"]/@href')[-1]
    for pic_url in r:
      a = 'http:'+pic_url
      savePic(a)
  print('第%d頁圖片下載完成' % (k))

print('The End!')

嘗試執行爬蟲,嘿,沒想到行了:

python自動下載圖片的方法示例

python自動下載圖片的方法示例

過了一會兒,旁邊的哥們兒又來:‘嘿 bro 你這個可以是可以,就是速度太慢了啊,我的靈感會被長時間的等待磨滅,你給改進改進?'

python自動下載圖片的方法示例

怎麼提升爬蟲的效率呢?略一思索,公司的電腦可是偉大的四核CPU啊,要不擼個多程序版本試試。然後就產生了下面這個多程序版本

#多程序版——抓取愛小姐姐網圖片儲存到本地

import requests
from lxml import etree as et
import os
import time
from multiprocessing import Pool

#請求頭
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'
}

#待抓取網頁基地址
base_url = ''
#儲存圖片基本路徑
base_dir = 'D:/python/code/aixjj1/'

#儲存圖片
def savePic(pic_url):
  #如果目錄不存在,則新建
  if not os.path.exists(base_dir):
    os.makedirs(base_dir)
  
  arr = pic_url.split('/')
  file_name = base_dir+arr[-2]+arr[-1]
  print(file_name)
  #獲取圖片內容
  response = requests.get(pic_url,'wb') as fp:
    for data in response.iter_content(128):
      fp.write(data)

def geturl(url):
  #請求頁面地址
  #url = base_url+str(k)
  response = requests.get(url = url,headers = headers)
  #請求狀態碼
  code = response.status_code
  if code == 200:
    html = et.HTML(response.text)
    #獲取頁面所有圖片地址
    r = html.xpath('//li/a/img/@src')
    #獲取下一頁url
    #t = html.xpath('//div[@class="page"]/a[@class="ch"]/@href')[-1]
    for pic_url in r:
      a = 'http:'+pic_url
      savePic(a)

if __name__ == '__main__':
  #獲取要爬取的連結列表
  url_list = [base_url+format(i) for i in range(1,100)]
  a1 = time.time()
  #利用程序池方式建立程序,預設建立程序數量=電腦核數
  #自己定義程序數量方式 pool = Pool(4)
  pool = Pool()
  pool.map(geturl,url_list)
  pool.close()
  pool.join()
  b1 = time.time()
  print('執行時間:',b1-a1)

抱著試一試的心態,運行了多程序版本爬蟲,嘿沒想到又行了,在朕偉大的四核CPU的加持下,爬蟲速度提升了3~4倍。
又過了一會兒,那哥們兒又偏過頭來:‘你這個快是快了不少,但是還不是最理想的狀態,能不能一眨眼就能爬取百八十個圖片,畢竟我的靈感來的快去的也快'

我:‘…'
悄悄開啟Google,搜尋如何提升爬蟲效率,給出結論:

多程序:密集CPU任務,需要充分使用多核CPU資源(伺服器,大量的平行計算)的時候,用多程序。
多執行緒:密集I/O任務(網路I/O,磁碟I/O,資料庫I/O)使用多執行緒合適。

呵,我這可不就是I/O密集任務嗎,趕緊寫一個多執行緒版爬蟲先。於是,又誕生了第三款:

import threading # 匯入threading模組
from queue import Queue #匯入queue模組
import time #匯入time模組
import requests
import os
from lxml import etree as et

#請求頭
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'
}
#待抓取網頁基地址
base_url = ''
#儲存圖片基本路徑
base_dir = 'D:/python/code/aixjj/'

#儲存圖片
def savePic(pic_url):
  #如果目錄不存在,則新建
  if not os.path.exists(base_dir):
    os.makedirs(base_dir)
  
  arr = pic_url.split('/')
  file_name = base_dir+arr[-2]+arr[-1]
  print(file_name)
  #獲取圖片內容
  response = requests.get(pic_url,'wb') as fp:
    for data in response.iter_content(128):
      fp.write(data)

# 爬取文章詳情頁
def get_detail_html(detail_url_list,id):
  while True:
    url = detail_url_list.get() #Queue佇列的get方法用於從佇列中提取元素
    response = requests.get(url = url,headers = headers)
    #請求狀態碼
    code = response.status_code
    if code == 200:
      html = et.HTML(response.text)
      #獲取頁面所有圖片地址
      r = html.xpath('//li/a/img/@src')
      #獲取下一頁url
      #t = html.xpath('//div[@class="page"]/a[@class="ch"]/@href')[-1]
      for pic_url in r:
        a = 'http:'+pic_url
        savePic(a)

# 爬取文章列表頁
def get_detail_url(queue):
  for i in range(1,100):
    #time.sleep(1) # 延時1s,模擬比爬取文章詳情要快
    #Queue佇列的put方法用於向Queue佇列中放置元素,由於Queue是先進先出佇列,所以先被Put的URL也就會被先get出來。
    page_url = base_url+format(i)
    queue.put(page_url)
    print("put page url {id} end".format(id = page_url))#打印出得到了哪些文章的url

#主函式
if __name__ == "__main__":
  detail_url_queue = Queue(maxsize=1000) #用Queue構造一個大小為1000的執行緒安全的先進先出佇列
  #A執行緒負責抓取列表url
  thread = threading.Thread(target=get_detail_url,args=(detail_url_queue,)) 
  html_thread= []
  #另外建立三個執行緒負責抓取圖片
  for i in range(20):
    thread2 = threading.Thread(target=get_detail_html,i))
    html_thread.append(thread2)#B C D 執行緒抓取文章詳情
  start_time = time.time()
  # 啟動四個執行緒
  thread.start()
  for i in range(20):
    html_thread[i].start()
  # 等待所有執行緒結束,thread.join()函式代表子執行緒完成之前,其父程序一直處於阻塞狀態。
  thread.join()
  for i in range(20):
    html_thread[i].join()
  print("last time: {} s".format(time.time()-start_time))#等ABCD四個執行緒都結束後,在主程序中計算總爬取時間。

粗略測試一下,得出結論: ‘Oh my god,這也太快了吧'。
將多執行緒版本爬蟲扔到同事QQ頭像的臉上,並附文:‘拿去,速滾'

到此這篇關於python自動下載圖片的方法示例的文章就介紹到這了,更多相關python 自動下載圖片內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!