爬虫学习--15.进程与线程(2)

线程锁

当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制 某个线程要更改共享数据时,先将其锁定,此时资源的状态为"锁定",其他线程不能改变,只到该线程释放资源,将资源的状态变成"非锁定",其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。

创建锁
mutex = threading.Lock()
​
锁定
mutex.acquire()
​
解锁
mutex.release()

Queue线程

在线程中,访问一些全局变量,加锁是一个经常的过程。如果你是想把一些数据存储到某个队列中,那么Python内置了一个线程安全的模块叫做queue模块。Python中的queue模块中提供了同步的、线程安全的队列类,包括FIFO(先进先出)队列Queue,LIFO(后入先出)队列LifoQueue。这些队列都实现了锁原语(可以理解为原子操作,即要么不做,要么都做完),能够在多线程中直接使用。可以使用队列来实现线程间的同步。

初始化Queue(maxsize):创建一个先进先出的队列。
empty():判断队列是否为空。
full():判断队列是否满了。
get():从队列中取最后一个数据。
put():将一个数据放到队列中。

生产者与消费者模式

生产者和消费者模式是多线程开发中常见的一种模式。通过生产者和消费者模式,可以让代码达到高内聚低耦合的目标,线程管理更加方便,程序分工更加明确。 生产者的线程专门用来生产一些数据,然后存放到容器中(中间变量)。消费者在从这个中间的容器中取出数据进行消费

使用单线程下载表情包

 

import re
import requests
from urllib.request import urlretrieve
from lxml import etree
"""
将http://www.godoutu.com/face/hot/page/1.html下10页数据的表情包全部抓取
print(45*1801)  8w多条数据 
图片数据 二进制  
保存   
with open  wb模式  
urllib
找到图片的路径  图片名字  
"""
for i in range(1,2):
    url = f'http://www.godoutu.com/face/hot/page/{i}.html'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36'
    }
    response = requests.get(url, headers=headers)
    response.encoding = 'utf-8'
    html = response.text
    # print(html)
    # xpath对象
    element = etree.HTML(html)
    alldiv = element.xpath('//div[@class="ui segment imghover"]/div[@class="tagbqppdiv"]')
    # print(alldiv,len(alldiv))
    for j in alldiv:
        everyhref = j.xpath('./a/img/@data-original')[0]
        # print(everyhref)
        title = j.xpath('./a/@title')[0]  # 必须要是合法的
        # print(title)
        newtitle = re.sub('[\/:*?<>|]','',title)
        # print(type(newtitle),type(everyhref))
        # 保存 jpg  gif
        if str(everyhref).endswith('jpg'):
            urlretrieve(everyhref,f'images/{newtitle}.jpg')
            print(f'{newtitle}.jpg下载成功!')
        else:
            urlretrieve(everyhref, f'images/{newtitle}.gif')
            print(f'{newtitle}.gif下载成功!')

使用生产者与消费者模式下载表情包

 

import threading
import time
import re
import requests
from lxml import etree
from queue import Queue
from urllib.request import urlretrieve

# 生产者模型
class Producer(threading.Thread):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36'
    }

    def __init__(self, page_queue,img_queue ):  # RuntimeError: thread.__init__() not called
        # 在自写的类中的init中,先初始化Thread
        threading.Thread.__init__(self)  # 或则 super().__init__()
        self.page_queue = page_queue
        self.img_queue = img_queue

    def run(self):
        while True:  # 让我们创建的三个生产者一直工作
            if self.page_queue.empty():
                break
            else:
                url = self.page_queue.get()
                print(url)
            # 获取到了url就可以去解析数据了
            self.Parse_html(url)
    def Parse_html(self,url):
        # 上锁
        lock.acquire()
        # 发请求,获取响应
        res = requests.get(url, headers=self.headers)
        text = res.text
        # 随机延迟
        # time.sleep(random.random())
        # 解析数据,拿真的图片地址
        element = etree.HTML(text)

        # 将获取的所有img标签放到列表里面
        alldiv = element.xpath('//div[@class="ui segment imghover"]/div[@class="tagbqppdiv"]')

        # 解锁
        lock.release()
        # 取出每一个图片的地址
        for j in alldiv:
            everyhref = j.xpath('./a/img/@data-original')[0]
            print(everyhref)
            title = j.xpath('./a/@title')[0]  # 必须要是合法的
            print(title)
            newtitle = re.sub('[\/:*?<>|]', '', title)
            # 将获取到的img_url和title数据存放在另一个队列种然后再交给消费者进行处理
            self.img_queue.put((everyhref,newtitle)) # 用元组打包作为整体进行处理
            # 检测我获取的数据量是否正确
        print(self.img_queue.qsize())

# 消费者模型
class Consumer(threading.Thread):
    def __init__(self, img_queue):  # RuntimeError: thread.__init__() not called
        # 在自写的类中的init中,先初始化Thread
        threading.Thread.__init__(self)  # 或则 super().__init__()
        self.img_queue = img_queue

    def run(self):
        while True:  # 让我们创建的三个生产者一直工作
            if self.img_queue.empty():
                break
            else:
                img_data = self.img_queue.get()  # 元组类型数据
            # 解包
            img_url, filename = img_data
            # 下载操作
            if str(img_url).endswith('jpg'):
                urlretrieve(img_url, f'imagesss/{filename}.jpg')
                print(f'{filename}.jpg下载成功!')
            else:
                urlretrieve(img_url, f'imagesss/{filename}.gif')
                print(f'{filename}.gif下载成功!')

# 程序主入口

if __name__ == '__main__':
    # 创建一把锁
    lock = threading.Lock()

    # 1 将所有的url存放在队列中
    page_queue = Queue()  # 创建一个队列 然后通过put方法存放进去

    #  创建一个存放数据的队列
    img_queue = Queue()  # 同样将这个队列通过init初始化传到生产者模型中

    for i in range(1, 11):
        url = f'http://www.godoutu.com/face/hot/page/{i}.html'
        page_queue.put(url)

    p_list = []
    # 2 创建生产者对象  三个
    for i in range(3):
        t = Producer(page_queue,img_queue)  # 将队列传给生产者处理 那再创建对象进行传参的过程中我们需要进行接收 init
        t.start()  # 开启多线程   执行的是run方法
        p_list.append(t)

    for p in p_list:
        p.join()

    # 创建三个消费者
    for j in range(3):
        t = Consumer(img_queue)
        t.start()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/16939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux如何设置共享文件夹

打开虚拟机->菜单->虚拟机设置->选项->共享文件夹->总是启用。点击添加按钮->弹出添加向导->点击浏览按钮&#xff0c;从windows中选择一个文件夹&#xff0c;确定即可。

[Windows] GIF动画、动图制作神器 ScreenToGif(免费)

ScreenToGif 是开源免费的 Gif 动画录制工具&#xff0c;小巧原生单文件&#xff0c;功能很实用。它有录制屏幕、录制摄像头、录制画板、图像编辑器等功能&#xff0c;可以将屏幕任何区域及操作过程录制成 GIF 格式的动态图像。保存前还可对 GIF 图像编辑优化&#xff0c;支持自…

研二学妹面试字节,竟倒在了ThreadLocal上,这是不要应届生还是不要女生啊?

一、写在开头 今天和一个之前研二的学妹聊天&#xff0c;聊及她上周面试字节的情况&#xff0c;着实感受到了Java后端现在找工作的压力啊&#xff0c;记得在18&#xff0c;19年的时候&#xff0c;研究生计算机专业的学生&#xff0c;背背八股文找个Java开发工作毫无问题&#x…

抖音里卖什么最赚钱?4个冷门的高利润商品,还有谁不知道!

哈喽~我的电商月月 做抖音小店的新手朋友&#xff0c;一定很想知道&#xff0c;在抖音里卖什么最赚钱&#xff1f; 很多人都会推荐&#xff0c;日常百货&#xff0c;小风扇&#xff0c;女装&#xff0c;宠物用品等等&#xff0c;这些商品确实很好做&#xff0c;你们可以试试 …

备忘录可以统计字数吗?备忘录里在哪查看字数?

在这个信息爆炸的时代&#xff0c;很多人喜欢使用备忘录app来记录生活中的点点滴滴。备忘录不仅可以帮助我们记事、安排日程&#xff0c;还能提醒我们完成各种任务&#xff0c;是我们日常生活中不可或缺的小助手。 然而&#xff0c;在使用备忘录时&#xff0c;有时我们会遇到需…

不用BookStack的企业都在用什么知识库软件

现如今&#xff0c;越来越多的企业使用知识库软件对企业内部知识进行管理。BookStack作为一款功能强大的开源知识库软件&#xff0c;成为很多企业的首选。但是还是有一部分人群认为BookStack不适合他们的企业那么他们都是在用什么别的知识库软件呢&#xff1f;LookLook同学今天…

《python本机环境多版本切换》-两种方式以及具体使用--venv/pyenv+pycharm测试

阿丹&#xff1a; source myenv/bin/activate 在开发使用rasa的时候发现自己安装的python环境是3.12的&#xff0c;和rasa不兼容&#xff0c;所以实践一下更换多python环境。 使用虚拟环境 在Python中使用虚拟环境来切换Python版本是一个常见的做法&#xff0c;这可以帮助你…

实用篇| huggingface网络不通

之前文章《Transformer原理》中介绍过,Transformers 是由 Hugging Face 开发的一个包&#xff0c;支持加载目前绝大部分的预训练模型。随着 BERT、GPT 等大规模语言模型的兴起&#xff0c;越来越多的公司和研究者采用 Transformers 库来构建应用。 Hugging Face是一家美国公司…

Easy IP + DNAT(服务器NAT转换)

第一章 Easy IP 1.1 一般家庭和企业使用的地址转换方式 直接使用出接口的地址做转换Easy IP适用于小规模居于网中的主机访问Internet的场景如&#xff1a;家庭、小型网吧、小型办公室中&#xff0c;这些地方内部主机不多&#xff0c;出接口可以通过拨号方式获取一个临时公网I…

视频监控汇聚平台LntonCVS通过GB/T28181国标协议实现视频监控平台的级联方案

近年来&#xff0c;随着网络视频监控应用范围的拓展&#xff0c;越来越多的政府部门和跨区域行业单位对视频监控的需求已经不局限于本地联网监控。他们正在探索在原有的本地联网监控基础上&#xff0c;建设省级乃至全国范围内的跨区域监控联网&#xff0c;以全面打造数据共享平…

BUUCTF靶场[Reverse]内涵的文件、新年快乐

[reverse]内涵的文件 文件运行看一下 老规矩&#xff0c;拿到文件先用DIE查有没有壳 没有壳&#xff0c;且是一个32位的文件&#xff0c;用相对应的IDA打开 &#xff0c;有主函数&#xff08;mian&#xff09;&#xff0c;先点开 这里点开&#xff08;mian_0&#xff09;,发现…

【详细介绍WebKit的结构】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

Samtec技术漫谈 | 电动自行车中的传感器和信号传输技术

【摘要/前言】 电动自行车&#xff0c;大家熟悉吗&#xff1f; 今天的话题似乎是可以唤起大家心底骑车的美好回忆&#xff0c;我们也曾骑车探索过大自然和社区&#xff0c;自行车也是我们曾经不可或缺的便捷交通工具。 怀旧思潮的影响&#xff0c;加持科技的进步&#xff0c…

【云原生】Kubernetes中的List-Watch机制详解与容器生命周期

目录 引言 一、List-Watch机制概述 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;工作机制 1.List操作 2.Watch操作 &#xff08;三&#xff09;数据流向 1.按模块划分 2.按整体总结 二、Pod生命周期 &#xff08;一&#xff09;生命周期 1.创建…

5款好用的AI写作软件,一键生成高质量文章

在当今信息快速发展的时代&#xff0c;AI写作软件逐渐成为创作者们的得力助手。它们能够凭借先进的技术和算法&#xff0c;一键生成高质量的文章&#xff0c;为创作者们节省大量的创作时间和精力。以下是5款备受好评的AI写作软件&#xff0c;下面在本文中分享给大家&#xff0c…

kettle学习之表的输入输出

需求 把表A里的数据传送到表B中&#xff0c;在此之前&#xff0c;清空表B内的数据 表输入 执行SQL脚本 表输出

一文带你学会如何部署个人博客到云服务器,并进行域名备案与解析!

哈喽&#xff0c;大家好呀&#xff01;这里是码农后端。之前我给大家介绍了如何快速注册一个自己的域名&#xff0c;并创建一台自己的阿里云ECS云服务器。本篇将介绍如何将个人博客部署到云服务器&#xff0c;并进行域名备案与解析。 1、域名备案 注册了域名并购买了云服务器之…

探索自动化办公的新境界:批量操作与智能管理

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、自动化办公的必要性与价值 二、基础操作与自动化脚本 三、Python在自动化办公中的应用…

Meme币总市值突破630亿美元 以太坊ETF获批意味着代币化资产“完全安全”

近日&#xff0c;数字货币市场再次掀起轩然大波。一方面&#xff0c;Meme币总市值突破了630亿美元&#xff0c;令人瞠目结舌&#xff1b;另一方面&#xff0c;以太坊ETF的获批也引发了市场的广泛关注&#xff0c;被视为代币化资产的“完全安全”标志。 Meme币总市值飙升 Meme币…

深圳比创达电子EMC|EMC电磁兼容性行业:挑战与机遇并存

随着电子技术的迅猛发展&#xff0c;电磁兼容性&#xff08;EMC&#xff09;已成为各行各业不可忽视的关键问题。EMC是指设备或系统在其电磁环境中能正常工作且不对该环境中任何事物构成不能承受的电磁骚扰的能力。 一、EMC电磁兼容性行业的现状 EMC电磁兼容性行业作为电子技…