Python爬虫实战:批量下载网站图片 📸

在这篇文章中,我们将深入探索如何使用Python编写一个爬虫程序,目的是从特定网站上批量下载图片。我们选定的目标网站是一个充满丰富图片资源的网站,我们的任务是高效地下载这些资源。本指南不仅适合初学者入门,也适用于希望提升Python爬虫技能的进阶读者。我们将从基础开始,逐步深入,最终实现一个并发下载图片的高效爬虫。

开篇明义:理解任务与挑战 🚀

网络爬虫是数据科学和自动化任务中的重要工具。通过编写爬虫,我们可以从互联网上收集到大量的数据和资源。本教程的目标网站提供了海量的图片资源,这些资源通常被用于学术研究、设计项目、或个人收藏等多种用途。然而,手动下载这些图片既耗时又低效,因此我们需要一个自动化的解决方案。

准备工作:环境搭建与依赖安装 🛠️

在开始编写代码之前,请确保你的Python环境已经安装了以下库:

  • requests:用于发送网络请求。
  • lxml:一个强大的HTML/XML解析库。
  • multiprocessing:Python中的多进程管理库。

如果你还没有安装这些库,可以通过运行pip install requests lxml来安装它们。

步骤一:解析网页获取图片链接 🔍

我们首先需要分析目标网站的结构,找到图片存储的规律,然后编写函数获取图片链接。这里我们使用requests获取网页内容,然后用lxml解析HTML,提取出图片的URL。

步骤二:并发下载提高效率 ⚡

为了提高下载效率,我们将采用多进程的方式进行并发下载。multiprocessing库让这个任务变得简单。我们将为每个图片下载任务创建一个进程,这样可以显著提高下载速度。

动手实践:编写爬虫代码 📝

接下来,我们将一步步编写爬虫代码,从获取图片列表到并发下载图片,每一步都将详细解释代码的功能和逻辑。
在本篇文章中,我们将深入探索如何使用Python进行网络爬虫,以从网站上下载图片。我们的目标网站是一个提供丰富图片资源的网站。本指南将分为几个部分:首先是分析目标网站结构,其次是编写爬虫代码,最后是并发下载图片以提高效率。让我们开始吧!🌟

准备工作 🛠️

在开始编写代码之前,请确保已经安装了requestslxml库。这些库将帮助我们发送HTTP请求和解析HTML内容。

分析目标网站 🕵️‍♂️

我们的目标是下载网站上的图片,这个过程可以分为两个主要步骤:

  1. 从主页面中解析出详情页的URL列表。
  2. 从每个详情页中解析出图片的URL列表。

编写爬虫代码 📜

获取列表页面数据

首先,我们需要获取列表页面的HTML内容,这可以通过requests库实现。

def get_list_data(url):
    response = requests.get(url, headers=headers)
    response.encoding = "gb2312"
    return response.text

解析列表页面

接下来,我们将解析列表页面,获取详情页的URL列表。

def parse_list_data(html):
    tree = etree.HTML(html)
    detail_urls = tree.xpath('//ul[@class="g-gxlist-imgbox"]/li/a/@href')
    return detail_urls

获取并解析详情页面

对于每个详情页,我们首先获取HTML内容,然后解析出图片URL列表。

def get_detail_data(detail_url):
    response = requests.get(prefix_url + detail_url, headers=headers)
    response.encoding = "gb2312"
    return response.text

def parse_detail_data(html):
    tree = etree.HTML(html)
    title, img_urls = tree.xpath('//div[@class="g-cont-detail g-main-bg"]/h1/text()')[0], tree.xpath('//div[@class="m_qmview"]/p/img/@src')
    return title, img_urls

保存图片

最后,我们定义一个函数来保存图片到本地。

def save_data(title, img_urls):
    create_directory(f"./file/image/{title}")
    for img_url in img_urls:
        response = requests.get(img_url, headers=headers)
        with open(f"./file/image/{title}/{img_url[-10:]}", "wb") as f:
            f.write(response.content)
        print(f"图片{img_url[-10:]}保存成功")

并发下载

为了提高下载效率,我们将使用Python的多进程特性。

def main():
    list_html = get_list_data(list_url)
    detail_urls = parse_list_data(list_html)
    processes = []
    for detail_url in detail_urls:
        process = Process(target=process_detail_page, args=(detail_url,))
        processes.append(process)
        process.start()
    for process in processes:
        process.join()

完整代码

"""
准备的爬取地址:https://www.qqtn.com/tp/meinvtp_1.html

分析:
    进程1 : 从主页面中解析出详情页的url列表,从详情页中解析出图片的url列表
    进程2 : 下载图片
    队列:可以进程之间传递数据


"""
import os
import time
from multiprocessing import Process
import requests
from lxml import etree  # xpath解析库

# 前缀
prefix_url = "https://www.qqtn.com/"
# 列表url 每个页面有多个列表 点击进去有详情页 我们要下载详情页的图片
list_url = "https://www.qqtn.com/tp/sgtp_1.html"
# 请求头
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36"
}


# 获取列表页数据
def get_list_data(url):
    response = requests.get(url, headers=headers)
    response.encoding = "gb2312"
    return response.text


# 解析list页面获取到详情url列表
def parse_list_data(html):
    tree = etree.HTML(html)
    detail_urls = tree.xpath('//ul[@class="g-gxlist-imgbox"]/li/a/@href')
    return detail_urls


# 获取详情页数据
def get_detail_data(detail_url):
    prefix_url + detail_url
    response = requests.get(prefix_url + detail_url, headers=headers)
    response.encoding = "gb2312"
    return response.text


# 解析详情页数据获取图片url列表
def parse_detail_data(html):
    tree = etree.HTML(html)
    title = tree.xpath('//div[@class="g-cont-detail g-main-bg"]/h1/text()')[0]  # 只有一个标题
    img_urls = tree.xpath('//div[@class="m_qmview"]/p/img/@src')
    return title, img_urls


def create_directory(directory_path):
    try:
        # 如果目录不存在,则创建它
        if not os.path.exists(directory_path):
            os.makedirs(directory_path)
            print(f"目录 '{directory_path}' 已创建。")
        else:
            print(f"目录 '{directory_path}' 已存在。")
    except Exception as e:
        print(f"创建目录时发生错误: {e}")


# 保存图片
def save_data(title, img_urls):
    # 创建目录
    create_directory(f"./file/image/{title}")
    for img_url in img_urls:
        response = requests.get(img_url, headers=headers)
        with open(f"./file/image/{title}/{img_url[-10:]}", "wb") as f:  # 图片名字 {img_url[-10:]} 截取后10位
            # https://p.qqan.com/up/2023-12/17020933181904416.jpg -> 17020933181904416.jpg
            f.write(response.content)
        print(f"图片{img_url[-10:]}保存成功")
#         关闭文件
        f.close()
        response.close()


def main():
    # 获取列表页HTML
    list_html = get_list_data(list_url)
    # 解析列表页获取详情页URLs
    detail_urls = parse_list_data(list_html)

    processes = []

    for detail_url in detail_urls:
        # 对每个详情页创建一个进程
        process = Process(target=process_detail_page, args=(detail_url,))
        processes.append(process)
        process.start()

    # 等待所有进程完成
    for process in processes:
        process.join()
    # 关闭资源
    for process in processes:
        process.close()


def process_detail_page(detail_url):
    # 获取详情页数据
    detail_html = get_detail_data(detail_url)
    # 解析详情页数据获取图片url列表
    title, img_urls = parse_detail_data(detail_html)
    # 创建目录并保存图片
    save_data(title, img_urls)


if __name__ == '__main__':
    # 计时
    start_time = time.time()
    main()
    end_time = time.time()
    print(f"耗时:{end_time - start_time}")
    # 异步保存耗时:7.585883140563965 对比 同步保存耗时:18.70596742630005


希望这篇文章能帮助你轻松入门Python网络爬虫,并在实际项目中发挥作用。如果有任何问题,欢迎在评论区留言讨论!🚀

免责声明 ⚠️

在使用编写的爬虫程序下载网站内容时,请确保你的行为符合法律法规和网站的使用条款。本教程仅供学习和研究目的,作者不承担任何因滥用爬虫技术而导致的法律责任。

结语 🌟

通过本教程,你将学会如何使用Python编写一个简单而强大的图片下载爬虫,以及如何通过并发下载显著提高下载效率。希望你能将这些技能应用到实际项目中,发挥出它们的最大价值。

如果你觉得这篇文章对你有帮助,请不吝点赞和分享。你的支持是我不断前进和改进的动力!同时,如果有任何问题或建议,欢迎在**评论区留言,**我会尽力回复每一条评论。让我们一起学习,一起进步!

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐