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

需求描述

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

  • 进程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()
相关推荐
步辞几秒前
css伪类选择器-nth-child应用技巧_循环选择列表或表格行的实现方法
jvm·数据库·python
xcbrand1 小时前
快消品品牌策划公司哪家好
大数据·人工智能·python
2301_803875611 小时前
Python怎么计算NumPy数组的切比雪夫距离_使用abs与max求解
jvm·数据库·python
Dxy12393102161 小时前
Python使用XPath定位元素:动态计算与函数调用
开发语言·python
qq_349317481 小时前
CSS如何实现Bootstrap进度条自定义动画_利用keyframe关键帧
jvm·数据库·python
wltx16881 小时前
海外版GEO优化适合耳机出口吗?
人工智能·python
vonlycn2 小时前
PaddleDetection转ONNX 填坑
python·onnx·paddledetection
2401_871492852 小时前
Python机器学习怎么防止数据泄漏_确保Scaler在Pipeline内拟合
jvm·数据库·python
2301_818008442 小时前
MySQL怎样在触发器中引用新旧数据行_NEW与OLD关键字详解
jvm·数据库·python
毕胜客源码3 小时前
卷积神经网络的农作物识别系统(有技术文档)深度学习 图像识别 卷积神经网络 Django python 人工智能
人工智能·python·深度学习·cnn·django