gpt4 book ai didi

python - 我的 Python Set() 中的某些元素最终变成了十六进制

转载 作者:行者123 更新时间:2023-12-01 01:44:50 25 4
gpt4 key购买 nike

我试图将 fortinet 日志解析为 csv 文件。部分代码将读取日志文件中的全部 400 万行,并将“=”号之前的任何单词保存为 set() 中的元素。这些元素将成为 csv 标题。

当尝试解析 500000 行时,该集合看起来不错,但是当我尝试解析 100 万行时,某些元素开始变成长十六进制值。

附件是最终的样子。

C:\Python27>python.exe D:\parser\logtocsv.py
* Finding Column Headers 2018-07-24 08:59:23
completed 1517027 lines
set(['', 'shapersentname', 'tuple-num', 'bandwidth', 'totalsession', 'disk', 'hook', 'HTTP/1.1in.css?ver', 'group', 'HTTP/1.13&ip', 'to',
'\xe7\xbf\xbb\xe4\xba\x86\xe5\x8d\x8a\xe5\xa4\xa9\xe6\x89\x8d\xe6\x89\xbe\xe5\x88\xb0\xe4\xbd\xa0\xef\xbc\x8cJia\xe6\x88\x91\xe5\xb8\xb8\xe7\x
94\xa8\xe6\x89\xa3\xe5\x8f\xb7706772123\xe5\x88\xab\xe5\x86\x8d\xe5\x88\xa0\xe6\x88\x91\xe5\x95\xa6~', 'HTTP/1.1?cms_redirect', 'analyticscksu
m', 'devname', 'setuprate', 'appact', 'fazlograte', 'recipient', 'sentpkt', 'shaperrcvdname', 'level', 'subtype', 'attackid', 'appid', 'dir',
'profile', 'sentbyte', 'crscore', 'duration', 'analyticssubmit', 'subject', 'error', 'eventtype', 'dstcountry', 'countweb', 'filename', 'diskl
ograte', 'applist', 'fcni', 'ref', 'method', 'mem', 'incidentserialno', 'processtime', 'reason', 'dstintf', 'srcintf', 'countav', 'sender', 'v
irusid', 'logid', 'HTTP/1.1ver', 'act', 'action', 'carrier_ep', 'policyid', 'dstip', 'rcvdbyte', 'srccountry', 'dtype', 'app', 'utmaction', 's
rcip', '\xe7\xbf\xbb\xe4\xba\x86\xe5\x8d\x8a\xe5\xa4\xa9\xe6\x89\x8d\xe6\x89\xbe\xe5\x88\xb0\xe4\xbd\xa0\xef\xbc\x8cJia\xe6\x88\x91\xe5\xb8\xb
8\xe7\x94\xa8\xe6\x89\xa3\xe5\x8f\xb7715859168\xe5\x88\xab\xe5\x86\x8d\xe5\x88\xa0\xe6\x88\x91\xe5\x95\xa6~', 'crlevel', 'shaperdropsentbyte',
'rsso_key', 'from', 'log', 'service', 'fdni', 'devid', '\xe5\xbe\x88\xe5\xbc\x80\xe5\xbf\x83\xef\xbc\x8c\xe8\x83\xbd\xe6\x89\xbe\xe5\x88\xb0\
xe4\xbd\xa0\xef\xbc\x81Jia\xe4\xb8\x8b\xe6\x88\x91\xe5\xb8\xb8\xe7\x94\xa8q\xe5\x8f\xb7717598789\xe5\x88\xab\xe5\xbf\x98\xe4\xba\x86\xef\xbc\x
81', 'attack', 'filesize', 'logdesc', 'poluuid', 'msg', 'type', 'direction', 'authproto', 'sessionid', 'shaperdroprcvdbyte', 'countips', 'coun
t', 'datarange', 'cat', 'ui', 'countapp', 'rcvdpkt', 'quarskip', 'vd', 'craction', 'file', 'apprisk', 'severity', 'proto', 'hostname', 'new_st
atus', 'attachment', 'dstport', 'status', 'acct_stat', 'time', 'fsci', 'catdesc', 'virus', 'reporttype', 'user', 'reqtype', 'date', 'old_statu
s', 'countemail', 'url', 'appcat', 'srcport', 'command', 'trandisp', 'cpu'])
pause^A

下面是我的代码部分,它将元素保存在我的 set() 中:

import csv
import time
import datetime
def findColumnHeaders(log_file_path):
ts = time.time()
st = datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
print "* Finding Column Headers " + st
f = open(log_file_path, "r")
col_headers = set() # create empty set for all column headers
col_headers_old = set()
content = f.readlines()
content = [x.strip() for x in content]# List of lines to iterate through
current_col_header = ""
start = False
count = 0
letter_chr = 0
line_number = 0
letter_number = 0
for line in content:
letter_number = 0
line_number += 1
for letter in line:
letter_number += 1
if letter == " ":
# space means start taking in new col_value
# data is in this structure with space prior to column names -> " column=col_value"
start = True
current_col_header = ""
elif letter == "=":
# when hits "=", means that prior word is a column col_value -> "column=col_value"
col_headers.add(current_col_header)
# reset current_col_header to empty string
current_col_header = ""
# only take in once another space has been encountered
start = False
continue
elif start:
current_col_header += letter
# else, do nothing
print "completed " + str(line_number) + " lines"
print col_headers
raw_input("pause")
return col_headers

最佳答案

您的问题是您正在打印 UTF-8 编码的字符串。例如,这个:

'\xe7\xbf\xbb\xe4\xba\x86\xe5\x8d\x8a\xe5\xa4\xa9\xe6\x89\x8d\xe6\x89\xbe\xe5\x88\xb0\xe4\xbd\xa0\xef\xbc\x8cJia\xe6\x88\x91\xe5\xb8\xb8\xe7\x94\xa8\xe6\x89\xa3\xe5\x8f\xb7706772123\xe5\x88\xab\xe5\x86\x8d\xe5\x88\xa0\xe6\x88\x91\xe5\x95\xa6~'

…是这个字符串的UTF-8编码:

翻了半天才找到你,Jia我常用扣号706772123别再删我啦~

您想要做的是将 UTF-8 str 字节字符串解码unicode 文本字符串。

<小时/>

执行此操作的最干净的地方是尽早 - 告诉文件对象本身为您解码。您可以使用 codecs.open如果您想与 Python 2.6 及更早版本兼容,或 io.open如果您想与 Python 3 兼容。无论哪种方式,您都需要将 "=" 之类的字符串文字替换为 u"=" 之类的 unicode 文字>。因此,例如:

f = io.open(log_file_path, "r", encoding="utf-8")
# ...
current_col_header = u""
# ...
if letter == u" ":
# etc.
<小时/>

另一方面,最小的变化是尽可能执行此操作,仅当您将它们存储在集合中时才手动解码它们:

col_headers.add(current_col_header.decode('utf-8')

...甚至稍后,当您打印出内容时:

print {header.decode('utf-8') for header in col_headers}
<小时/>

第一种方法的好处是,如果您想查找任何非 ASCII 字符,可以使用 unicode 字符串来实现。例如,unicode形式的中文字符串中的第一个字母是u'翻',所以你可以这样做if letter == u'翻':; UTF-8 形式的中文字符串中的第一个字节是 '\xe7',因此您不能执行 if letter == '翻': (并且,当您可以if letter == '\xe7',这是不正确的,因为许多其他字符以相同的\xe7字节开头) .

但如果这永远不会成为问题,那么您可以采用任何一种方式。

<小时/>

顺便说一句,由于您使用的是 Windows 并使用 Python 2.7,因此尝试打印非 ASCII 字符串可能不起作用。有一些解决方法,但它们都很痛苦。简单的解决方案是切换到 Python 3。(事实上,在 Python 3 中,整个问题一开始就不会出现,因为文件自动解码 UTF-8,并且每个字符串自动都是 Unicode 字符串。)但是如果由于某种原因你无法升级,并且遇到这个问题,你将需要那些可怕的解决方法之一。

关于python - 我的 Python Set() 中的某些元素最终变成了十六进制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51490693/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com