线程 Thread-2 中的异常:回溯(最近一次调用)我无法使多线程工作



我正试图构建一个能同时做两件事的discord机器人。第一步是查看推特上的一些个人资料,并在这些个人资料发推时转发。第二个每隔5分钟在一个无头铬上用硒元素拍摄一张截图,并在另一个频道上分享。

这两个线程似乎拒绝同时工作。当我计时.sleep时,第二个线程停止工作。

需要注意的是,如果没有任何新的推文,第二个线程根本不起作用。

这是完整的代码:

main.py:

import influenceur  #See bellow
import threading
import long_short #See bellow
import discord
# Connexion discord
client = discord.Client()
@client.event
async def on_ready():
print("Ready")
th1 = threading.Thread(target=client.loop.create_task(influenceur.influenceur(client)))
th2 = threading.Thread(target=client.loop.create_task(long_short.long_short(client)))
th1.start()
th2.start()
th1.join()
th2.join()
client.run(<tocken>)

influenceur.py:

import discord
from discord.ext import commands
import tweepy
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from PIL import Image
import asyncio
import data
import data
# Read txt, return int list
def read_txt(txt):
with open(txt, "r", encoding="utf8") as f:
liste = f.read().split("n")
list_id = []
del liste[-1]
for item in liste:
item_int = int(item)
list_id.append(item_int)
return list_id
# Write in txt
def write_txt(tweet_id, txt):
with open(txt, "a", encoding="utf8") as f:
f.write(str(tweet_id) + "n")
print("id enregistrée")
async def influenceur(client):
# Connexion twitter
auth = tweepy.OAuthHandler(<key>, <key_secret>)
auth.set_access_token(<access_tocken>, <access_tocken_secret>)
api = tweepy.API(auth)
usernames_influenceur = ["elonmusk", "michael_saylor", "PeterSchiff" ,"jack", "VitalikButerin", "WarrenBuffett", "cz_binance"]
usernames_twitos_fr = ["CryptoMatrix2", "PowerHasheur", "cryptoastblog", "cryptonews_FR", "CryptoActuFr", "maxime__prigent"]
usernames_twitos_eng = ["TheMoonCarl", "MMCrypto", "Davincij15", "aantonop", "justinsuntron", "CryptoCobain", "BTC_Archive"]
usernames = usernames_twitos_fr + usernames_twitos_eng + usernames_influenceur
while True:
try:
for username in usernames:
count = 2
time.sleep(2)
try:
# Get tweets
tweets = tweepy.Cursor(api.user_timeline, id=username, exclude_replies=True).items(count)
except Exception as e:
time.sleep(5)
print("Error, retry : ", e)
pass
print("lecture des tweets de ", username)
for tweet in tweets:
id_tweet = read_txt("id_tweet.txt")
if tweet.id in id_tweet:
pass
else:
print("printing")
if username in usernames_influenceur:
channel = client.get_channel(data.influenceur_chan)
await channel.send("https://twitter.com/" + username + "/status/" + str(tweet.id))
elif username in usernames_twitos_fr:
channel = client.get_channel(data.twitos_fr_chan)
await channel.send("https://twitter.com/" + username + "/status/" + str(tweet.id))
elif username in usernames_twitos_eng:
channel = client.get_channel(data.twitos_eng_chan)
await channel.send("https://twitter.com/" + username + "/status/" + str(tweet.id))
write_txt(tweet.id, "id_tweet.txt")
print("End of infuenceurs, sleep 5")
time.sleep(5)

except Exception as e:
print("Erreur:", e)
continue

long_short.py:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from PIL import Image
import discord
import asyncio
import data

async def long_short(client):
while True:
print("long short")
WINDOW_SIZE = "1920,2160"
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--headless")
chrome_options.add_argument("--window-size=%s" % WINDOW_SIZE)
chrome_options.add_argument("--kiosk")
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://fr.coinalyze.net/bitcoin/usdt/binance/btcusdt_perp/price-chart-live/")
driver.find_element_by_xpath("//*[@class='login']").click()
time.sleep(3)
email = driver.find_element_by_xpath("//input[@name='email']").send_keys(<mail>)
password = driver.find_element_by_xpath("//input[@name='pwd']").send_keys(<password>)
time.sleep(1)
driver.find_element_by_xpath("//input[@value='Se connecter']").click()
time.sleep(8)
driver.get_screenshot_as_file("screenshot.png")
time.sleep(1)
driver.quit()
##############################
screen = Image.open("screenshot.png")
width, height = screen.size
left = 83
top = 150
width = 1385
height = 1960
box = (left, top, left+width, top+height)
area = screen.crop(box)
area.save("screen_sized.png", "PNG")
###################################
print("I'm ready.")
channel = client.get_channel(data.long_short_chan)
print("Channel :", channel)
await channel.send(file=discord.File("screen_sized.png"))
print("Screen uploadé, wait 60")

time.sleep(420)

错误:

Exception in thread Thread-2:
Traceback (most recent call last):
Exception in thread Thread-3:
File "C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.9_3.9.1520.0_x64__qbz5n2kfra8p0libthreading.py", line 954, in _bootstrap_inner
Traceback (most recent call last):
self.run()
File "C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.9_3.9.1520.0_x64__qbz5n2kfra8p0libthreading.py", line 892, in run        
File "C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.9_3.9.1520.0_x64__qbz5n2kfra8p0libthreading.py", line 954, in _bootstrap_inner
self._target(*self._args, **self._kwargs)
TypeError: '_asyncio.Task' object is not callable
self.run()
File "C:Program FilesWindowsAppsPythonSoftwareFoundation.Python.3.9_3.9.1520.0_x64__qbz5n2kfra8p0libthreading.py", line 892, in run        
self._target(*self._args, **self._kwargs)
TypeError: '_asyncio.Task' object is not callable

有一种方法可以运行;"阻塞";单独线程中的协同程序:

import asyncio
import contextlib
async def run_non_trapping_coro(func, /, *args, **kwargs):
def wrapper():
with contextlib.closing(fn(*args, **kwargs).__await__()) as gen:
try:
value = gen.send(None)
except StopIteration as exc:
return exc.value
else:
raise Exception(f"Unexpected yield {value} from {func}")
return await asyncio.to_thread(wrapper)

如果您使用的是python<3.9

import asyncio
import contextlib
async def run_non_trapping_coro(func, /, *args, **kwargs):
loop = asyncio.get_event_loop()
def wrapper():
with contextlib.closing(fn(*args, **kwargs).__await__()) as gen:
try:
value = gen.send(None)
except StopIteration as exc:
return exc.value
else:
raise Exception(f"Unexpected yield {value} from {func}")
return await loop.run_in_executor(None, wrapper)

用法:

await run_non_trapping_coro(influenceur.influenceur(client))

您可以将其作为退出函数的任务运行,也可以使用asyncio.gather等待结果

# Tasks
client.loop.create_task(run_non_trapping_coro(influenceur.influenceur, client.loop))
client.loop.create_task(run_non_trapping_coro(long_short.long_short, client.loop))
# asyncio.gather
await asyncio.gather(
run_non_trapping_coro(influenceur.influenceur, client.loop)
run_non_trapping_coro(long_short.long_short, client.loop)
)

最新更新