爬虫实战——结合多进程、线程池爬取多张图片

需求描述

需求:结合多进程和线程池,下载一个图片网站某一页的全部图片 将上述需求分为两个进程执行:

  • 进程1、获取图片下载地址;
  • 进程2、根据图片下载地址下载图片(下载图片的时候使用线程池)

代码实现

python 复制代码
import requests
from urllib import parse
from lxml import etree
# 多进程中的队列用于在不同的进程中传递信息
from multiprocessing import Process, Queue
from concurrent.futures import ThreadPoolExecutor


def get_img_url(q):
    """
    从图片详情页获取图片下载地址
    """
    # 图片首页网页链接
    url = 'https://m.mms591.com/filter.php?q=dongwu_zhiwu-0-0-755-2'
    resp_img = requests.get(url)
    # print(resp_img.text)
    # 用xpath解析网页,获取每个图片详情页的url
    tree = etree.HTML(resp_img.text)
    hrefs = tree.xpath('//div[@class="am-list-news-bd"]//a/@href')
    for href in hrefs:  # 每一个href是图片详情页的链接
        # print(href)
        # 拼接图片详情页链接
        href = parse.urljoin(url, href)
        # print(href)
        # 向图片详情页url发送请求,获取图片的下载地址
        child_resp = requests.get(href)
        child_tree = etree.HTML(child_resp.text)
        # 从HTML页面中解析出图片下载地址
        img_src = child_tree.xpath('/html/body/div[3]/div[2]/article/div[1]/a/img/@src')[0]
        # print(img_src)
        # 将图片下载地址放入到队列中
        q.put(img_src)
        print(f'获取图片地址{img_src}成功')
    # 向队列中添加一个表示结束的标志,否则下载图片的进程将会一直处于阻塞状态,不能结束程序
    q.put('over!')


def downloading(img_src):
    # 下载图片
    name = img_src.split("/")[-1]  # 图片名称
    with open(f'./img/{name}', mode='wb') as f:
        resp = requests.get(img_src)
        f.write(resp.content)
    print(f'{name}下载完成')


def download_img(q):
    # 用线程池下载图片
    with ThreadPoolExecutor(3) as t:
        while True:
            # 从队列中取出图片下载地址
            # 如果队列为空,就会一直阻塞,直到队列中有值
            img_src = q.get()
            if img_src == 'over!':  # 图片已经全部下载完成,结束程序运行
                break
            # 提交任务
            t.submit(downloading, img_src)


if __name__ == '__main__':
    # 由于进程之间的内存、资源是相互隔离的,所以两个进程之间不能直接通信,要通过队列等方式才能传递信息
    q = Queue()
    p1 = Process(target=get_img_url, args=(q,))
    p2 = Process(target=download_img, args=(q,))
    p1.start()
    p2.start()
相关推荐
码界筑梦坊28 分钟前
120-基于Python的食品营养特征数据可视化分析系统
开发语言·python·信息可视化·数据分析·毕业设计·echarts·fastapi
logo_2838 分钟前
Xpath语法规则的学习和使用
javascript·python·xpath·xpath语法
快乐江湖1 小时前
「层层包装」—— 装饰器模式
开发语言·python·装饰器模式
m0_702036532 小时前
mysql如何通过索引减少行锁范围_mysql索引与加锁逻辑
jvm·数据库·python
用户0332126663672 小时前
使用 Python 设置 Word 文档文本的颜色
python
qxwlcsdn2 小时前
如何用 IndexedDB 存储从 API 获取的超大列表并实现二级索引
jvm·数据库·python
小新同学^O^2 小时前
简单学习 --> 模型微调
开发语言·人工智能·python·模型微淘
2301_809244533 小时前
C#怎么使用协变和逆变 C#泛型中的in和out关键字协变逆变是什么意思怎么用【语法】
jvm·数据库·python
知识汲取者3 小时前
巨量引擎营销 API 完整文档
开发语言·数据库·python
DevnullCoffe3 小时前
用 MCP 让 AI Agent 直接批量下载亚马逊商品图片——原理、踩坑与实现
爬虫·python·api