多线程下载图片-练手

学习了多线程下载表情包的笔记:

原视频网站:Python多线程下载表情包

整体思路

  • 先获取整个网站的所有页面的url

  • 把所有页面url 和所有图片url 的list, 设置成全局变量 并且要用到全局锁。(在启动多线程时,全局变量会被同时改动,所以要加上全局锁)

  • 用了生产者-消费者模式进行爬虫

  • 设置生产者:循环获取当前页面的所有图片的url,添加到全局变量图片url的list

  • 设置消费者:开始下载图片。


代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import threading
import requests
import urllib
from bs4 import BeautifulSoup
import os

# 要爬的 一个简单网站
PAGE_URL = 'http://www.doutula.com/photo/list/?page='
# 页面 url
PAGE_LIST = []
# 所有图片的 url
EMOJI_LIST = []
# 全局锁
gLock = threading.Lock()

# 循环获取所有页面的url
for i in range(1, 1334):
    url = PAGE_URL + str(i)
    PAGE_LIST.append(url)


# 生产者:获取图片url
def Procuder():
    while True:
        # 加锁
        gLock.acquire()
        if len(PAGE_LIST) == 0:
            # 解锁
            gLock.release()
            break
        else:
            page_url = PAGE_LIST.pop(0)
            gLock.release()

            # 获得url的所有数据
            response = requests.get(page_url)
            content = response.content
            # content = str(content)
            # 解析数据 为 lxml
            soup = BeautifulSoup(content, 'lxml')
            # 根据class找到img的标签
            imagelist = soup.find_all('img', attrs={'class': 'img-responsive lazy image_dta'})
            #
            gLock.acquire()
            for i in imagelist:
                url = i['data-original']
                # 有的图片的url后缀是:xxx.jpg!data
                if url.endswith('!dta'):
                    url = url[:-4]
                EMOJI_LIST.append(url)
            gLock.release()


# 消费者:下载图片
def Customer():
    while True:
        gLock.acquire()
        if len(EMOJI_LIST) == 0:
            gLock.release()
            continue
        else:
            url = EMOJI_LIST.pop(0)
            gLock.release()
            # 把url根据'/' 拆分成多个元素
            split_list = url.split('/')
            # 最后一个就是 图片的名称
            filename = split_list.pop()
            # filename = filename[:-4]
            # 设置现在路径 为当前文件夹下的 images 文件夹
            path = os.path.join('images', filename)
            # 开始 下载
            print filename
            # 自带的下载方法
            urllib.urlretrieve(url, filename=path)


def main():
    # 两个生产者 爬图片url
    for x in range(2):
        th = threading.Thread(target=Procuder)
        th.start()

    # 三个消费者 下载图片
    for x in range(3):
        th = threading.Thread(target=Customer)
        th.start()

if __name__ == "__main__":
    main()

原网站图片的标签:
这里写图片描述

最后:
有可能会报错:Connection reset by peer;

百度了一下是①:服务器的并发连接数超过了其承载量,服务器会将其中一些连接Down掉;
②:客户关掉了浏览器,而服务器还在给客户端发送数据;
③:浏览器端按了Stop
PS:估计是网络的问题,我在测试的时候 有时候是没有报错的。。。(ಥ _ ಥ)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值