在多线程爬虫中,快速爬取数据并写入CSV文件是一个常见的需求。为了提高效率和避免数据写入冲突,我们可以采用以下策略:

1. 使用线程安全的队列

在多线程环境下,使用线程安全的队列(如 queue.Queue)来管理待写入的数据。每个线程从网络抓取数据后,将数据放入队列中,然后主线程(或使用额外的线程)从队列中取出数据并写入CSV文件。

2. 使用线程锁

为了避免多个线程同时写入CSV文件导致的冲突和数据错乱,可以使用 threading.Lock 来确保每次只有一个线程可以写入文件。

3. 使用concurrent.futures模块

Python的concurrent.futures模块提供了高级的API来处理并发执行,例如ThreadPoolExecutor。这可以简化多线程的管理,并且自动处理线程的创建和销毁。

示例代码

以下是一个使用ThreadPoolExecutorqueue.Queue的多线程爬虫示例,该示例将抓取的数据写入CSV文件:

import csv

import requests

import threading

from queue import Queue

from concurrent.futures import ThreadPoolExecutor

# 定义一个全局队列来存储爬取的数据

data_queue = Queue()

# 定义一个锁来控制CSV文件的写入

csv_lock = threading.Lock()

# 定义一个函数来抓取数据并放入队列

def fetch_data(url):

response = requests.get(url)

if response.status_code == 200:

data = response.json() # 假设返回的是JSON格式的数据

data_queue.put(data)

# 定义一个函数来从队列中读取数据并写入CSV文件

def write_to_csv(filename):

with open(filename, mode='a', newline='', encoding='utf-8') as file:

writer = csv.writer(file)

while True:

try:

data = data_queue.get(timeout=1) # 获取数据,如果队列为空则等待1秒

with csv_lock: # 确保写入操作的线程安全

writer.writerow(data) # 假设每个数据项是一个列表或元组形式

data_queue.task_done() # 表示数据已被处理,减少队列大小计数器

except queue.Empty:

break # 如果队列为空,则退出循环

# 主函数

def main():

urls = ["http://example.com/api/data1", "http://example.com/api/data2"] # 示例URLs列表

filename = "output.csv" # CSV文件名

headers = ["column1", "column2", "column3"] # CSV列标题

with open(filename, mode='w', newline='', encoding='utf-8') as file:

writer = csv.writer(file)

writer.writerow(headers) # 写入列标题

# 使用线程池来并发抓取数据

with ThreadPoolExecutor(max_workers=5) as executor:

executor.map(fetch_data, urls)

# 使用单独的线程来写入CSV文件(可选,也可以用ThreadPoolExecutor)

writer_thread = threading.Thread(target=write_to_csv, args=(filename,))

writer_thread.start()

writer_thread.join() # 等待写入线程完成

data_queue.join() # 等待队列中的所有数据都被处理完毕(可选)

if __name__ == "__main__":

main()

注意事项:

  1. 异常处理:在网络请求和数据写入过程中加入适当的异常处理逻辑,例如使用try-except块。

  2. 资源释放:确保所有打开的文件和数据库连接在使用完毕后正确关闭。

  3. 性能调优:根据实际情况调整max_workers的数量,以达到最优的并发效率。过多的线程可能会因为系统资源竞争而降低性能。

  4. 数据验证:在写入CSV前验证数据的完整性和正确性。

  5. 持久化存储CSV前网络错误,请检查网络状态

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐