欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python爬取視頻(其實是一篇福利)過程解析

 更新時間:2019年08月01日 09:57:59   作者:再見紫羅蘭  
這篇文章主要介紹了Python爬取視頻(其實是一篇福利)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

窗外下著小雨,作為單身程序員的我逛著逛著發(fā)現一篇好東西,來自知乎 你都用 Python 來做什么?的第一個高亮答案。

到上面去看了看,地址都是明文的,得,趕緊開始吧。

下載流式文件,requests庫中請求的stream設為True就可以啦,文檔在此。

先找一個視頻地址試驗一下:

# -*- coding: utf-8 -*-
import requests 
def download_file(url, path):
  with requests.get(url, stream=True) as r:
    chunk_size = 1024
    content_size = int(r.headers['content-length'])
    print '下載開始'
    with open(path, "wb") as f:
      for chunk in r.iter_content(chunk_size=chunk_size):
        f.write(chunk) 
if __name__ == '__main__':
  url = '就在原帖...'
  path = '想存哪都行'
  download_file(url, path)

遭遇當頭一棒:

AttributeError: __exit__

這文檔也會騙人的么!

看樣子是沒有實現上下文需要的__exit__方法。既然只是為了保證要讓r最后close以釋放連接池,那就使用contextlib的closing特性好了:

# -*- coding: utf-8 -*-
import requests
from contextlib import closing
 
def download_file(url, path):
  with closing(requests.get(url, stream=True)) as r:
    chunk_size = 1024
    content_size = int(r.headers['content-length'])
    print '下載開始'
    with open(path, "wb") as f:
      for chunk in r.iter_content(chunk_size=chunk_size):
        f.write(chunk)

程序正常運行了,不過我盯著這文件,怎么大小不見變啊,到底是完成了多少了呢?還是要讓下好的內容及時存進硬盤,還能省點內存是不是:

# -*- coding: utf-8 -*-
import requests
from contextlib import closing
import os
 
def download_file(url, path):
  with closing(requests.get(url, stream=True)) as r:
    chunk_size = 1024
    content_size = int(r.headers['content-length'])
    print '下載開始'
    with open(path, "wb") as f:
      for chunk in r.iter_content(chunk_size=chunk_size):
        f.write(chunk)
        f.flush()
        os.fsync(f.fileno())

文件以肉眼可見的速度在增大,真心疼我的硬盤,還是最后一次寫入硬盤吧,程序中記個數就好了:

def download_file(url, path):
  with closing(requests.get(url, stream=True)) as r:
    chunk_size = 1024
    content_size = int(r.headers['content-length'])
    print '下載開始'
    with open(path, "wb") as f:
      n = 1
      for chunk in r.iter_content(chunk_size=chunk_size):
        loaded = n*1024.0/content_size
        f.write(chunk)
        print '已下載{0:%}'.format(loaded)
        n += 1

結果就很直觀了:

已下載2.579129%
已下載2.581255%
已下載2.583382%
已下載2.585508%

心懷遠大理想的我怎么會只滿足于這一個呢,寫個類一起使用吧:

# -*- coding: utf-8 -*-
import requests
from contextlib import closing
import time 
def download_file(url, path):
  with closing(requests.get(url, stream=True)) as r:
    chunk_size = 1024*10
    content_size = int(r.headers['content-length'])
    print '下載開始'
    with open(path, "wb") as f:
      p = ProgressData(size = content_size, unit='Kb', block=chunk_size)
      for chunk in r.iter_content(chunk_size=chunk_size):
        f.write(chunk)
        p.output()
 
 
class ProgressData(object):
 
  def __init__(self, block,size, unit, file_name='', ):
    self.file_name = file_name
    self.block = block/1000.0
    self.size = size/1000.0
    self.unit = unit
    self.count = 0
    self.start = time.time()
  def output(self):
    self.end = time.time()
    self.count += 1
    speed = self.block/(self.end-self.start) if (self.end-self.start)>0 else 0
    self.start = time.time()
    loaded = self.count*self.block
    progress = round(loaded/self.size, 4)
    if loaded >= self.size:
      print u'%s下載完成\r\n'%self.file_name
    else:
      print u'{0}下載進度{1:.2f}{2}/{3:.2f}{4} 下載速度{5:.2%} {6:.2f}{7}/s'.\
         format(self.file_name, loaded, self.unit,\
         self.size, self.unit, progress, speed, self.unit)
      print '%50s'%('/'*int((1-progress)*50))

運行:

下載開始
下載進度10.24Kb/120174.05Kb 0.01% 下載速度4.75Kb/s
/////////////////////////////////////////////////
下載進度20.48Kb/120174.05Kb 0.02% 下載速度32.93Kb/s
/////////////////////////////////////////////////

看上去舒服多了。

下面要做的就是多線程同時下載了,主線程生產url放入隊列,下載線程獲取url:

# -*- coding: utf-8 -*-
import requests
from contextlib import closing
import time
import Queue
import hashlib
import threading
import os 
def download_file(url, path):
  with closing(requests.get(url, stream=True)) as r:
    chunk_size = 1024*10
    content_size = int(r.headers['content-length'])
    if os.path.exists(path) and os.path.getsize(path)>=content_size:
      print '已下載'
      return
    print '下載開始'
    with open(path, "wb") as f:
      p = ProgressData(size = content_size, unit='Kb', block=chunk_size, file_name=path)
      for chunk in r.iter_content(chunk_size=chunk_size):
        f.write(chunk)
        p.output()
 
class ProgressData(object):
 
  def __init__(self, block,size, unit, file_name='', ):
    self.file_name = file_name
    self.block = block/1000.0
    self.size = size/1000.0
    self.unit = unit
    self.count = 0
    self.start = time.time()
  def output(self):
    self.end = time.time()
    self.count += 1
    speed = self.block/(self.end-self.start) if (self.end-self.start)>0 else 0
    self.start = time.time()
    loaded = self.count*self.block
    progress = round(loaded/self.size, 4)
    if loaded >= self.size:
      print u'%s下載完成\r\n'%self.file_name
    else:
      print u'{0}下載進度{1:.2f}{2}/{3:.2f}{4} {5:.2%} 下載速度{6:.2f}{7}/s'.\
         format(self.file_name, loaded, self.unit,\
         self.size, self.unit, progress, speed, self.unit)
      print '%50s'%('/'*int((1-progress)*50))
 queue = Queue.Queue() 
def run():
  while True:
    url = queue.get(timeout=100)
    if url is None:
      print u'全下完啦'
      break
    h = hashlib.md5()
    h.update(url)
    name = h.hexdigest()
    path = 'e:/download/' + name + '.mp4'
    download_file(url, path) 
def get_url():
  queue.put(None)
if __name__ == '__main__':
  get_url()
  for i in xrange(4):
    t = threading.Thread(target=run)
    t.daemon = True
    t.start()

加了重復下載的判斷,至于怎么源源不斷的生產url,諸位摸索吧,保重身體!

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • python實現opencv+scoket網絡實時圖傳

    python實現opencv+scoket網絡實時圖傳

    這篇文章主要為大家詳細介紹了python實現opencv+scoket網絡實時圖傳,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • Python 基礎教程之str和repr的詳解

    Python 基礎教程之str和repr的詳解

    這篇文章主要介紹了Python 基礎教程之str和repr的詳解的相關資料,主要說明他們之家的區(qū)別,通過此文希望能幫助到大家,幫助大家理解這部分內容,需要的可以參考下
    2017-08-08
  • PHP函數__autoload失效原因及解決方法

    PHP函數__autoload失效原因及解決方法

    在本篇文章里小編給大家整理的是一篇關于PHP函數__autoload失效原因及解決方法,有興趣的朋友們可以學習下。
    2021-09-09
  • python爬蟲之模擬登陸csdn的實例代碼

    python爬蟲之模擬登陸csdn的實例代碼

    今天小編就為大家分享一篇python爬蟲之模擬登陸csdn的實例代碼,具有很好的參考價值希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • 通過實例了解Python str()和repr()的區(qū)別

    通過實例了解Python str()和repr()的區(qū)別

    這篇文章主要介紹了通過實例了解Python str()和repr()的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • python自制包并用pip免提交到pypi僅安裝到本機【推薦】

    python自制包并用pip免提交到pypi僅安裝到本機【推薦】

    這篇文章主要介紹了python自制包并用pip免提交到pypi僅安裝到本機,本文分步驟給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-06-06
  • Matplotlib多子圖使用一個圖例的實現

    Matplotlib多子圖使用一個圖例的實現

    多子圖是Matplotlib中的一個功能,可以在同一圖形中創(chuàng)建多個子圖,本文主要介紹了Matplotlib多子圖使用一個圖例的實現,感興趣的可以了解一下
    2023-08-08
  • python實現多線程采集的2個代碼例子

    python實現多線程采集的2個代碼例子

    這篇文章主要介紹了python多線程采集代碼例子,使用了Threading、Queue、MySQLdb等模塊,需要的朋友可以參考下
    2014-07-07
  • Python微信庫:itchat的用法詳解

    Python微信庫:itchat的用法詳解

    本篇文章主要介紹了Python微信庫:itchat的用法詳解,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • 使用Python?Cupy模塊加速大規(guī)模數值計算實例深究

    使用Python?Cupy模塊加速大規(guī)模數值計算實例深究

    Cupy是一個基于NumPy的庫,專門設計用于在GPU上進行高性能計算,它提供了與NumPy相似的API,因此用戶可以很容易地將現有的NumPy代碼遷移到Cupy上,從而充分利用GPU的并行計算能力
    2023-12-12

最新評論