zoukankan      html  css  js  c++  java
  • 斗图啦+多线程(队列)

    import threading
    import requests
    from lxml import etree
    import time
    import os
    from queue import Queue  #引入队列消除线程执行过程的无序性  和上锁解锁机制一样 的作用
    
    
    #先用os模块创建一个文件夹
    name = os.getcwd()
    file = name + os.sep + '斗图啦'
    if not os.path.exists(file):  # 如果存在文件不存在创建
        os.mkdir(file)  # 在当前目录下创建一个文件夹
    
    class Producer(threading.Thread):#生产者函数,用来保存生产的队列,继承多线程模块
        def __init__(self,page_queue,img_queue,*args,**kwargs):
            #*args,**kwargs是python中的可变参数。*args表示任何多个无名参数,它是一个tuple,表示可接受任何位置的参数;**kwargs表示关键字参数,它是一个dict
            self.header = {
                'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4094.1 Safari/537.36',
                'Referer': 'http://www.doutula.com/photo/list/',
                }
            super(Producer,self).__init__(*args,**kwargs)
            self.img_queue=img_queue
            self.page_queue=page_queue
    
        def page(self,url):
            print(url)
            response=requests.get(url,headers=self.header).text
            html = etree.HTML(response)  # 初始化源代码,只能对字符串处理
            # print(type(html))
            images = html.xpath('//div[@class="page-content text-center"]//img[@class != "gif"]')
            for imgs in images:
                name = imgs.get('alt')
                img_url = imgs.get('data-original')  # 也可以用数组的方式 因为xpath返回的是列表格式的数据
                self.img_queue.put((name,img_url))  #添加到队列中  向后插入数据
            print('该涨图片地址插入成功!')
    
        def run(self):
            #提取出队列中的pagr_url    .get()方法在队列中是删除第一个参数并返回
            while True:
                if self.page_queue.empty():    #当表为空时候 就跳出循环
                    break
                url=self.page_queue.get()
                #没提取一页的网址 传入到解析的函数中,进行解析
                self.page(url)
    
    
    class Consumer(threading.Thread):   #消费者
        def __init__(self,page_queue,img_queue,*args, **kwargs):
            self.header = {
                'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.4094.1 Safari/537.36',
                'Referer': 'http://www.doutula.com/photo/list/',
            }
            super(Consumer, self).__init__(*args, **kwargs)
            self.page_queue=page_queue
            self.img_queue = img_queue
    
        def run(self):
            # print(self.img_queue.get())
            while True:
                if self.img_queue.empty() and self.page_queue.empty():   #当图片地址和页数地址表为空时候 就跳出循环
                    break
                name,img_url= self.img_queue.get()
                name=name.replace('?','')  #3文件名带?会有问题
                with open(file+os.sep+name+'.jpg','wb') as f:
                    img = requests.get(img_url, headers=self.header).content
                    # img = requests.get(img_url,headers=self.header).content   #用requests请求图片的url  让以.content保存他
                    f.write(img)
                    f.close()
                    print('%s保存成功!'%name)
    
    
    def main(page):
        #创建一个保存页面的page_queue队列 和保存img_queue的元组(name,img_url)的队列
        page_queue=Queue(page)
        img_queue=Queue(100)
        for i in range(1,page+1):
            url = 'http://www.doutula.com/photo/list/?page='+str(i)
            page_queue.put(url)
        for x in range(5):   #创建5个生产者线程
            producer=Producer(page_queue,img_queue)
            #线程的开始运行
            producer.start()
    
        for y in range(5):  #创建5个消费者线程
            consumer=Consumer(page_queue,img_queue)
            consumer.start()
    
    if __name__=='__main__':
        main(8)
    

      

  • 相关阅读:
    DirectUI精髓之一 控件布局的自动缩放(弹簧特性)
    windows mobile6.5截屏工具
    实现的ATL(AtlSimpleArray)数组任意插入辅助函数
    动态库中单例一记
    ASP.NET组件设计Step by Step(4)
    Asp.net 中服务端控件事件是如何触发的
    PagesSection.EnableEventValidation 属性
    ASP.NET事件回传机制
    (服务器控件)页面框架处理回发数据的过程
    ASP.NET底层架构
  • 原文地址:https://www.cnblogs.com/hum0ro/p/9601808.html
Copyright © 2011-2022 走看看