2

我正在使用丰富的库来解析通过 aiohttp 检索到的 json 数据。它直接从 API 打印数据效果很好,格式很好(带有换行符,因此不难阅读):

{
    'city': 'Haidian',
    'region_code': 'BJ',
    'os': None,
    'tags': [],
    'ip': 1699530633,
    'isp': 'China Education and Research Network Center',
    'area_code': None,
    'longitude': 116.28868,
    'last_update': '2021-12-16T05:42:00.377583',
    'ports': [8888],
    'latitude': 39.99064,
    'hostnames': [],
    'postal_code': None,
    'country_code': 'CN',
    'country_name': 'China',
    'domains': [],
    'org': 'China Education and Research Network',
    'data': [
        {
            '_shodan': {'options': {}, 'id': '1d25e274-18ce-4a3d-8e1c-73e5bf35bf76', 'module': 'http-simple-new', 'crawler': '42f86247b760542c0192b61c60405edc5db01d55'},
            'hash': -1008250258,
            'os': None,
            'opts': {},
            'timestamp': '2021-12-16T05:42:00.377583',
            'isp': 'China Education and Research Network Center',
            'port': 8888,
            'hostnames': [],
            'location': {'city': 'Haidian', 'region_code': 'BJ', 'area_code': None, 'longitude': 116.28868, 'country_name': 'China', 'postal_code': None, 'country_code': 'CN', 'latitude': 39.99064},
            'ip': 1699530633,
            'domains': [],
            'org': 'China Education and Research Network',
            'data': 'GET / HTTP/1.1\r\nHost: 101.76.199.137\r\n\r\n',
            'asn': 'AS4538',
            'transport': 'tcp',
            'ip_str': '101.x.199.x'
        }
    ],
    'asn': 'AS4538',
    'ip_str': '101.x.199.x'
}

然后程序将其附加到字典中,例如:

ipInfo = {}
async def host(ip):
    ret = await fetch(ip) 
    ipInfo[ip] = ret

然后在它完成了一个 ip 地址列表之后,它将这个字典写入一个文件。我遇到的问题是,当我加载这些数据以稍后查看并尝试解析它时,丰富的库不会像它刚刚来自 API 时那样很好地格式化它。它总是最终看起来像:

[{'hash': -644847518, 'timestamp': '2021-12-27T15:08:16.109960', 'isp': 'VNPT Corp', 'transport': 'tcp', 'data': 'GET / HTTP/1.1\r\nHost: 113.x.185.x\r\n\r\n', 'asn': 'AS45899', 'port': 5555, 'hostnames': ['static.vnpt.vn'], 
'location': {'city': 'Vị Thanh', 'region_code': '73', 'area_code': None, 'longitude': 105.47012, 'latitude': 9.78449, 'postal_code': None, 'country_code': 'VN', 'country_name': 'Viet Nam'}, 'ip': 1906751888, 'domains': ['vnpt.vn'], 
'org': 'Vietnam Posts and Telecommunications Group', 'os': None, '_shodan': {'crawler': 'd905ab419aeb10e9c57a336c7e1aa9629ae4a733', 'options': {}, 'id': '33f5bd73-c7d7-4dc0-beb8-b17afb53d931', 'module': 'http-simple-new', 'ptr': 
True}, 'opts': {}, 'ip_str': '113.x.185.x'}], 'asn': 'AS45899', 'city': 'Vị Thanh', 'latitude': 9.78449, 'isp': 'VNPT Corp', 'longitude': 105.47012, 'last_update': '2021-12-27T15:08:16.109960', 'country_name': 'Viet Nam', 
'ip_str': '113.x.185.x', 'os': None, 'ports': [5555]}

这对我不起作用,因为我需要能够真正阅读它。我目前用来解析它的代码如下所示:

if argsc.parse:
    _print(f'Opening {argsc.parse}')
    with open(argsc.parse, 'r') as f:
        f = f.read()
        rich.print(f)
        exit(0)

我试过rich.print_json一次使用和解析字典条目,真的是各种各样的事情。我在写这篇文章时确实注意到,如果数据像第一个示例中那样保存,并且具有漂亮的换行符格式,那么它确实可以正确解析,但我也不知道该怎么做。

所以我的问题是(猜想是两个问题):1)我如何保存丰富的数据,以便以我在屏幕上看到的方式保存数据?并且:2)我如何使用第一个示例中看到的漂亮换行格式解析文件中的 json 数据?这甚至可能吗?也许这就是它返回 API 的方式,并且它的编写方式不同。但是我尝试按原样编写数据而不将其附加到字典中,但这也不起作用。

4

2 回答 2

0

当你从文件中读取时,你会得到一个字符串。Rich 不会对该字符串进行任何格式化,因为它不知道该字符串包含 JSON。

您可以使用内置json模块将该字符串解码为 Python 对象。添加import json到文件的顶部,然后my_data=json.loads(f.read())它会给你一个字典或列表,然后你可以打印。

或者,使用 Rich,您可以使用print_json在一个步骤中解析和漂亮打印包含 JSON 的字符串的方法。

将其放在代码的开头:

from rich import print_json

然后将以下内容添加到您的parse_data方法中:

print_json(f.read())
于 2021-12-30T12:06:42.130 回答
0

我想到了。答案是保存输出,就像我只是将标准输出重定向到文件一样,如本博客所述。我最终使用的功能是:

from rich import print as rprint

def write_formatted(data):
    """
    Func to write PARSABLE output 
    :param data:
    :return: nada, just print
    """
    with open(f'{argsc.output}-parsable.txt', 'a') as f:
        rprint(data, file=f)
        f.close()

以及一个稍后打开该数据并使用丰富解析它的函数:

def parse_data():
    _print(f'Opening {argsc.parse}')
    with open(argsc.parse, 'r') as f:
        f = f.read()
        rprint(f)
        exit(0)
于 2021-12-29T20:59:39.937 回答