in

如何使用 Python 下载图片?

使用 Python 下载图片的方法

Requests 库是网页抓取中下载网页 HTML 代码的常用工具。但你知道吗,它也可以用来下载和抓取其他类型的信息,例如图片。

本文将向你展示如何使用 Python 下载图片。它将涵盖三个库:Requests、urllib3 和 wget。此外,它还将展示如何使用代理隐藏你的 IP 地址,同时抓取图片。


使用 Requests 下载图片

如果你已经在使用 Requests 库来抓取网页,那么它也是下载图片的不二之选。Requests 是一个功能强大、广泛使用的 Python 库,用于发送 HTTP 请求和处理响应。

虽然 Requests 擅长从网页和 API 中获取数据,但它不能直接处理图片。不过,不要担心—Python 有内置的工具来解决这些问题。

要使用 Requests 下载图片,只需要:

  • 使用 Requests 请求文件。
  • 将响应的内容写入图片文件。

例如,如果你想从 Books to Scrape(一个网页抓取沙箱)下载一本书的封面,这是如何做到的。

首先,导入库。

import requests

然后,创建一个变量来保存要下载的图像的URL。

url = 'https://books.toscrape.com/media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg'

使用requests.get()请求图像。

res = requests.get(url)

最后,将其写入文件。

with open('img.jpg','wb') as f:
    f.write(res.content)

不过,您确实需要小心,不要在此方法中使用错误的扩展。例如,尝试将PNG文件写入JPG文件将导致文件不可读。

下面是解决这个问题的方法。如果您从页面获取URL,则可以从URL中提取文件名和/或扩展名,并将其用作下载文件的文件名。

def extract_name(url): 
      file_name = url.split("/")[-1]
      return file_name

with open(extract_name(url),'wb') as f:
      f.write(res.content)

这将确保文件内容与名称匹配。

为 Requests 使用代理

如果你使用脚本下载一两张图片,没人会注意。但是,如果你想下载大量图片,例如整个书籍封面集合,而不仅仅是一张,你需要小心。网站管理员通常不喜欢大规模的抓取活动,特别是当它涉及到加载大量元素,例如图片时。

为了避免被检测,使用代理是必不可少的。代理充当着你和你访问的网站之间的门户,允许你隐藏你的 IP 地址。

将代理添加到 Requests 请求中非常简单。你只需要一个代理提供商,我推荐使用如 Bright DataIPRoyal 之类的轮换住宅代理,因为它们可以为每个请求提供一个新的IP,使其快速设置和安全使用。

然后,在脚本中创建一个字典来保存代理链接。

proxies = {
    'http': 'http://link-to-proxy.com',
    'https': 'http://link-to-proxy.com' 
}

然后,您可以通过代理参数向requests.get()函数提供字典。

response = requests.get(
    url,
    proxies=proxies
)

现在,您将能够下载图像而不会被网站所有者检测到。

下面是使用代理从网站下载图像的完整代码:

import requests

def extract_name(url): 
    file_name = url.split("/")[-1]
    return file_name


proxies = {
    'http': 'http://link-to-proxy',
    'https': 'http://link-to-proxy'
}

url = 'https://books.toscrape.com/media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg'

res = requests.get(
    url, 
    proxies=proxies
)

with open(extract_name(url),'wb') as f:
    f.write(res.content)

使用Urllib3下载图像

Urllib3 是 Python 的一个 HTTP 客户端库,与 Requests 库相似。实际上,Requests 库在其实现中使用了 urllib3。两个库非常相似,选择哪一个库通常取决于你已经在工作流程中使用的库。

如果你选择使用 urllib3 而不是 Requests,这里是使用它下载图片的方法:

首先,导入库:

import urllib3

然后,用您想要抓取的图像的URL创建一个变量。

url = 'http://books.toscrape.com/media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg'

之后,下载图像:

res = http.request('GET', url)

现在可以从URL中提取文件名并将其保存到文件中。

def extract_name(url): 
    file_name = url.split("/")[-1]
    return file_name

with open(extract_name(url),'wb') as f:
    f.write(res.data)

下面是完整的代码:

import urllib3

url = 'http://books.toscrape.com/media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg'

res = urllib3.request('GET', url)

def extract_name(url): 
    file_name = url.split("/")[-1]
    return file_name

with open(extract_name(url),'wb') as f:
    f.write(res.data)

为 Urllib3 使用代理

与使用 Requests 相似,使用 urllib3 下载图片时也需要使用代理来隐藏你的活动,以免被网站所有者发现。

不幸的是,使用 urllib3 的代理比使用 Requests 的代理要复杂一些。 特别是当你想使用授权代理时—这些代理需要你提供用户名和密码来访问它们。

要使用 urllib3 的授权代理,你需要三个东西:

  • 代理提供商的 URL 和端口
  • 用户名;
  • 密码。

首先,使用urllib3.make_headers()函数生成代理授权的标头。将用户名和密码替换为您使用的实际用户名和密码。

default_headers = urllib3.make_headers(proxy_basic_auth='username:password')

然后,创建ProxyManager对象的一个新实例。它将确保所有请求都将使用代理。用仪表板中的详细信息替换代理主机和端口。

http = urllib3.ProxyManager('http://proxy-host:port', proxy_headers=default_headers)

现在您可以调用http对象上的.get()方法来使用代理连接到网站。

url = 'http://books.toscrape.com/media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg'
res = http.request('GET', url)

剩下的代码和没有代理时一样:

def extract_name(url): 
    file_name = url.split("/")[-1]
    return file_name

with open(extract_name(url),'wb') as f:
    f.write(res.data)

下面是完整的脚本代码:

import urllib3

default_headers = urllib3.make_headers(proxy_basic_auth='username:password')
http = urllib3.ProxyManager('http://proxy-host:port', proxy_headers=default_headers)

url = 'http://books.toscrape.com/media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg'

res = http.request('GET', url)

def extract_name(url): 
    file_name = url.split("/")[-1]
    return file_name

with open(extract_name(url),'wb') as f:
    f.write(res.data)

使用 Wget 下载图片

Wget 是一个 Python 库,它封装了一个流行的 Linux 命令行工具,也名为 wget。使用该库,你可以下载各种文件(包括图片),并提供一个与 Python 代码无缝集成的友好界面。

如果你有一个文件的 URL,使用 wget 下载它非常简单。

首先,导入库。

import wget

然后,创建一个变量来保存图像的URL。

url = 'https://books.toscrape.com/media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg'

最后,在URL上运行wget.download()函数来下载图像。

wget.download(url)

为 Wget 使用代理

要了解如何通过代理运行 wget 请求,可以查看我们的 Wget 代理命令行教程。并且,要了解如何通过 Python 调用 CLI 工具,可以查看这篇文章


常见问题

我无法打开使用 Python 下载的图片,该怎么办?

这个 bug 可能来自多种问题,但主要原因可能是你使用了错误的文件扩展名来保存图片。这将创建一个看似图像格式的文件,但实际上不可读,就像将文本文件重命名为 img.jpg 一样。

TypeError: ‘module'对象不可调用

如果你使用的是旧版本的 urllib3,不支持简洁的请求语法,这个错误可能会发生。要解决这个问题,可以升级库到最新版本或按照用户指南中描述的方式创建 PoolManager 来处理请求。

隧道连接失败:407 Proxy Authentication Required

这个错误意味着你在抓取时未能成功认证代理提供商。这是一个常见的问题,解决方法是按照我们的指导一步步使用 urllib3 的代理。


结    论

借助本文中描述的任意工具,在 Python 中下载图片都相对容易。 具体库的选择并不重要,所以最好选择你已经使用的工具。但是,如果你刚刚开始,我们推荐使用 Requests,因为它易于使用,并且在许多其他基于 Web 的 Python 任务中都非常有用。

Written by 河小马

河小马是一位杰出的数字营销行业领袖,广告中国论坛的重要成员,其专业技能涵盖了PPC广告、域名停放、网站开发、联盟营销以及跨境电商咨询等多个领域。作为一位资深程序开发者,他不仅具备强大的技术能力,而且在出海网络营销方面拥有超过13年的经验。