为什么mxrecord应该更改为字符串?

问题描述 投票:2回答:2

我试图将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)

任何人都可以解释为什么它接受字符串?

python python-3.x smtp mx-record
2个回答
2
投票

来自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服务器名称。


1
投票

第三方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标准库的一部分,这样的内部依赖会引入不受欢迎的刚性,内部耦合,以及潜在的一些讨厌的内部版本问题。

© www.soinside.com 2019 - 2024. All rights reserved.