You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让两个Python Selenium线程分别读取credentials.txt不同行?

解决多线程读取不同凭证行的问题

问题说明

需要用Python Selenium创建2个线程,每个线程读取credentials.txt中的一行内容作为登录凭证:第一个线程读第一行,第二个线程读第二行。当前代码能启动两个线程,但两个线程始终读取同一行,无法按预期分别读取不同行。

原代码:

import csv
from selenium import webdriver
import time
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from threading import Thread

line_count = 0

def login():
    global line_count
    with open('credentials.txt') as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=':')
        line_count = 0
        for row in csv_reader:
            driver = webdriver.Chrome("C:\\Chromedriver.exe")
            driver.maximize_window()
            driver.get('https://twitter.com/i/flow/login')
            time.sleep(4)
            driver.find_element(By.NAME, "text").send_keys(row[0])
            time.sleep(3)


number_of_threads = 2

threads = []

for number in range(number_of_threads):
    t = Thread(target=login) 
    t.start()
    threads.append(t)

for t in threads:
    t.join()

问题根源

  1. 重复读取文件头部:每个线程都会重新打开credentials.txt并从头开始遍历,所以两个线程都会先拿到文件的第一行内容。
  2. 全局变量失效:每个线程内部都重置了line_count = 0,全局变量的同步逻辑完全失效,无法控制线程读取指定行。
  3. 循环逻辑错误:每个线程内的for row in csv_reader会遍历所有行,导致单个线程会打开多个浏览器实例,不符合“一个线程处理一行”的需求。

修正方案

  1. 提前加载所有凭证:在启动线程前,先把credentials.txt中的所有凭证读取到内存列表中,避免多个线程重复读取文件。
  2. 线程函数传参:让线程函数接收对应的凭证行作为参数,每个线程只处理分配给自己的那一行。
  3. 移除无效全局变量:不需要依赖全局变量控制读取位置,直接通过参数分配任务。

修正后的完整代码

import csv
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
from threading import Thread

def login(credential):
    # 每个线程只处理传入的单个凭证行
    driver = webdriver.Chrome("C:\\Chromedriver.exe")
    driver.maximize_window()
    try:
        driver.get('https://twitter.com/i/flow/login')
        time.sleep(4)
        # 使用传入的凭证用户名
        driver.find_element(By.NAME, "text").send_keys(credential[0])
        time.sleep(3)
        # 这里可以继续添加后续登录步骤,比如点击下一步、输入密码等
    finally:
        # 可以根据需求选择是否关闭浏览器
        # driver.quit()
        pass

if __name__ == "__main__":
    number_of_threads = 2
    credentials = []
    
    # 提前读取所有凭证到内存
    with open('credentials.txt') as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=':')
        credentials = list(csv_reader)
    
    # 确保凭证数量和线程数量匹配
    if len(credentials) < number_of_threads:
        print(f"错误:凭证文件只有{len(credentials)}行,无法启动{number_of_threads}个线程")
    else:
        threads = []
        # 为每个线程分配对应的凭证行
        for i in range(number_of_threads):
            t = Thread(target=login, args=(credentials[i],))
            t.start()
            threads.append(t)
        
        # 等待所有线程完成
        for t in threads:
            t.join()

关键改动说明

  • 提前加载凭证:在主线程中一次性读取所有凭证,避免多线程同时读取文件导致的资源竞争和重复读取问题。
  • 线程传参:创建线程时通过args参数把对应的凭证行传递给login函数,每个线程只处理自己的凭证。
  • 异常处理:添加try...finally块,确保浏览器资源能被正确管理(可以根据需求选择是否关闭浏览器)。
  • 参数校验:增加了凭证数量和线程数量的匹配检查,避免出现索引越界错误。

内容的提问来源于stack exchange,提问作者Giovanni Di Renzo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 22:01:18