【问题标题】:Extend Python module in whois package在 whois 包中扩展 Python 模块
【发布时间】:2020-01-31 15:58:43
【问题描述】:

我正在使用 pythons whois 模块来检查 .by 区域中的免费域。该模块目前不支持。但我需要做的就是将这些代码添加到 .../lib/python3.8/site-packages/whois/tld_regexpr.py:

by = {
'extend': 'com'
}

我认为硬编码到 lib 文件夹是不对的。我的代码现在看起来像这样:

import whois

def free_domains(domain_list):
    """Looking for free domains"""
    free_d = []
    for domain in domain_list:
        if whois.query(domain) is None:
            free_d.append(domain)
    return free_d

但如果没有这些注入,它就无法工作。 ???如何从我的 .py 文件中扩展 tld_regexpr.py?

【问题讨论】:

    标签: python module whois


    【解决方案1】:

    作为参考,这里是whois.tld_regexpr 的源代码。在whois._2_parse 中使用如下:

    from . import tld_regexpr
    
    TLD_RE = {}
    
    
    def get_tld_re(tld):
        if tld in TLD_RE:
            return TLD_RE[tld]
        v = getattr(tld_regexpr, tld)
        extend = v.get('extend')
    
        if extend:
            e = get_tld_re(extend)
            tmp = e.copy()
            tmp.update(v)
        else:
            tmp = v
    
        if 'extend' in tmp:
            del tmp['extend']
    
        TLD_RE[tld] = dict((k, re.compile(v, re.IGNORECASE) if isinstance(v, str) else v) for k, v in tmp.items())
        return TLD_RE[tld]
    
    
    [get_tld_re(tld) for tld in dir(tld_regexpr) if tld[0] != '_']
    

    正如我们所见,这会运行一些模块级代码,从 tld_regexpr 中的数据生成正则表达式并将它们缓存在 TLD_RE 全局表中。

    烦人的是,没有办法轻松扩展tld_regexpr 发生这种情况之前,因为这个模块是从顶层__init__.py 导入的。然后,内部代码在此之后甚至不再使用get_tld_re,即使它提供了到缓存的接口:/ 所以你需要在添加它之后在你的新TLD 上显式地调用这个get_tld_re。比如:

    from whois import tld_regexpr
    from whois._2_parse import get_tld_re  # a "private" module, but they leave us little choice
    tld_regexpr.by = {
        'extend': 'com'
    }
    get_tld_re('by')
    

    之前:

    >>> whois.query('bayern.by')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/embray/src/python-whois/whois/__init__.py", line 60, in query
        raise UnknownTld('Unknown TLD: %s\n(all known TLD: %s)' % (tld, list(TLD_RE.keys())))
    whois.exceptions.UnknownTld: Unknown TLD: by
    (all known TLD: ['com', 'uk', 'ac_uk', 'ar', 'at', 'pl', 'be', 'biz', 'br', 'ca', 'cc', 'cl', 'club', 'cn', 'co', 'jp', 'co_jp', 'cz', 'de', 'edu', 'eu', 'fr', 'id', 'info', 'io', 'it', 'kr', 'kz', 'ru', 'lv', 'me', 'mobi', 'mx', 'name', 'net', 'nyc', 'nz', 'online', 'org', 'pharmacy', 'press', 'pw', 'store', 'rest', 'ru_rf', 'security', 'sh', 'site', 'space', 'tech', 'tel', 'theatre', 'tickets', 'tv', 'us', 'uz', 'video', 'website', 'wiki', 'xyz'])
    

    之后:

    >>> from whois import tld_regexpr
    >>> from whois._2_parse import get_tld_re  # a "private" module, but they leave us little choice
    >>> tld_regexpr.by = {
    ...     'extend': 'com'
    ... }
    >>> get_tld_re('by')
    {'domain_name': re.compile('Domain Name:\\s?(.+)', re.IGNORECASE), 'registrar': re.compile('Registrar:\\s?(.+)', re.IGNORECASE), 'registrant': None, 'creation_date': re.compile('Creation Date:\\s?(.+)', re.IGNORECASE), 'expiration_date': re.compile('Registry Expiry Date:\\s?(.+)', re.IGNORECASE), 'updated_date': re.compile('Updated Date:\\s?(.+)$', re.IGNORECASE), 'name_servers': re.compile('Name Server:\\s*(.+)\\s*', re.IGNORECASE), 'status': re.compile('Status:\\s?(.+)', re.IGNORECASE), 'emails': re.compile('[\\w.-]+@[\\w.-]+\\.[\\w]{2,4}', re.IGNORECASE)}
    >>> whois.query('bayern.by')
    <whois._3_adjust.Domain object at 0x6ffffbbc9e8>
    

    我猜这个模块没有最好的可扩展性设计,但没关系——可以通过一些小的调整来修复。同时,您应该向作者提交 PR 以添加更多 ccTLD,或使可扩展性更容易。

    【讨论】:

    • 导入tld_regexpr会导致whois本身被导入,所以使用tld_regexpr的机器在你打补丁之前已经运行了。
    • 是的,我已经解释清楚了,以及如何解决它。
    • 没关系;当我测试类似的东西时,我想重新导入whois 以运行query 以某种方式重置数据。不知道我做了什么不同,但import whois; whois.query(...) 在这个补丁之后似乎确实有效。
    • 添加了演示。
    猜你喜欢
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 2013-11-09
    • 2015-05-14
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 2011-03-31
    相关资源
    最近更新 更多