使用python多线程查找邮箱地址时遇到错误

想要用发送垃圾邮件试验存在哪些邮箱地址时出现了问题。

import smtplib
import threading as thread
from random import randint
from email.mime.text import MIMEText
username="msabc.shu@foxmail.com"
password="matecwwoqhbjdhba"
server=smtplib.SMTP_SSL('smtp.qq.com',465)
server.connect('smtp.qq.com',465)
print(server.login(username,password))
content=open("temp.html","r",encoding="utf-8").read()
qqs=[""]
temp=open("emails.txt",'r').read()[:-1]
qqs+=temp.split("\n")
lock=thread.Lock()
def send(to):
    msg=MIMEText(content,'html','utf-8')
    msg['From']=username
    msg["To"]=to
    msg["Subject"]="快点开!"
    try:
        server.sendmail(username,[to],msg.as_string())
        return True
    except Exception as e:
        return False
def getqq():
    qq=""
    while qq in qqs:
        temp=""
        while len(temp)<8:
            a=randint(1,9)
            b=randint(0,9)
            c=1 if b>a else -1
            for i in range(a,b,c):
                temp+=str(i)
        qq=temp[:10]
    qqs.append(qq)
    return qq+"@qq.com"
def main(lock):
    while True:
        temp=getqq()
        if send(temp):
            print(temp)
            lock.acquire()
            open("emails.txt",'a').write(temp+"\n")
            lock.release()
for i in range(2):
    thread.Thread(target=main,args=(lock,)).start()

当线程数量为1时可以正常获取数据:

Python 3.11.4 (tags/v3.11.4:d2340ef, Jun  7 2023, 05:45:37) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.

= RESTART: E:\python files\广告服务器\发送垃圾邮件.py
(235, b'Authentication successful')
987654321@qq.com
87654323@qq.com
87654387@qq.com
54322345@qq.com
45678345@qq.com
19876543@qq.com
765421678@qq.com

但当线程数量超过1时(即多线程),就会没有输出。因为程序在报错时不输出,所以看了一下报错情况,发现错误是:Mailfrom may not be repeated from 39.189.22.98 to newxmesmtplogicsvrsza7-0.qq.com.
我也不知道后面这个是什么。

出现了"Mailfrom may not be repeated"的错误。这个错误是由于在使用SMTP发送邮件时,重复使用了相同的发件人地址引起的。这个问题可以通过修改代码来解决。

在代码中,每个线程都会调用send()函数来发送邮件,并且在成功发送后将邮箱地址追加到emails.txt文件中。然而,在多线程情况下,多个线程可能会同时执行到获取新的QQ邮箱地址的逻辑,导致重复获取并使用相同的QQ邮箱地址作为发件人。

为了避免这个问题,可以在代码中添加一个互斥锁(mutex lock)来确保只有一个线程可以获取新的QQ邮箱地址并发送邮件。可以使用threading.Lock()来创建一个互斥锁,并在获取新的QQ邮箱地址和发送邮件的部分添加对互斥锁的操作。


```python
import smtplib
import threading as thread
from random import randint
from email.mime.text import MIMEText

username = "msabc.shu@foxmail.com"
password = "matecwwoqhbjdhba"

server = smtplib.SMTP_SSL('smtp.qq.com', 465)
server.connect('smtp.qq.com', 465)
print(server.login(username, password))

content = open("temp.html", "r", encoding="utf-8").read()
qqs = [""]
temp = open("emails.txt", 'r').read()[:-1]
qqs += temp.split("\n")
lock = thread.Lock()

def send(to):
    msg = MIMEText(content, 'html', 'utf-8')
    msg['From'] = username
    msg["To"] = to
    msg["Subject"] = "快点开!"
    try:
        server.sendmail(username, [to], msg.as_string())
        return True
    except Exception as e:
        return False

def getqq():
    qq = ""
    while qq in qqs:
        temp = ""
        while len(temp) < 8:
            a = randint(1, 9)
            b = randint(0, 9)
            c = 1 if b > a else -1
            for i in range(a, b, c):
                temp += str(i)
        qq = temp[:10]
    qqs.append(qq)
    return qq + "@qq.com"

def main(lock):
    while True:
        lock.acquire()  # 在获取新QQ邮箱地址和发送邮件前,获取互斥锁
        temp = getqq()
        lock.release()  # 在完成获取新QQ邮箱地址和发送邮件后,释放互斥锁

        if send(temp):
            print(temp)
            lock.acquire()  # 在追加成功发送的QQ邮箱到emails.txt前,获取互斥锁
            open("emails.txt", 'a').write(temp + "\n")
            lock.release()  # 在完成追加成功发送的QQ邮箱到emails.txt后,释放互斥锁

for i in range(2):
    thread.Thread(target=main, args=(lock,)).start()



```python