【问题标题】:convert large string output to dictionary将大字符串输出转换为字典
【发布时间】:2017-10-09 15:55:31
【问题描述】:

我有一个看起来像这样的函数,它在给定 url 时查找 who.is 上的域:

import whois    

def who_is(url):
    w = whois.whois(url)
    return w.text

返回一个巨大的字符串:

Domain name:
    amazon.co.uk

Registrant:
    Amazon Europe Holding Technologies SCS

Registrant type:
    Unknown

Registrant's address:
    65 boulevard G-D. Charlotte
    Luxembourg City
    Luxembourg
    LU-1311
    Luxembourg

Data validation:
    Nominet was able to match the registrant's name and address against a 3rd party data source on 10-Dec-2012

Registrar:
    Amazon.com, Inc. t/a Amazon.com, Inc. [Tag = AMAZON-COM]
    URL: http://www.amazon.com

Relevant dates:
    Registered on: before Aug-1996
    Expiry date:  05-Dec-2020
    Last updated:  23-Oct-2013

Registration status:
    Registered until expiry date.

Name servers:
    ns1.p31.dynect.net
    ns2.p31.dynect.net
    ns3.p31.dynect.net
    ns4.p31.dynect.net
    pdns1.ultradns.net
    pdns2.ultradns.net
    pdns3.ultradns.org
    pdns4.ultradns.org
    pdns5.ultradns.info
    pdns6.ultradns.co.uk      204.74.115.1  2610:00a1:1017:0000:0000:0000:0000:0001

WHOIS lookup made at 21:09:42 10-May-2017

 -- 
   This WHOIS information is provided for free by Nominet UK the central registry
for .uk domain names. This information and the .uk WHOIS are:

Copyright Nominet UK 1996 - 2017.

You may not access the .uk WHOIS or use any data from it except as permitted
by the terms of use available in full at http://www.nominet.uk/whoisterms,
 which includes restrictions on: (A) use of the data for advertising, or its
 repackaging, recompilation, redistribution or reuse (B) obscuring, removing
 or hiding any or all of this notice and (C) exceeding query rate or volume
limits. The data is provided on an 'as-is' basis and may lag behind the
register. Access may be withdrawn or restricted at any time. 

所以只要看看它,我就可以看到布局可以将它变成字典,但不确定如何以最有效的方式实际执行它。我需要删除底部不需要的文本,并删除所有换行符和缩进。单独完成不是很有效。我希望能够将任何 url 传递给函数并使用字典。任何帮助将非常感激。

期望的输出是:

dict = {
'Domain name':'amazon.co.uk',
'Registrant':'Amazon Europe Holding Technologies'
'Registrant type': 'Unknown'
and so on for all the available fields.
}

到目前为止,我已经尝试使用 remove 函数删除所有 \n 新行和 \r,然后用 replace 函数替换所有缩进。但是我完全不确定如何删除底部的大量文本。

python-whois 文档告诉您只打印 w 但是这样做时它会返回以下内容:

{
  "domain_name": null,
  "registrar": null,
  "registrar_url": "http://www.amazon.com",
  "status": null,
  "registrant_name": null,
  "creation_date": "before Aug-1996",
  "expiration_date": "2020-12-05 00:00:00",
  "updated_date": "2013-10-23 00:00:00",
  "name_servers": null
 }

如您所见,其中大部分值是 null,但在返回 w.text 时,它们确实有值

【问题讨论】:

  • @abccd 我已经添加了一些说明,我并没有要求有人为我做这件事,如果遇到这种情况,我很抱歉,我正在寻找更多关于如何去的想法关于有效地做到这一点。我可以通过将字符串转换为列表并使用替换删除它们来删除所有缩进,然后删除所有\n\rs,然后将其重新转换为由:拆分的字符串,然后我会让所有偶数索引成为键,奇数索引成为值。但这似乎效率不高,而且似乎是不好的做法。
  • 说真的,python-whois 看起来像一个不错的库,任何解析 w.text 的尝试都会真正违背它的目的。为您的用例修复它确实应该是要走的路。不幸的是,它依赖于正则表达式,如果你不熟悉这些可能会很痛苦。但是,如果您打开一张包含所有所需信息(不多,只是 URL 和您的输出)的票证,开发人员可能会为您解决问题...

标签: python string python-3.x dictionary


【解决方案1】:

显然,您使用的是python-whois

查看example。您可以以结构化形式获取所有数据,而不是需要解析的文本:

import whois
w = whois.whois('webscraping.com')
w.expiration_date  # dates converted to datetime object
# datetime.datetime(2013, 6, 26, 0, 0)
w.text  # the content downloaded from whois server
# u'\nWhois Server Version 2.0\n\nDomain names in the .com and .net ...'

print w  # print values of all found attributes
# creation_date: 2004-06-26 00:00:00
# domain_name: [u'WEBSCRAPING.COM', u'WEBSCRAPING.COM']
# emails: [u'WEBSCRAPING.COM@domainsbyproxy.com', u'WEBSCRAPING.COM@domainsbyproxy.com']
# expiration_date: 2013-06-26 00:00:00

您从 whois 对象 (w) 中一一获取所需的所有属性,并将它们存储在 dict 中,或者将对象本身传递给需要这些信息的任何函数。

w.text 中是否有任何信息无法作为w 的属性访问?

编辑:

它适用于我,使用与您相同的示例 URL。

pip install python-whois
pip freeze |grep python-whois
# python-whois==0.6.5

import whois
w = whois.whois("amazon.co.uk")
w
# {'updated_date': datetime.datetime(2013, 10, 23, 0, 0), 'creation_date': 'before Aug-1996', 'registrar': None, 'registrar_url': 'http://www.amazon.com', 'domain_name': None, 'expiration_date': datetime.datetime(2020, 12, 5, 0, 0), 'name_servers': None, 'status': None, 'registrant_name': None}

 编辑 2:

如果我认为我在解析器中发现了问题。

正则表达式不应该是

'Registrant:\n\s*(.*)'

但是

'Registrant:\r\n\s*(.*)'

您可以尝试在本地克隆whois 并像这样修改它(添加\r),然后如果可行,请提出此补丁,或者至少在bug report 中提及。

【讨论】:

  • 当您尝试访问 w 时,它会返回您解析为未知的任何字段,而当您将其作为 w.text 返回时,您可以看到实际数据在那里。
  • 查看您的输出,我可以看到注册人名称、名称服务器、域名等字段的值为 None,但在 w.text 中它们有值。
  • .uk parser 似乎有问题。也许您可以在 bitbucket 上打开一个错误。
  • 谢谢你,我已经提交了一个错误报告,我会发消息告诉他们你找到了问题和你建议的修复,再次感谢你这对我有很大帮助。
【解决方案2】:

试试这个:

from collections import OrderedDict

key_value=OrderedDict() #use dict() if order of keys is not important

for block in textstring.split("\n\n"): #textstring contains the string of w.text.
    try:
        key_value[block.split(":\n")[0].strip()] = '\n'.join(element.strip() for element in block.split(":\n")[1].split('\n'))
    except IndexError:
        pass

#print the result
for key in key_value:
    print(key)
    print(key_value[key])
    print("\n")

【讨论】:

    猜你喜欢
    • 2023-01-28
    • 2020-02-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    相关资源
    最近更新 更多