(一)向多人发送邮件(带附件)
一、使用的库
这个程序涉及两个库:smtplib 和 email
这两个库都是Python自带的,所以不需要额外的下载安装。

二、思路和步骤
总体思路很简单,就像我们平常上网是通过HTTP协议一样,我们发送邮件是通过SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)来传输的,而现在我们需要做的就是:
(1)开启邮箱 SMTP 服务:
以 QQ 邮箱为例,开启 SMTP 的路径是:邮箱首页 → 设置 → 账户 → POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 → 开启,如下图:

(2)设置好SMTP服务器地址;
例如 QQ 邮箱的 SMTP 服务器的地址就是:smtp.qq.com,端口号是 465 或 587

server = smtplib.SMTP("smtp.qq.com",587)

(3)告诉服务器我们的邮箱地址和密码(如果是 QQ 邮箱,那么则是授权码);

server.login(fromaddr , "fuheabperjoybjjg")

(4)设置要发送的邮件内容,例如发送者地址,接收者地址,邮件主题,邮件正文,附件等;

(5)将设置好的邮件内容传给服务器,并发送。

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipartfromaddr = "2******9@qq.com"
toaddr = "2******9@qq.com"
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
# 邮件主题
msg['Subject'] = "Hooah"
# 邮件正文
body = "HAHAHA!"msg.attach(MIMEText(body, 'plain'))server = smtplib.SMTP("smtp.qq.com",587) #设置SMTP服务器地址
server.starttls()
server.login(fromaddr , "fuheabperjoybjjg")   #告诉服务器发送者的邮箱地址和密码(如果是QQ邮箱,那么则是授权码)
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()

三、向多人发送

四、发送有附件的邮件

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encodersfromaddr = "2*******9@qq.com"
toaddr = "2*******9@qq.com"
msg = MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = toaddr
# 邮件主题
msg['Subject'] = "Hooah"
# 邮件正文
body = "HAHAHA!"msg.attach(MIMEText(body, 'plain'))# 附件
filename = "蟊.pdf"
attachment = open(filename, 'rb')
part = MIMEBase('application', 'octet-stream')
# 这也可以: part = MIMEBase('application', 'pdf')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment', filename=filename)msg.attach(part)# 设置 SMTP
server = smtplib.SMTP("smtp.qq.com")
server.starttls()
server.login(fromaddr , "fuheabperjoybjjg")
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()


(二)遍历邮件获取内容
在正式介绍 imbox 库之前,再分享一个技巧。从上面的代码中也可以看到,当输入密码(授权码)的时候是在代码中明文显示,这就带来了风险。
解决办法:
利用 keyring 库,通过系统密钥环将密码(授权码),预先在本地存储好,后面在代码中调用 keyring 库的方法,通过账号把密码取出来作为变量就可以。
这样即使别人拿到了全部代码,但他的本地中没有预先配置好密码,就不会有泄露信息的风险了。具体使用方法为,首先打开命令行安装:pip install keyring
然后运行py文件:

import keyringkeyring.set_password('api', 'user1', 'keyou520')  # 应用名(指定在哪一个应用中来使用)、用户名、密码

这样就完成了该应用名下该用户名和密码的本地注册,下次要使用密码时,直接调用就可以了。

一、安装imbox:
pip install imbox

二、按照上述keyring的本地注册,完成qq邮箱的授权码注册。

三、遍历邮件 (imbox方法)
设置:进入邮箱,选择设置,选择启用IMAP,并将收取选项设置为全部,保存设置,如下图:

代码:

import keyring
from imbox import Imboxpassword=keyring.get_password("qqmail", "261082579@qq.com")with Imbox('imap.qq.com', '261082579@qq.com', password, ssl=True) as imbox: #服务器、用户名、密码、SSL加密# 获取未读邮件all_inbox_messages = imbox.messages(unread=True)   #参数是空的话,就是获取全部邮件for uid, message in all_inbox_messages:  #uid参数是每封邮件的编号,可以用于邮件的标记和删除print(message.subject)  # 邮件主题
#        print(message.body['plain']) # 邮件文本格式正文

除了邮件主题及文本格式正文外,我们还有以下常用内容:

此外,我们常常会有选择性获取已读、未读和红旗标记邮件:

unread_inbox_messages = imbox.messages(unread=True) # 未读邮件
read_inbox_messages = imbox.messages(unread=False) # 已读邮件
flagged_inbox_messages = imbox.messages(flagged=True) # 红旗标记邮件

也可以通过邮件的收件时间获取邮件:

inbox_message_before = imbox.messages(date__lt=datetime.date(2021, 1, 18))
inbox_message_after = imbox.messages(date__gt=datetime.date(2021, 1, 18))
inbox_message_on_date = imbox.messages(date__on=datetime.date(2021, 1, 18))

那么如何筛选指定发件人发送的邮件呢?答案就在于对 message.sent_from 的理解了。message.sent_from 是一个字典元组,在遍历的过程中只需要简单通过 message.sent_from[0]['email'] 就能够将发件人邮箱提取出来,接着做判断就能够达到目的:

最后,基于编号的两个重要方法:
(1)标记已读 imbox.mark_seen(uid)
(2)删除邮件 imbox.delete(uid)
以删除邮件为例:

for uid, message in all_inbox_messages: if 满足某种条件的邮件: imbox.delete(uid)

四、imaplib方法
(1)获取邮件中所有的文件夹:

(2)选择收件箱后,筛选邮件:

收件箱中所有邮件,如果想要筛选出发件人为user2邮箱地址的邮件,对应语句为status, data = server.search(None, ‘(FROM “user2”)’),如下图:

(3)提取邮件:server.fetch(num, ‘(RFC822)’),返回的是一个元组。

·参数num表示提取的邮件序列号,支持同时提取多个连续邮件消息,例如同时提取邮件序列号为2-5的邮件命令为M.fetch(‘2:5’, ‘(RFC822)’)

·参数’(RFC822)'表示数据项名称,RFC822是电子邮件的标准格式,这里’(RFC822)’等同于BODY[]
如果只想获得邮件头部的内容,可以使用以下代码:server.fetch(num, ‘BODY[HEADER]’)

如果只想获得邮件体的内容,可以使用以下代码:server.fetch(num, ‘BODY[TEXT]’)

(4)email.parser.BytesParser(),将字节对象返回一个消息对象结构,与email.message_from_bytes()效果等价。
字节对象:

消息对象结构:

消息对象结构全览:

对邮件头的操作:
(5)消息对象结构中,如何获取某个字段:get()
(以邮件头中的subject为例)

(6)解码后以显示中文:(以邮件头中的subject为例)
email.header.decode_header()函数,输入包含编码信息的base64字符串,解析出解码后的字节串和charset,解析器的返回是list套一个tuple,即[(bytes, charset)]
如果charset为None, 说明bytes里面不是字节而是str。

(7)对邮件头中的发件人的操作为例:

email.utils.parseaddr 专门用来解析邮件地址的,原因是邮件地址很多时候在原文里是这样写的:user1 xxxxxxxx@163.com, 返回一个列表,[user1, xxxxxxxx@163.com]

import imaplib
import email
from email.parser import BytesParser    #从邮件解析导入BytesParser类
from email.utils import parseaddr #专门用来解析邮件地址的,原因是邮件地址很多时候在原文里是这样写的:user1 xxxxxxxx@163.com, 返回一个列表,[user1, xxxxxxxx@163.com]
import keyringserver= imaplib.IMAP4('imap.qq.com')
server.login("261082579@qq.com",keyring.get_password('qq','261082579@qq.com'))
#print(server.list())   #查看所有的文件夹,收件箱一般默认为'INBOX'
server.select('INBOX')    #表示选择收件箱
# 搜索匹配的邮件,第一个参数是字符集,None默认就是ASCII编码,第二个参数是查询条件,ALL就是查找全部,返回的是一个元组
status, data = server.search(None, 'ALL')
#print(data)#返回的是这个收件箱里所有邮件的序列号,按接收时间升序排列,最大的表示最近
typ, content = server.fetch('31','BODY[]')
msg = BytesParser().parsebytes(content[0][1])  #将字节对象返回一个消息对象结构,与email.message_from_bytes效果等价,即email.message_from_bytes(content[0][1])#对邮件头的操作
s = msg.get('Subject')#或者msg['Subject']print(len(s))
print(s)
s_bytes_char=email.header.decode_header(s)
print(s_bytes_char)
sub=str(s_bytes_char[0][0], s_bytes_char[0][1])
print(sub)
print('-'*90)addr=msg.get('from')
print(addr)
print(parseaddr(addr))
addr_1=email.header.decode_header(parseaddr(addr)[0])
print(addr_1)
print(str(addr_1[0][0],addr_1[0][1]))

对邮件体的操作,邮件体里可能有纯文本的plain和html两部分,也可能有附件。
(8)walk() 函数,循环信件中的每一个mime的数据块。

(9)如果循环中有附件,那么获取附件名,并解码以显示中文:

解码过程和上述操作邮件头标题的过程一样,如下:

备注:不同的charset,有不同的应对方法。参考:https://cloud.tencent.com/developer/article/1541116

(10)下载附件:get_payload(decode=True)函数, 通常decode设为True,即邮件正文根据每个Content-Transfer-Encoding头解码。

完整代码:

import imaplib
import email
from email.parser import BytesParser    #从邮件解析导入BytesParser类
from email.utils import parseaddr #专门用来解析邮件地址的,原因是邮件地址很多时候在原文里是这样写的:user1 xxxxxxxx@163.com, 返回一个列表,[user1, xxxxxxxx@163.com]
import keyringserver= imaplib.IMAP4('imap.qq.com')
server.login("261082579@qq.com",keyring.get_password('qq','261082579@qq.com'))
#print(server.list())   #查看所有的文件夹,收件箱一般默认为'INBOX'
server.select('INBOX')    #表示选择收件箱
# 搜索匹配的邮件,第一个参数是字符集,None默认就是ASCII编码,第二个参数是查询条件,ALL就是查找全部,返回的是一个元组
status, data = server.search(None, 'ALL')
#print(data)#返回的是这个收件箱里所有邮件的序列号,按接收时间升序排列,最大的表示最近
typ, content = server.fetch('31','BODY[]')
msg = BytesParser().parsebytes(content[0][1])  #将字节对象返回一个消息对象结构,与email.message_from_bytes效果等价,即email.message_from_bytes(content[0][1])#对邮件头的操作
#(1)操作邮件标题:
# s = msg.get('Subject')#或者msg['Subject']print(len(s))
# print(s)
# s_bytes_char=email.header.decode_header(s)
# print(s_bytes_char)
# sub=str(s_bytes_char[0][0], s_bytes_char[0][1])
# print(sub)
# print('-'*90)#(2)操作发件人:
# addr=msg.get('from')
# print(addr)
# print(parseaddr(addr))
# addr_1=email.header.decode_header(parseaddr(addr)[0])
# print(addr_1)
# print(str(addr_1[0][0],addr_1[0][1]))#对邮件体的操作,邮件里可能有纯文本的plain和html两部分,也可能有附件。
p=msg.walk()
#print(type(p))
for part in msg.walk():  #循环邮件中的每一个mime的数据块#print(part)#print('-'*25)   #从结果看有5个partfileName = part.get_filename()   #如果是附件,这里就会取出附件的文件名try:subject = email.header.decode_header(fileName)except:print('Header decode error')else:sub_bytes = subject[0][0]sub_charset = subject[0][1]if sub_charset == None:subject = sub_byteselif sub_charset=='unknown-8bit' :subject = str(sub_bytes, 'utf8')else:subject = str(sub_bytes, sub_charset)   print(subject)#保存附件      if subject:  with open(subject, 'wb') as fEx:data = part.get_payload(decode=True) #通常decode会设为True,即邮件正文根据每个Content-Transfer-Encoding头解码。fEx.write(data)  print("附件%s已保存" % subject)server.close() #用来关闭当前选择的邮箱
server.logout()#退出登录

上述代码是查看单封邮件的,要遍历整个收件箱的代码如下:

import imaplib
import email
from email.parser import BytesParser
from email.utils import parseaddr
import keyringserver= imaplib.IMAP4('imap.qq.com')
server.login("261082579@qq.com",keyring.get_password('qq','261082579@qq.com'))
server.select('INBOX')
status, data = server.search(None, 'ALL')
email_list = list(reversed(data[0].split()))
def decode_str(s):try:subject = email.header.decode_header(s)except:# print('Header decode error')return None sub_bytes = subject[0][0] sub_charset = subject[0][1]if None == sub_charset:subject = sub_byteselif 'unknown-8bit' == sub_charset:subject = str(sub_bytes, 'utf8')else:subject = str(sub_bytes, sub_charset)return subject
def get_email(num, server):typ, content = server.fetch(num, '(RFC822)')msg = BytesParser().parsebytes(content[0][1])sub = msg.get('Subject')for part in msg.walk():  fileName = part.get_filename()  fileName = decode_str(fileName)if None != fileName:print('+++++++++++++++++++')print(fileName)print(num, decode_str(sub))
for num in email_list:get_email(num, server)
server.close()
server.logout()

在补一个稍微复杂一点的,有空研究:


import imaplib
import email
from email.header import decode_header
from email.utils import parseaddr
import keyringdef get_mail(email_address, sqm):server= imaplib.IMAP4('imap.qq.com') server.login(email_address,sqm)server.select("INBOX")  type, data = server.search(None, "ALL")  msgList = data[0].split()latest = msgList[len(msgList) - 1]type, datas = server.fetch(latest, '(RFC822)')  ## 使用utf-8解码text = datas[0][1].decode('utf8')# 转化为email.message对象message = email.message_from_string(text)return message
#邮件的Subject或者Email中包含的名字都是经过编码后的字符串,要正常显示就必须decode,定义 一个decode函数
def decode_str(s):value, charset = decode_header(s)[0]if charset:value = value.decode(charset)return value
#为了防止非UTF-8编码的邮件无法显示,定义一个检测邮件编码函数
def guess_charset(msg):charset = msg.get_charset()if charset is None:content_type = msg.get('Content-Type', '').lower()pos = content_type.find('charset=')if pos >= 0:# 去掉尾部不代表编码的字段charset = content_type[pos + 8:].strip('; format=flowed; delsp=yes')return charset
#接下来通过循环遍历来读取邮件内容
# 使用全局变量来保存邮件内容
mail_content = '\n'
# indent用于缩进显示:
def print_info(msg, indent=0):global mail_contentif indent == 0:for header in ['From', 'To', 'Subject']:value = msg.get(header, '')if value:if header == 'Subject':value = decode_str(value)else:hdr, addr = parseaddr(value)name = decode_str(hdr)value = u'%s <%s>' % (name, addr)mail_content += '%s%s: %s' % ('  ' * indent, header, value) + '\n'parts = msg.get_payload()for n, part in enumerate(parts):content_type = part.get_content_type()if content_type == 'text/plain':content = part.get_payload(decode=True)# charset = guess_charset(msg)charset = 'utf-8'if charset:content = content.decode(charset)mail_content += '%sText:\n %s' % (' ' * indent, content)else:# 这里没有读取非text/plain类型的内容,只是读取了其格式,一般为text/htmlmail_content += '%sAttachment: %s' % ('  ' * indent, content_type)return mail_content
#最后,调用上述函数,输出邮件内容
if __name__ == '__main__':email_addr = "261082579@qq.com"sqm=keyring.get_password('qq','261082579@qq.com')test = print_info(get_mail(email_addr, sqm))        print("mail content is: %s" % test)

补充:
(11)搜索中文标题邮件:(待确认)

typ, data = server.search(None,‘SUBJECT “融资中国”’.encode(‘utf-8’))

(12)reversed函数:即倒序迭代器

(3)MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,它是一个互联网标准,扩展了电子邮件标准,使其能够支持:
非ASCII字符文本;非文本格式附件(二进制、声音、图像等);由多部分(multiple parts)组成的消息体;包含非ASCII字符的头信息(Header information)。
这是walk()函数循环的场景基础。
for part in msg.walk():
# 如果ture的话内容是没用的
if not part.is_multipart():
print(part.get_payload(decode=True).decode(‘utf-8’))
# 解码出文本内容,直接输出来就可以了。walk()函数能历遍邮件所有部分,所以通常都把它放到for循环里面使用。然后再使用is_multipart()函数来判断内容是否有用,打印出有用内容最后用get_payload(decode=True).decode(‘utf-8’)解码并且打印到控制台。通常这个循环有两次,第一次是单纯的字符串格式的,能在控制台显示出来的,第二次循环打印的是像HTML的格式,能在浏览器里查看,就像平时看到的邮件那样。参考:https://blog.csdn.net/diyiday/article/details/81504567?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-2.highlightwordscore&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-2.highlightwordscore
(4)解释一下什么是 payload?
payload 字面意思“有效载荷,有效负荷,有效载重”。
payload维基百科payload中的解释:
在计算机科学与电信领域,负载(英语:Payload)是数据传输中所欲传输的实际信息,通常也被称作实际数据或者数据体。信头与元数据,或称为开销数据,仅用于辅助数据传输。
在计算机病毒或电脑蠕虫领域中,负载指的是进行有害操作的部分,例如:数据销毁、发送垃圾邮件等。比如有一位客户需要支付一笔费用委托货车司机运送一车石油,石油本身的重量、车子的重量、司机的重量等等,这些都属于载重(load)。但是对于该客户来说,他关心的只有石油的重量,所以石油的重量是有效载重(payload,也就是付费的重量)。那么payload对于程序员来说就是在程序中 起关键作用的代码。维基百科给出了这个样的例子:payload通俗一点讲,在程序的世界里,payload(有效载荷)就是对于接收者有用的数据

进阶资料:
(1)https://www.cnblogs.com/gujianjian/p/12762040.html
(2)https://blog.csdn.net/diyiday/article/details/81504596?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2.no_search_link

未完待续,
后面有空还需要落实的是:怎么搜索中文标题邮件,以及检索的几种方式
实验代码如下:

import imaplib
import email
from email.parser import BytesParser    #从邮件解析导入BytesParser类
from email.utils import parseaddr #专门用来解析邮件地址的,原因是邮件地址很多时候在原文里是这样写的:user1 xxxxxxxx@163.com, 返回一个列表,[user1, xxxxxxxx@163.com]
import keyringserver= imaplib.IMAP4('imap.qq.com')
server.login("261082579@qq.com",keyring.get_password('qq','261082579@qq.com'))
#print(server.list())   #查看所有的文件夹,收件箱一般默认为'INBOX'
server.select('INBOX')    #表示选择收件箱
status, data = server.search(None, 'all')
print(data[0].split())#print(data)#返回的是这个收件箱里所有邮件的序列号,按接收时间升序排列,最大的表示最近status1, data1 = server.search(None, 'OR (FROM"citiccard@bill.citiccard.com")','SUBJECT', "测试".encode('utf-8'))#'OR FROM"citiccard@bill.citiccard.com"',
email_list1 = list(reversed(data1[0].split()))
print(email_list1)status2, data2 = server.search(None, '(FROM"261082579@qq.com")','SUBJECT', "中信银行信用卡电子账单".encode('utf-8'))
email_list2 = list(reversed(data2[0].split()))
print(email_list2)"""
or 或的关系 不加就是 and 中文主题要encode utf-8 有的邮箱可能编码也不好使
status, message = imap_object.search(None, 'OR FROM "ooxx@fuck.com"', 'SUBJECT "测试"'.encode('utf-8'))
"""
# mail.search(None, '(FROM "anjali sinha" SUBJECT "test")') #'UNSEEN FROM "test@testmail.com" SUBJECT "Subject" SINCE 17-may-1814'

进阶的阿牛哥之用python向多人发送邮件(带附件)、遍历邮件获取内容(两种方法:imbox、imaplib)相关推荐

  1. python怎么在图片上写字_Python在图片中添加文字的两种方法

    本文主要介绍的是利用Python在图片中添加文字的两种方法,下面分享处理供大家参考学习,下来要看看吧 一.使用OpenCV 在图片中添加文字看上去很简单,但是如果是利用OpenCV来做却很麻烦.Ope ...

  2. 怎样在python的turtle中输入文字_Python在图片中添加文字的两种方法

    本文主要介绍的是利用Python在图片中添加文字的两种方法,下面分享处理供大家参考学习,下来要看看吧 一.使用OpenCV 在图片中添加文字看上去很简单,但是如果是利用OpenCV来做却很麻烦.Ope ...

  3. python统计汉字个数是_python统计中文字符数量的两种方法

    方法一: def str_count(str): '''找出字符串中的中英文.空格.数字.标点符号个数''' count_en = count_dg = count_sp = count_zh = c ...

  4. python怎么统计多少字符_python统计中文字符数量的两种方法

    方法一: def str_count(str): '''找出字符串中的中英文.空格.数字.标点符号个数''' count_en = count_dg = count_sp = count_zh = c ...

  5. 使用Python的smtplib模块发送带附件的邮件

      上一篇文章<使用Python的smtplib模块发送简单邮件>介绍了调用smtplib模块发送包含简单内容的邮件,本文继续学习参考文献1中的发送带附件的邮件的示例代码,同时由于参考文献 ...

  6. python 学习系列(3) 读取并显示图片的两种方法

    python 读取并显示图片的两种方法 在 python 中除了用 opencv,也可以用 matplotlib 和 PIL 这两个库操作图片.本人偏爱 matpoltlib,因为它的语法更像 mat ...

  7. python读取指定行到最后一行_python读取文件最后一行两种方法

    原博文 2018-09-27 13:58 − 1)常规方法:从前往后依次读取 步骤:open打开文件. ... 相关推荐 2019-09-28 21:13 − Python python是一种跨平台的 ...

  8. python杨辉三角居中_python打印杨辉三角的两种方法及详解

    艾斯压阵 1c950a7b02087bf4200394cdf1d3572c11dfcf23.jpg 一盏灯, 一片昏黄: 一简书, 一杯淡茶. 守着那一份淡定, 品读属于自己的寂寞. 保持淡定, 才能 ...

  9. Python 技术篇-通过进程名称、PID杀死windows进程的两种方法,获取当前运行程序的pid

    方法一: 利用 os 杀死进程. import os# 通过进程名称杀死进程 os.system('taskkill /f /im %s' % 'python.exe')# 通过pid杀死进程 os. ...

最新文章

  1. 让DJANGO里的get_success_url定义的reverse_lazy带参数跳转
  2. vs2003不能正常调试或运行!
  3. 网络工程师求职与职业规划
  4. nagios新添加服务有时显示,有时不显示问题解决
  5. express开发实例
  6. 如何删除Apple Music中的连接功能
  7. python 遗传算法 agv_基于改进遗传算法的AGV路径规划
  8. TypeError: cannot convert the series to <class ‘float‘>问题解决
  9. 智能手机玩转Smart3D三维建模介绍
  10. bat计算机清理原理,如何一键清除系统垃圾bat,教您如何清理
  11. 67.220.92.12 /forum index.php,http://67.220.92.21/forum/inde PHP静态类
  12. php时间正序排序,列表的时间排序,应该正序还是倒序?
  13. C语言共用体中,共用体变量的规律
  14. PIL打开PNG图片出现杂乱的条纹
  15. [算法]LeetCode第194场周赛202006021
  16. mysql count的用法_155、MySQL入门(五):SUM and COUNT用法
  17. 计算流体力学三大基本方程:连续性方程、动量方程(纳维-斯托克斯方程)和能量方程推导
  18. 高并发】高并发秒杀系统架构解密,不是所有的秒杀都是秒杀
  19. OSChina 周六乱弹 ——不正经的动物越来越多了
  20. MySQL 8.0.17安装教程(windows 64位)

热门文章

  1. 最新版ser2net移植到ARM板上,交叉编译
  2. 我用Python制作整蛊软件发送给女友,结果.......我单身了!!
  3. cad模型轻量化_CAD软件发展简史
  4. 表情包也能用 AI 生成?如何借助 AIGC 自定义专属表情包 #Memix
  5. qpython l怎么用_QPythonL
  6. 作为一名半路出家的程序员,要学的还很多
  7. 盛天海科技:拼多多怎么提高转化?
  8. 中小型机器人开发平台Aopllp的秘密
  9. bzoj3056 升降梯口(组合数学+模拟)
  10. CIO免费IT预算计划模板