[英]Extract JSON from Text in python
我想從日志文本中提取 JSON/字典。
示例日志文本:
2018-06-21 19:42:58 [scrapy.crawler] INFO: Overridden settings: {'BOT_NAME': 'locations', 'CLOSESPIDER_TIMEOUT': '14400', 'FEED_FORMAT': 'geojson', 'LOG_FILE': '/geojson_dumps/21_Jun_2018_07_42_54/logs/coastalfarm.log', 'LOG_LEVEL': 'INFO', 'NEWSPIDER_MODULE': 'locations.spiders', 'SPIDER_MODULES': ['locations.spiders'], 'TELNETCONSOLE_ENABLED': '0', 'USER_AGENT': 'Mozilla/5.0'}
2018-06-21 19:43:00 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 369,
'downloader/request_count': 1,
'downloader/request_method_count/GET': 1,
'downloader/response_bytes': 1718,
'downloader/response_count': 1,
'downloader/response_status_count/200': 1,
'finish_reason': 'finished',
'finish_time': datetime.datetime(2018, 6, 21, 14, 13, 0, 841666),
'item_scraped_count': 4,
'log_count/INFO': 8,
'memusage/max': 56856576,
'memusage/startup': 56856576,
'response_received_count': 1,
'scheduler/dequeued': 1,
'scheduler/dequeued/memory': 1,
'scheduler/enqueued': 1,
'scheduler/enqueued/memory': 1,
'start_time': datetime.datetime(2018, 6, 21, 14, 12, 58, 499385)}
2018-06-21 19:43:00 [scrapy.core.engine] INFO: Spider closed (finished)
我試過(\\{.+$\\})
作為正則表達式,但它給了我單行的字典, {'BOT_NAME': 'locations',..., 'USER_AGENT': 'Mozilla/5.0'}
這不是預期的。
我想提取的 json/dictionary:注意:字典不會有相同的鍵,它可能會有所不同。
{'downloader/request_bytes': 369,
'downloader/request_count': 1,
'downloader/request_method_count/GET': 1,
'downloader/response_bytes': 1718,
'downloader/response_count': 1,
'downloader/response_status_count/200': 1,
'finish_reason': 'finished',
'finish_time': datetime.datetime(2018, 6, 21, 14, 13, 0, 841666),
'item_scraped_count': 4,
'log_count/INFO': 8,
'memusage/max': 56856576,
'memusage/startup': 56856576,
'response_received_count': 1,
'scheduler/dequeued': 1,
'scheduler/dequeued/memory': 1,
'scheduler/enqueued': 1,
'scheduler/enqueued/memory': 1,
'start_time': datetime.datetime(2018, 6, 21, 14, 12, 58, 499385)}
編輯:JSON跨越多行,所以這是將要執行的操作:
import re
re_str = '\d{2}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} \[scrapy\.statscollectors] INFO: Dumping Scrapy stats:.({.+?\})'
stats_re = re.compile(re_str, re.MULTILINE | re.DOTALL)
for match in stats_re.findall(log):
print(match)
如果您只關注statscollector中的各行,那么這應該可以幫助您(假設所有內容也都在同一行上):
^.*?\[scrapy.statscollectors] INFO: Dumping Scrapy stats: (\{.+$\}).*?$
使用 JSON 標記器使這成為一項非常簡單和高效的任務,只要您有一個錨點可以在原始文檔中搜索,至少可以識別 JSON blob 的開頭。 這使用json-5從 HTML 中提取 JSON:
import json5.tokenizer
with open('5f32d5b4e2c432f660e1df44.html') as f:
document = f.read()
search_for = "window.__INITIAL_STATE__="
i = document.index(search_for)
j = i + len(search_for)
extract_from = document[j:]
tokens = json5.tokenizer.tokenize(extract_from)
stack = []
collected = []
for token in tokens:
collected.append(token.value)
if token.type in ('LBRACE', 'LBRACKET'):
stack.append(token)
elif token.type in ('RBRACE', 'RBRACKET'):
stack.pop()
if not stack:
break
json_blob = ''.join(collected)
請注意,這將 JSON 解釋為復雜(對象、列表)或標量類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.