Can';我无法在Python中使用我的类实例进行多处理
基本上,我希望为同一对象创建几个实例,并同时分别执行它们。此示例代码:Can';我无法在Python中使用我的类实例进行多处理,python,python-3.x,multithreading,multiprocessing,Python,Python 3.x,Multithreading,Multiprocessing,基本上,我希望为同一对象创建几个实例,并同时分别执行它们。此示例代码: class Student: def __init__(self, username_, password_): self.username = username_ self.password = password_ self.driver = webdriver.Chrome('chromedriver.exe') def login(self):
class Student:
def __init__(self, username_, password_):
self.username = username_
self.password = password_
self.driver = webdriver.Chrome('chromedriver.exe')
def login(self):
# Go to students page
self.driver.get('https://www.students.com/')
time.sleep(2)
# Enter username in login form
enter_username = WebDriverWait(self.driver, 20).until(
expected_conditions.presence_of_element_located((By.NAME, 'username')))
enter_username.send_keys(self.username)
# Enter password in login form
enter_password = WebDriverWait(self.driver, 20).until(
expected_conditions.presence_of_element_located((By.NAME, 'password')))
enter_password.send_keys(self.password)
# Wait to send the form
time.sleep(2)
# Click Log In button
self.driver.find_elements_by_xpath("//div[contains(text(), 'Iniciar sesión')]")[0].click()
# Wait for the form to be sent
time.sleep(5)
self.start_working()
# This functions is and endless loop that simulates work
if __name__ == '__main__':
load_dotenv()
query = "SELECT username, password FROM students"
cursor.execute(query)
records = cursor.fetchall()
print("Total number of accounts botting up ", cursor.rowcount)
object_list = list()
for username, password in records:
obj = Student(username, password)
object_list.append(obj)
instance_list = list()
for x in object_list:
p = multiprocessing.Process(target=x.login)
p.start()
instace_list.append(p)
for x in instance_list:
x.join()
到目前为止,我已经让所有人创建了类的实例,但是我还不能为每个实例执行login方法
我在终端中得到了这个错误:
(student-bot) C:\python\student-bot>Traceback (most recent call last):
File "<string>", line 1, in <module>
File "c:\users\alberto\appdata\local\programs\python\python37\lib\multiprocessing\spawn.py", line 99, in spawn_main
new_handle = reduction.steal_handle(parent_pid, pipe_handle)
File "c:\users\alberto\appdata\local\programs\python\python37\lib\multiprocessing\reduction.py", line 87, in steal_handle
_winapi.DUPLICATE_SAME_ACCESS | _winapi.DUPLICATE_CLOSE_SOURCE)
PermissionError: [WinError 5] Acceso denegado
[13852:1860:0427/193022.541:ERROR:device_event_log_impl.cc(162)] [19:30:22.541] Bluetooth: bluetooth_adapter_winrt.cc:1055 Getting Default Adapter failed.
(学生机器人)C:\python\student bot>回溯(最近一次调用):
文件“”,第1行,在
文件“c:\users\alberto\appdata\local\programs\python\37\lib\multiprocessing\spawn.py”,第99行,在spawn\u main中
新的\u句柄=减少。偷取\u句柄(父\u pid,管道\u句柄)
文件“c:\users\alberto\appdata\local\programs\python\python37\lib\multiprocessing\reduce.py”,第87行,在steal\u句柄中
_winapi.DUPLICATE_SAME_ACCESS|_winapi.DUPLICATE_CLOSE_SOURCE)
许可错误:[WinError 5]Acceso denegado
[13852:1860:0427/193022.541:错误:设备\u事件\u日志\u impl.cc(162)][19:30:22.541]蓝牙:蓝牙适配器\u winrt.cc:1055获取默认适配器失败。
您可能想要target=x.login
,而不是x.login()
。否则,您将调用target.login()返回的任何内容,这些内容甚至可能不可调用。一个“正在执行”的进程实际上可能只是主线程,并且是您编码的x.login()
,但实际上没有任何子进程在工作。显示错误消息会很有帮助。还要确保上述代码位于以以下内容开头的块中:
if __name__ == '__main__':
例如:
import multiprocessing
class Foo:
def bar(self, i):
print(i, flush=True)
f = Foo()
if __name__ == '__main__':
instace_list = list()
for i in range(3):
p = multiprocessing.Process(target=f.bar, args=(i,))
p.start()
instace_list.append(p)
for x in instace_list:
x.join()
印刷品:
0
1
2
更新
理想情况下,您的文件结构应如下所示:
import blah, blah, blah;
class Student: # or perhaps this is imported above
# definition of this class
def foo():
# definition of foo
def bar():
#d definition of bar
def query_database():
load_dotenv()
# obtain connection and cursor (code not shown)
query = "SELECT username, password FROM students"
cursor.execute(query)
records = cursor.fetchall()
print("Total number of accounts botting up ", cursor.rowcount)
object_list = list()
for username, password in records:
obj = Student(username, password)
object_list.append(obj)
return object_list
if __name__ == '__main__':
object_list = query_database() # get Student list
with multiprocessing.Pool(processes=8) as pool:
instance_list = list()
for x in object_list:
result = pool.apply_async(x.login)
instance_list.append(result)
for result in instance_list:
result.get() # return value from login, which is None
更新2
<>因为<代码>登录方法似乎不是CPU绑定的进程,所以您可以考虑使用线程。此代码不必位于\uuuuu main\uuuu
块中(尽管这样做完全正确):
我编辑了这段代码以显示更多细节,我会尝试你的答案并给出反馈,我对Python的这部分内容很陌生,这几乎让我发疯。我在帖子中修改了代码,现在每个对象都正确创建了,但在所有学生都搞砸了之后,我现在遇到了这个错误,我还没有让他们执行登录功能。我必须看看
login
功能在做什么,也许还有其余的代码。您必须意识到,对于创建的每个子进程,除了主块中的代码之外,整个源文件都会从上到下执行(这就是为什么创建子进程的代码会出现在主块中)。因此,理想情况下,文件应该只包含在调用函数和类定义之前不会执行的函数。然后,您应该有一个函数,可以在主块中调用该函数来查询数据库以获取所需的行。我会更新我的答案。我必须说,我不知道是什么导致了那个特定的错误。我再次更新了我的代码,将多处理池设置为最多8个子进程。正如您的代码现在所示,如果您有5000名学生,您将尝试创建5000个进程。我并不是说这是造成问题的原因(可能是)。但是,拥有比计算机上的CPU数量更多的进程是没有任何意义的。我的电脑有8个,所以我把号码发到了8。您的任务没有特别的CPU限制,因此您可以尝试使用线程而不是多处理。我回答了您最初的问题,即为什么您无法创建进程并成功调用登录方法,并提供了一个正常工作的演示程序。登录方法失败的原因是该方法特有的。也许它正在做的事情与同时运行的多个实例不兼容。但我认为这应该是一个新问题的主题,你发布标签,明确说明你正在使用的工具,例如chromdriver.exe
,以及你正在运行的环境,即Windows,并获得了解这些东西的人的帮助。
from concurrent.futures import ThreadPoolExecutor
object_list = query_database() # get Student list
with ThreadPoolExecutor(max_workers=8) as executor:
instance_list = list()
for x in object_list:
future = executor.submit(x.login)
instance_list.append(future)
for future in instance_list:
future.get() # return value from login, which is None