如何使用 Python 从雅虎图片中抓取图片

评论: 0

在生成图像数据集时,从雅虎图像搜索中抓取图像非常重要。本指南介绍了如何使用 Python 以及 Requests 库结合 lxml HTML 解析技术从雅虎图片搜索中抓取图片。它还涉及代理的使用,以避免被雅虎僵尸检测系统捕获。

所需工具和程序库

要从 Yahoo Images 搜刮图片,您需要以下 Python 库:

  • Requests: 用于发出 HTTP 请求。
  • lxml: 用于解析 HTML。
  • Proxies: 用于在大范围刮擦时避免 IP 禁止。

安装第三方库

确保已安装所有必要的库。使用 pip 安装它们:

pip install requests
pip install lxml

或者使用单一命令:

pip install requests lxml

使用 Python 进行刮擦的分步指南

首先,我们需要导入刮板所需的库。

import requests
from lxml import html

执行雅虎图片搜索

接下来,我们在雅虎图片上进行搜索。

在这里,我们将把搜索查询定义为小狗,并向雅虎图片搜索发送一个 GET 请求,其中包含必要的标头。请求头对于模仿浏览器请求非常重要,有助于绕过一些基本的僵尸检测机制。

# 定义标头以模拟浏览器请求
headers = {
    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "accept-language": "en-IN,en;q=0.9",
    "cache-control": "max-age=0",
    "dnt": "1",
    "priority": "u=0, i",
    "sec-ch-ua": '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"Linux"',
    "sec-fetch-dest": "document",
    "sec-fetch-mode": "navigate",
    "sec-fetch-site": "none",
    "sec-fetch-user": "?1",
    "upgrade-insecure-requests": "1",
    "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
}

# 定义搜索查询
search_query = "puppies"

# 向雅虎图片搜索页面发出 GET 请求
response = requests.get(
    url=f"https://images.search.yahoo.com/search/images?p={search_query}",
    headers=headers
)

使用 lxml 解析图像 URL

收到雅虎的回复后,我们需要解析 HTML 以提取图片 URL。为此,我们使用了 lxml。

# 解析 HTML 响应
parser = fromstring(response.text)

# 使用 XPath 提取图像 URL
images_urls = parser.xpath("//li[contains(@id, 'resitem-')]/a//@src")

函数 fromstring 用于解析 HTML 响应文本。Xpath 用于提取图像的 URL。下面的截图显示了如何获取 xpath。

yaho.png

下载图片

有了图片 URL 列表,我们现在需要下载每张图片。

在此,我们将循环浏览 images_urls 列表,以提取计数(索引)和 url(地址)。然后,我们将向相应的 url 发送 GET 请求,下载每张图片。

# 下载每张图片并保存到文件中
for count, url in enumerate(images_urls):
    response = requests.get(url=url, headers=headers)

保存图像

最后,我们将下载的图像保存到本地文件系统。我们定义了一个函数 download_file,用于处理文件保存过程。

该函数接收计数(创建唯一文件名)和响应(包含图像数据)。它根据 Content-Type 标头确定文件扩展名,并将文件保存在 ./images/ 目录中。

def download_file(count, response):
    # 从 Content-Type 标头获取文件扩展名
    extension = response.headers.get("Content-Type").split("/")[1]
    filename = "./images/" + str(count) + f".{extension}"

    # 如果目录不存在,则创建该目录
    os.makedirs(os.path.dirname(filename), exist_ok=True)

    # 将响应内容写入文件
    with open(filename, "wb") as f:
        f.write(response.content)

通过在循环中调用该函数,我们可以保存下载的每张图片:

for count, url in enumerate(images_urls):
    response = requests.get(url=url, headers=headers)
    download_file(count, response)

雅虎的僵尸检测机制

从雅虎抓取数据时,一定要注意雅虎的僵尸检测机制。雅虎主要使用这些技术来识别和阻止自动机器人:

  • IP 速率限制:雅虎监控来自单个 IP 地址的请求率。来自一个 IP 的过多请求可能导致临时或永久封禁。
  • 验证码:雅虎可能会对用户使用验证码,以验证其是否为人类。

使用代理服务器逃避检测

为了避免被雅虎机器人检测机制拦截,特别是当从同一个 IP 提出多个请求时,我们使用代理服务器来掩盖我们的 IP 地址。

通过不同的代理服务器路由我们的请求,我们可以在多个 IP 地址上分布我们的刮擦活动,从而降低被检测到的概率。

proxies = {
    'http': 'http://USER:PASS@HOST:PORT',
    'https': 'http://USER:PASS@HOST:PORT'
}
response = requests.get(url, headers=headers, proxies=proxies, verify=False)

完整代码

以下是使用代理从雅虎图片搜索结果中抓取图片的完整脚本:

import os
import requests
from lxml.html import fromstring


def download_file(count, response):
    """
    将响应内容保存到 ./images/ 目录中的文件。

    Args:
        count (int): 文件的唯一标识符。
        response (requests.Response): 包含文件内容的 HTTP 响应。

    """
    # 从 Content-Type 标头获取文件扩展名
    extension = response.headers.get("Content-Type").split("/")[1]
    filename = "./images/" + str(count) + f".{extension}"

    # 如果目录不存在,则创建该目录
    os.makedirs(os.path.dirname(filename), exist_ok=True)

    # 将响应内容写入文件
    with open(filename, "wb") as f:
        f.write(response.content)


def main():
    """
   主要功能是搜索和下载图片。

    该功能执行以下步骤:
    1.设置请求标头。
    2.在 Yahoo 上搜索小狗的图片。
    3.解析 HTML 响应,提取图片 URL。
    4.下载每张图片并将其保存到 ./images/ 目录中。

    """
    # 定义标头以模拟浏览器请求
    headers = {
        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
        "accept-language": "en-IN,en;q=0.9",
        "cache-control": "max-age=0",
        "dnt": "1",
        "priority": "u=0, i",
        "sec-ch-ua": '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": '"Linux"',
        "sec-fetch-dest": "document",
        "sec-fetch-mode": "navigate",
        "sec-fetch-site": "none",
        "sec-fetch-user": "?1",
        "upgrade-insecure-requests": "1",
        "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
    }

    # 定义代理以绕过速率限制
    proxies = {"http": "http://USER:PASS@HOST:PORT", "https": "http://USER:PASS@HOST:PORT"}

    # 定义搜索查询
    search_query = "puppies"

    # 向雅虎图片搜索页面发出 GET 请求
    response = requests.get(
        url=f"https://images.search.yahoo.com/search/images?p={search_query}",
        headers=headers,
        proxies=proxies,
        verify=False
    )

    # 解析 HTML 响应
    parser = fromstring(response.text)

    # 使用 XPath 提取图像 URL
    images_urls = parser.xpath("//li[contains(@id, 'resitem-')]/a//@src")

    # 下载每张图片并保存到文件中
    for count, url in enumerate(images_urls):
        response = requests.get(url=url, headers=headers, proxies=proxies, verify=False)
        download_file(count, response)


if __name__ == "__main__":
    main()

使用 Python 从雅虎图片搜索中抓取图片是一项强大的技术,可自动执行数据收集和分析任务。通过利用用于 HTTP 请求的 Requests 库和用于 HTML 解析的 lxml 库,您可以高效地提取图片 URL 并下载图片。在进行大量搜索活动时,使用代理服务器可帮助您避免被发现并防止 IP 禁止。

评论:

0 评论