zoukankan      html  css  js  c++  java
  • 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'xffxd8xffxe0x00x10JFIFx00x01x01x01x00Hx00Hx00x00xffxd....后面跟着很多类似的乱码一样的数据


    现在问题来了,我们怎么样才能把图片下载到本地,用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是变量,图片名称和保存路径也是变量。这里不继续讨论,爬虫实现的过程了。

  • 相关阅读:
    ASP.NET中几种加密方法
    Linux Mint17.1安装PHPStorm8.0.2
    HTTP 错误 500.23
    Kali Linux 下安装配置MongoDB数据库 ubuntu 下安装配置MongoDB源码安装数据库
    如何在Ubuntu 18.04 LTS上安装和配置MongoDB
    scrapy 如何链接有密码的redis scrapy-redis 设置redis 密码 scrapy-redis如何为redis配置密码
    Redis报错:DENIED Redis is running in protected mode
    ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory")
    用mingw32编译ffmpeg2.7
    VS2005编译QT4.8.2
  • 原文地址:https://www.cnblogs.com/111testing/p/10296342.html
Copyright © 2011-2022 走看看