为什么MX记录应该被更改为字符串?

2024-09-30 08:27:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试将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'

但当我把mxrecords改成string时,它就工作了

mxrecords=str(check_domain[0].exchange)

有人能解释一下为什么它接受字符串吗?你知道吗


Tags: import服务器hostexchangeserverdnsdomaincheck
2条回答

https://docs.python.org/3/library/smtplib.html

您可以知道connect()需要一个字符串参数host。你知道吗

An SMTP instance encapsulates an SMTP connection. It has methods that support a full repertoire of SMTP and ESMTP operations. If the optional host and port parameters are given, the SMTP connect() method is called with those parameters during initialization.

connect()可以单击然后重定向到链接,然后您可以看到:

SMTP.connect(host='localhost', port=0)
Connect to a host on a given port. The defaults are to connect to the local host at the standard SMTP port (25). If the hostname ends with a colon (':') followed by a number, that suffix will be stripped off and the number interpreted as the port number to use. This method is automatically invoked by the constructor if a host is specified during instantiation. Returns a 2-tuple of the response code and message sent by the server in its connection response.

在这里您可以知道paramhost='localhost'默认值是一个字符串。你知道吗


编辑

我查了你的密码

print(type(mxrecords)) 

印刷品

<class 'dns.name.Name'>

表示mxrecords对象是dns.name.Name对象,而不是字符串。你知道吗

如果单击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方法:

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()来获取MX服务器名。你知道吗

第三方dns.resolver包返回的对象不是标准库smtplib所知道的类型(或类,如果有帮助的话)。你知道吗

很多时候,在与库API接口时,作为程序员,您的任务是将一个API作为输出返回的自定义表示转换为另一个API调用的适合作为输入的不同表示。你知道吗

系统库需要特别注意这一点。如果smtplib(或者甚至socket)知道您的特定解析器,那么与其他解析器一起使用会更加困难。即使您的解析器也是Python标准库的一部分,这样的内部依赖也会引入不受欢迎的僵化、内部耦合,以及潜在的一些讨厌的内部版本控制问题。你知道吗

相关问题 更多 >

    热门问题