爬蟲學習--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.pswp.cn/bicheng/16939.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/16939.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/16939.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux如何設置共享文件夾

打開虛擬機->菜單->虛擬機設置->選項->共享文件夾->總是啟用。點擊添加按鈕->彈出添加向導->點擊瀏覽按鈕&#xff0c;從windows中選擇一個文件夾&#xff0c;確定即可。

[Windows] GIF動畫、動圖制作神器 ScreenToGif(免費)

ScreenToGif 是開源免費的 Gif 動畫錄制工具&#xff0c;小巧原生單文件&#xff0c;功能很實用。它有錄制屏幕、錄制攝像頭、錄制畫板、圖像編輯器等功能&#xff0c;可以將屏幕任何區域及操作過程錄制成 GIF 格式的動態圖像。保存前還可對 GIF 圖像編輯優化&#xff0c;支持自…

末日設計1.00

故事背景: 在不遠的未來&#xff0c;世界陷入了末日危機。資源枯竭、社會秩序崩潰&#xff0c;幸存者們為了生存&#xff0c;不得不拿起武器爭奪每一寸土地和每一口食物。在這個混亂的世界中&#xff0c;你是一名傳奇狙擊手&#xff0c;憑借超凡的射擊技巧和生存智慧&#xff0…

研二學妹面試字節,竟倒在了ThreadLocal上,這是不要應屆生還是不要女生啊?

一、寫在開頭 今天和一個之前研二的學妹聊天&#xff0c;聊及她上周面試字節的情況&#xff0c;著實感受到了Java后端現在找工作的壓力啊&#xff0c;記得在18&#xff0c;19年的時候&#xff0c;研究生計算機專業的學生&#xff0c;背背八股文找個Java開發工作毫無問題&#x…

本地圖形客戶端查看git提交歷史 使用 TortoiseGit

要在本地查看提交記錄和修改歷史&#xff0c;可以使用 TortoiseGit 和 Git-SCM。這兩個工具都提供了強大的功能來管理和查看 Git 倉庫中的提交記錄和歷史修改。 使用 TortoiseGit 查看提交記錄和修改歷史 查看提交記錄&#xff08;Log&#xff09;&#xff1a; 右鍵點擊項目文…

抖音里賣什么最賺錢?4個冷門的高利潤商品,還有誰不知道!

哈嘍~我的電商月月 做抖音小店的新手朋友&#xff0c;一定很想知道&#xff0c;在抖音里賣什么最賺錢&#xff1f; 很多人都會推薦&#xff0c;日常百貨&#xff0c;小風扇&#xff0c;女裝&#xff0c;寵物用品等等&#xff0c;這些商品確實很好做&#xff0c;你們可以試試 …

Euraka詳解:實現微服務架構的關鍵組件

在當今互聯網時代&#xff0c;微服務架構已經成為許多企業構建和部署應用程序的首選方法之一。而要在微服務架構中實現高可用性和靈活性&#xff0c;服務發現和注冊是至關重要的一環。Eureka作為Netflix開源的服務發現組件&#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;這可以幫助你…

Minikube部署單節點Kubernetes

1.1 Minikube部署單節點K8s Minikube是由Kubernetes社區維護的單機版的Kubernetes集群&#xff0c;支持macOS, Linux, andWindows等多種操作系統平臺&#xff0c;使用最新的官方stable版本&#xff0c;并支持Kubernetes的大部分功能&#xff0c;從基礎的容器編排管理&#xff0…

實用篇| 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…

2.Nginx上配置圖片訪問

在 Nginx 上配置圖片訪問涉及到在 Nginx 配置文件中添加相應的 location 塊來處理圖片請求。以下是一個基本的示例&#xff0c;演示如何配置 Nginx 以便在指定目錄中存儲和訪問圖片。 1.上傳圖片到服務器 首先&#xff0c;將你的圖片上傳到服務器的某個目錄&#xff0c;例如 …

視頻監控匯聚平臺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;,發現…

Kotlin基礎之基本語法

Kotlin 簡介 Kotlin 是一種由 JetBrains 開發的靜態類型編程語言&#xff0c;設計用于與 Java 虛擬機 (JVM) 兼容&#xff0c;同時也可用于 Android、JavaScript&#xff08;通過 Kotlin/JS&#xff09;和原生&#xff08;通過 Kotlin/Native&#xff09;開發。Kotlin 旨在提供…

【詳細介紹WebKit的結構】

&#x1f3a5;博主&#xff1a;程序員不想YY啊 &#x1f4ab;CSDN優質創作者&#xff0c;CSDN實力新星&#xff0c;CSDN博客專家 &#x1f917;點贊&#x1f388;收藏?再看&#x1f4ab;養成習慣 ?希望本文對您有所裨益&#xff0c;如有不足之處&#xff0c;歡迎在評論區提出…

springboot + es7.12.3 elasticsearchRestTemplate使用記錄

private BoolQueryBuilder getQueryBuilder(QueryCollectWaterDataPageRequestVO requestVO) {BoolQueryBuilder queryBuilder QueryBuilders.boolQuery();if (!CollectionUtils.isEmpty(requestVO.getCompanyIds())) {//termsQuery 精確查找corpId字段為精確的多個值&#xf…

T-Sql 中斷正在連接的數據庫的客戶端并移除數據庫

USE master;-- 查找連接到數據庫 OGS_PlugPower 的會話ID&#xff08;SPID&#xff09; DECLARE SessionID INT;SELECT SessionID session_id FROM sys.dm_exec_sessions WHERE database_id DB_ID(OGS_PlugPower);-- 使用會話ID&#xff08;SPID&#xff09;中斷連接 IF Sess…