python - 安全存储多线程网络抓取数据

标签 python multithreading csv selenium queue

我正在使用 selenium 进行网页抓取,然后尝试将数据存储到 CSV 文件中。我正在与工作人员一起使用队列,以便使抓取操作更快。

但是,我发现有时一个工作人员会写入 CSV,然后另一个工作人员会尝试写入 CSV,导致数据溢出到新行。

有没有一种安全的方法可以让多个工作人员同时写入 CSV(或其他文件类型)?

这是我的工作人员和队列:

def worker():
while True:
    params = q.get()
    crawl(*params)
    q.task_done()

q = Queue()

for i in range(7):
    t = Thread(target=worker)
    t.daemon = True
    t.start()

每次调用“crawl”时,工作人员都会向 CSV 文件写入一行,然后关闭 CSV:

data_fd = open('data.csv','a')
data_fd.write(line)
data_fd.close()

但是,当一个工作人员在另一个工作人员完成写入 CSV 之前尝试写入 CSV 时,有时会发生以下情况:

item_1, item_2, item_3, item_4
item_1, item_2, item_3, 
item_1, item_2, item_3, item_4 
item_4

最佳答案

您可以采取两种不同的方法...

1)您以某种方式“锁定”文件 - 在操作系统级别上没有必要(您可以在写入文件之前获取一个监视器并在最后释放,这样在任何时间点,只有一个线程持有监视器并写入文件)。

2) 您可以拆分一个单独的线程,专门用于将数据写入 csv。您的爬网程序线程会抓取数据并将其附加到队列中。 csv 线程不断从队列中读取数据并将数据写入磁盘。

两种方法都有其优点 - 第一种方法可能效率较低,但更容易处理。第二种方法需要考虑队列可以增长多大(以防 csv 写入速度比抓取慢),并确保在退出应用程序之前队列已耗尽:)

关于python - 安全存储多线程网络抓取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35641901/

相关文章:

c++ - Qt多线程: How to append few QRunnable tasks to QThreadPool

c# - 多线程:限制并发线程数

java - 分割字符串时使用哪个分隔符

java - 从 JSP 读取 CSV 文件

javascript - 在 python selenium 中使用 JS 脚本向下滚动

python - 向 Pyramid 下的 jinja2 添加自定义过滤器

python - 在不添加到菜单(或工具栏)的情况下使用 QAction

python - 来自两个列表的随机元素 - Python

java - 包含 CSV 文件数据的 Arraylist 充满了空值?

java - System.out.println 的多线程输出是否交错