我试图将SMTP服务器连接到域名
import socket()
import smtplib
import dns.resolver
getdomain = user_email.split('@')
check_domain = dns.resolver.query(getdomain[1], 'MX')
mxrecords=check_domain[0].exchange
host=socket.gethostname()
server=SMTP()
server.connect(mxrecords)
这引起了我的错误
if not port and (host.find(':') == host.rfind(':')):
AttributeError: 'Name' object has no attribute 'find'
但是,当我将mx记录更改为字符串时,它可以工作
mxrecords=str(check_domain[0].exchange)
任何人都可以解释为什么它接受字符串?
来自https://docs.python.org/3/library/smtplib.html
你可以知道connect()
需要一个字符串参数host
。
SMTP实例封装了SMTP连接。它具有支持完整的SMTP和ESMTP操作的方法。如果给出了可选的主机和端口参数,则在初始化期间使用这些参数调用SMTP connect()方法。
connect()
可以点击然后重定向到一个链接,然后你可以看到:
SMTP.connect(host ='localhost',port = 0) 连接到给定端口上的主机。默认设置是连接到标准SMTP端口(25)的本地主机。如果主机名以冒号(':')结尾,后跟一个数字,则该后缀将被删除,并且该数字将被解释为要使用的端口号。如果在实例化期间指定了主机,则构造函数会自动调用此方法。返回服务器在其连接响应中发送的响应代码和消息的2元组。
在那里你可以知道param host='localhost'
默认是一个字符串。
编辑
我检查了你的代码,
print(type(mxrecords))
版画
<class 'dns.name.Name'>
这表明mxrecords
对象是dns.name.Name
对象,而不是字符串。
如果单击qazxsw poi方法源代码,您会发现qazxsw poi应该是一个字符串:
connect
在代码中你可以找到host
,它匹配你的错误。
检查def connect(self, host='localhost', port=0, source_address=None):
"""Connect to a host on a given port.
If the hostname ends with a colon (`:') followed by a number, and
there is no port specified, that suffix will be stripped off and the
number interpreted as the port number to use.
Note: This method is automatically invoked by __init__, if a host is
specified during instantiation.
"""
if source_address:
self.source_address = source_address
if not port and (host.find(':') == host.rfind(':')):
i = host.rfind(':')
if i >= 0:
host, port = host[:i], host[i + 1:]
try:
port = int(port)
except ValueError:
raise OSError("nonnumeric port")
if not port:
port = self.default_port
if self.debuglevel > 0:
self._print_debug('connect:', (host, port))
self.sock = self._get_socket(host, port, self.timeout)
self.file = None
(code, msg) = self.getreply()
if self.debuglevel > 0:
self._print_debug('connect:', repr(msg))
return (code, msg)
源代码,你会发现host.find(':') == host.rfind(':')
类有一个dns.name.Name
方法:
Name
因此,您应该使用to_text
来获取MX服务器名称。
第三方def to_text(self, omit_final_dot=False):
"""Convert name to text format.
@param omit_final_dot: If True, don't emit the final dot (denoting the
root label) for absolute names. The default is False.
@rtype: string
"""
if len(self.labels) == 0:
return maybe_decode(b'@')
if len(self.labels) == 1 and self.labels[0] == b'':
return maybe_decode(b'.')
if omit_final_dot and self.is_absolute():
l = self.labels[:-1]
else:
l = self.labels
s = b'.'.join(map(_escapify, l))
return maybe_decode(s)
包返回的对象不是标准库mxrecords.to_text()
知道的类型(或类,如果有帮助)。
很多时候,当连接库API时,作为程序员的任务是从一个API作为输出返回的自定义表示转换为适合作为另一个API调用的输入的不同表示。
系统库需要特别注意这一点。如果dns.resolver
(甚至smtplib
)知道你的特定解析器,那么与其他解析器一起使用会更难。即使你的解析器也是Python标准库的一部分,这样的内部依赖会引入不受欢迎的刚性,内部耦合,以及潜在的一些讨厌的内部版本问题。