如何确保Python Queue的线程和进程安全性:使用锁的技巧

ops/2024/10/18 8:35:08/

<a class=爬虫代理.png" />

背景/引言

在Python的并发编程中,Queue(队列)是一种常用的数据结构,特别是在多线程和多进程环境下,Queue能够有效地在不同线程进程之间传递数据。Python提供了queue.Queuemultiprocessing.Queue两种标准实现,分别用于线程进程之间的数据通信。
然而,在爬虫技术中,随着任务复杂度的增加,尤其是涉及到多线程或多进程时,确保Queue线程进程安全性变得至关重要。虽然Python的Queue提供了基本的线程进程安全性,但在某些场景下,如实现“只读”模式或防止数据竞争,还需要额外使用锁(Lock)来确保数据的完整性。
本文将探讨如何在Python中使用锁来保障Queue线程进程安全性,并通过一个使用代理IP、user-agent、cookie、多线程技术的实际爬虫示例,展示如何提高数据采集效率。

正文

Queue_7">1. Queue线程进程安全性

在Python中,queue.Queuemultiprocessing.Queue都提供了基本的线程进程安全性。具体来说,.put().get()方法是线程安全和进程安全的,意味着多个线程进程可以安全地同时调用这些方法而不会引起数据竞争。
然而,其他操作(如遍历队列内容)并没有被保证是安全的。尤其是在需要将队列内容设置为只读时,使用锁是确保数据一致性和防止竞态条件的有效手段。

Queue_10">2. 使用锁实现Queue的安全性

在需要对Queue进行“只读”操作时,可以使用threading.Lockmultiprocessing.Lock来确保在操作期间没有其他线程进程可以修改Queue的内容。下面的代码展示了如何使用锁来确保Queue线程进程安全性。

3. 代理IP、user-agent、cookie设置

在网络爬虫中,使用代理IP、user-agent和cookie是绕过网站反爬措施的常见手段。本文将使用亿牛云爬虫代理服务来设置代理IP,并展示如何在多线程环境下实现高效的数据采集。

实例

以下是一个示例代码,展示了如何在Python中使用锁来确保Queue的安全性,并结合代理IP、多线程技术来实现高效的网页数据采集。

python">import threading
import requests
from queue import Queue
from bs4 import BeautifulSoup# 设置代理IP相关信息(使用亿牛云爬虫代理 www.16yun.cn)
proxy_host = "代理服务器域名"  # 例如:"proxy.einiuyun.com"
proxy_port = "代理服务器端口"  # 例如:"12345"
proxy_username = "代理用户名"  # 例如:"your_username"
proxy_password = "代理密码"  # 例如:"your_password"proxy_url = f"http://{proxy_username}:{proxy_password}@{proxy_host}:{proxy_port}"
proxies = {"http": proxy_url,"https": proxy_url,
}# 设置User-Agent和Cookie
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3","Cookie": "your_cookie_data"  # 这里替换为实际的cookie
}# 初始化队列和锁
queue = Queue()
lock = threading.Lock()# 多线程数据采集函数
def fetch_data(url):with lock:  # 使用锁确保线程安全try:response = requests.get(url, headers=headers, proxies=proxies)if response.status_code == 200:# 将数据放入队列queue.put(response.text)print(f"成功采集数据:{url}")else:print(f"采集失败:{url},状态码:{response.status_code}")except Exception as e:print(f"请求发生错误:{e}")# 解析个人简历信息并存储为文档
def parse_and_save(html_content, resume_id):soup = BeautifulSoup(html_content, 'html.parser')# 假设的简历字段,实际需要根据51job的页面结构进行调整name = soup.find('div', class_='name').text.strip() if soup.find('div', class_='name') else "未提供"contact = soup.find('div', class_='contact').text.strip() if soup.find('div', class_='contact') else "未提供"experience = soup.find('div', class_='experience').text.strip() if soup.find('div', class_='experience') else "未提供"# 构建简历信息文本resume_content = f"姓名: {name}\n联系方式: {contact}\n工作经验: {experience}\n"# 将简历信息保存到文档with open(f'resume_{resume_id}.txt', 'w', encoding='utf-8') as file:file.write(resume_content)print(f"简历 {resume_id} 已保存.")# 多线程爬虫实现
def multi_thread_scraping(url_list):threads = []resume_id = 1for url in url_list:thread = threading.Thread(target=fetch_data, args=(url,))thread.start()threads.append(thread)for thread in threads:thread.join()# 读取Queue内容并处理数据while not queue.empty():html_content = queue.get()parse_and_save(html_content, resume_id)resume_id += 1# 示例URL列表(假设这些URL指向简历页面)
urls = ["https://www.51job.com/resume_example1","https://www.51job.com/resume_example2","https://www.51job.com/resume_example3",# 添加更多简历URL
]# 启动多线程爬虫
multi_thread_scraping(urls)

代码说明:

  1. 代理和请求设置:代码中使用亿牛云爬虫代理,并设置了User-Agent和Cookie以模拟正常用户访问。
  2. 线程采集:使用多线程来提高采集效率,将从51job.com采集到的HTML内容放入队列中。
  3. 简历解析:通过BeautifulSoup解析HTML内容,提取简历信息。这里假设简历包含姓名、联系方式、和工作经验的字段,实际解析时需要根据页面实际结构进行调整。
  4. 保存为文档:将提取的简历信息以文本文件的形式存储,每个简历对应一个文件,文件名格式为resume_x.txt
  5. 线程实现:通过启动多个线程来并发执行数据采集任务,并在队列中依次处理采集到的数据。

结论

在Python中,确保Queue线程进程安全性对于构建高效稳定的爬虫系统至关重要。本文通过一个使用锁的多线程爬虫示例,展示了如何在网络数据采集中使用代理IP、user-agent和cookie,并结合锁机制实现对Queue的安全操作。
通过合理使用锁和多线程技术,可以大幅提升数据采集的效率,同时避免在并发环境下可能出现的数据竞争问题。


http://www.ppmy.cn/ops/104816.html

相关文章

powershell自动提交git脚本

使用 PowerShell 编写一个自动提交 Git 仓库的脚本是一个很好的实践&#xff0c;可以帮助你在开发过程中节省时间并提高效率。下面是一个简单的示例脚本&#xff0c;它将执行以下步骤&#xff1a; 切换到 Git 仓库所在的目录。检查是否有未提交的更改。将所有更改添加到暂存区…

Java Excel转PDF(免费)

目前市面上 Excel 转 PDF 的组件较多&#xff1a; 收费&#xff1a;aspose、GcExcel、spire开源&#xff1a;jacob、itextpdf 其中收费的组件封装得比较好&#xff0c;代码简洁&#xff0c;转换的效果也很好&#xff0c;但收费也高得离谱&#xff1a; 为了成本考虑&#xff…

从向海外学习,到技术出海,中国零部件公司需要几步?

作者 |德新 编辑 |王博 从2008年出海向国际巨头学习汽车零部件的技术&#xff0c;到2024年把中国原创的高精定位技术推给国际车企。 Pia Hu的职业经历&#xff0c;恰好是国内智驾科技崛起的一个缩影。 一、第一批智驾人 2008年&#xff0c;Pia Hu在同济大学汽车学院读书时&…

网络爬虫调研报告

基本原理 Spider概述 Spider即网络爬虫 ,其定义有广义和狭义之分。狭义上指遵循标准的 http协议利用超链接和 Web文档检索的方法遍历万维网信息空间的软件程序 ;而广义的定义则是所有能遵循 http协议检索 Web文档的软件都称之为网络爬虫。 Spider是一个功能很强的自动提取…

ArrayList 和 LinkedList 之间的主要区别。在什么情况下你会选择使用 ArrayList 而不是 LinkedList,反之亦然?

ArrayList 与 LinkedList 的主要区别 在 Java 中&#xff0c;ArrayList 和 LinkedList 是两种常用的集合类&#xff0c;它们都是 List 接口的实现。尽管它们都可以存储一系列元素&#xff0c;但它们在内部实现上有着显著的不同&#xff0c;这也决定了它们在性能上的差异。 Ar…

缓存使用-缓存击穿、穿透、雪崩概念

一、缓存穿透 指查询一个不存在的数据、由于缓存不命中&#xff0c;将查询数据库&#xff0c;但是数据库也无此记录&#xff0c;我们没有将null写入缓存&#xff0c;这将导致这个不存在数据每次请求都会查询数据库&#xff0c;导致缓存失去意义。 风险&#xff1a; 利用不存在…

源代码编译,Apache DolphinScheduler前后端分离部署解决方案

转载自神龙大侠 生产环境部署方案 在企业线上生产环境中&#xff0c;普遍的做法是至少实施两套环境。 测试环境线上环境 测试环境用于验证代码的正确性&#xff0c;当测试环境验证ok后才会部署线上环境。 鉴于CI/CD应用的普遍性&#xff0c;源代码一键部署是必要的。 本文…

CTFHub SSRF靶场通关攻略

内网访问 首先进入环境 在url后面输入 http://127.0.0.1/flag.php访问&#xff0c;得出flag 伪协议读取文件 进入环境后再url后面拼接 file:///var/www/html/flag.php 访问后是&#xff1f;&#xff1f;&#xff1f;&#xff0c;那么我们F12检查源码得出flag 端口扫描 我们进行…