IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 【python数据下载】urllib与requests的简单使用 -> 正文阅读

[Python知识库]【python数据下载】urllib与requests的简单使用

使用python进行数据下载

使用urllib进行下载

在使用python作为爬虫与下载工具时,urllib是个常用的包,其核心下载方法使用起来非常简单,只需一个方法:

  • urllib.request.urlretrieve():
    urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)
      """
      @filename: 指定的存储路径
      @reporthook: 指定的回调函数, 包含block number, a read size, and the total file size
      """
    
  • 实际上简单使用只需要一行代码:
    import urllib
    urllib.request.urlretrieve(download_url, save_path)
    

而当我们需要显示下载进度时,可以在reporthook中传入一个回调函数,这个回调函数接口是固定的,会传入三个参数分别为:当前已经下载的块,每次传输的块大小以及文件总大小。

  • reporthook的简单实现
    def schedule(blocknum,blocksize,totalsize):
      # print(blocknum, blocksize, totalsize)
      """
      * 用于urllib.request.urlretrieve方法的回调函数
      @ blocknum:当前已经下载的块
      @ blocksize:每次传输的块大小
      @ totalsize:网页文件总大小
      """
      if totalsize == 0:
          percent = 0
      else:
          percent = blocknum * blocksize / totalsize
      if percent > 1.0:
          percent = 1.0
      percent = percent * 100
      # 打印下载的百分比
      print("download %s : %.4f%%" %(base_name, percent))
    

使用requests进行下载

除了urllib外使用requests模块也是一个常用的方法。使用requests时,多数的操作需要手动完成,但也因此在实行断点续传等操作时也更加方便。

  • 使用requests进行数据下载:
    # 首次请求
    r1 = requests.get(download_url, stream=True, verify=False)
    # 获得文件的总大小
    total_size = int(r1.headers['Content-Length'])
    if os.path.exists(video_save_path):
        temp_size = os.path.getsize(video_save_path)
    else:
        temp_size = 0
    # 下载时,从本地文件已经下载过的文件后面继续下载
    headers = {'Range': 'bytes=%d-' % temp_size}
    r = requests.get(download_url, stream=True, verify=False, headers=headers)
    with open(video_save_path, "ab") as f:
        # 当下载大文件时,不能一次加载,采用迭代方式下载
        for chunk in r.iter_content(chunk_size=1024):
            if chunk:
                temp_size += len(chunk)
                f.write(chunk)
                f.flush()
                # 打印下载进度
                print("download %s : %d / %d || %.4f%%" %(base_name, temp_size, total_size, temp_size/total_size))
    

多进程

python提供了便利的多进程方法,这里我们采用了最简单的方式:

  • 多进程
    def download():
      # 解析下载文件地址并存入列表
      with open('download_urls.txt', 'r', encoding='utf-8') as f:
          urls = f.readlines()
          f.close()
      process = []
      # 创建进程并加入进程池,每个进程对应一个下载文件(文件较大且个数较少,根据需要改写)
      for url in urls:
          process.append(Process(target=_download, args=[url.strip()]))
      # 创建并启动进程
      [p.start() for p in process]
      # 等待子进程结束后再继续往下运行,在当前位置阻塞主进程
      [p.join() for p in process]
    

完整代码

"""
* 提供了多进程下载
* 使用urllib.request包,当下载失败时自动重新下载
"""
import os
import os
import urllib.request
import socket
import sys
import logging
# 设置超时时间
socket.setdefaulttimeout(30)

from multiprocessing import Process, Queue
#设置日志模块
logging.basicConfig(level=logging.DEBUG #设置日志输出格式
                    ,filename="demo.log" #log日志输出的文件位置和文件名
                    ,filemode="w" #文件的写入格式,w为重新写入文件,默认是追加
                    ,format="%(asctime)s - %(name)s - %(levelname)-9s - %(filename)-8s : %(lineno)s line - %(message)s" #日志输出的格式
                    # -8表示占位符,让输出左对齐,输出长度都为8位
                    ,datefmt="%Y-%m-%d %H:%M:%S" #时间输出的格式
                    )

def _download(*args):
    """
    * 子进程函数,负责从每一个传入的url下载文件
    """
    logger=logging.getLogger()
    fh = logging.FileHandler('log.txt', mode='a', encoding='utf-8', delay=False)
    logger.addHandler(fh)

    # 下载地址解析,指定存储位置
    download_url = args[0]
    base_name = os.path.basename(download_url)
    video_save_path = os.path.join('save/', base_name)
    
    def schedule(blocknum,blocksize,totalsize):
        # print(blocknum, blocksize, totalsize)
        """
        * 用于urllib.request.urlretrieve方法的回调函数,接口是固定的
        @ blocknum:当前已经下载的块
        @ blocksize:每次传输的块大小
        @ totalsize:网页文件总大小
        """
        if totalsize == 0:
            percent = 0
        else:
            percent = blocknum * blocksize / totalsize
        if percent > 1.0:
            percent = 1.0
        percent = percent * 100
        print("download %s : %.4f%%" %(base_name, percent))
  
    while True:
        #当下载失败时重新下载
        try:
            logger.info('downloding %s ...'%download_url)
            urllib.request.urlretrieve(download_url, video_save_path, schedule)
        except Exception as e:
            logger.info('exception has occured in downloading {}: {}'.format(download_url, e))
            continue
        break

def download():
    # 解析下载文件地址并存入列表
    with open('download.txt', 'r', encoding='utf-8') as f:
        lines = f.readlines()
        f.close()
    process = []
    # 创建进程并加入进程池,每个进程对应一个下载文件(文件较大且个数较少,根据需要改写)
    for line in lines:
        process.append(Process(target=_download, args=[line.strip()]))
    # 创建并启动进程
    [p.start() for p in process]
    # 等待子进程结束后再继续往下运行,在当前位置阻塞主进程
    [p.join() for p in process]

    

if __name__ == '__main__':
    
    download()

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 12:36:21  更:2022-05-09 12:37:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 17:44:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计