Python代码无法从mem.raw提取URL并统计至字典的问题排查
问题分析与修复:从二进制文件提取URL并统计次数
问题描述
需要从mem.raw文件中提取所有URL,统计每个URL的出现次数并通过PrettyTable输出,但现有代码的for URL in fileContents循环无法找到匹配的URL,也无法正确将结果存入统计字典。
错误原因分析
- 遍历对象错误:
fileContents是二进制字节串,for URL in fileContents会逐个遍历每个字节(比如b'\x48'这种单个字节值),而不是遍历匹配到的URL,导致字典里存的全是单个字节的统计,和目标URL完全无关。 - 匹配结果未利用:每次循环都调用
urlPattern.findall(fileContents)获取当前chunk的所有URL匹配结果,但完全没使用这个urlMatches变量,反而把单个字节当作URL存入字典,逻辑完全错位。 - 异常捕获过于宽泛:直接用
except:捕获所有异常,会掩盖代码中的逻辑错误,比如键不存在的异常被处理,但其他真正的错误(如正则匹配问题)会被隐藏,不利于调试。 - 表格输出逻辑错误:在遍历字典的循环里,添加一行就打印一次表格,还加了
break,导致只输出第一行就终止;同时tbl.align = '1'是错误写法,左对齐应该用'l'。 - 未完整读取文件:代码只读取了一次指定大小的chunk,没有循环读取整个文件的内容,大文件中后续部分的URL完全不会被处理。
修复后的代码
import re import os import sys from prettytable import PrettyTable large_file = input("Enter the name of a large File: ") chunk_size = int(input("What size chunks? ")) # 适配二进制字符串的URL正则表达式 url_pattern = re.compile(b'\w+://[\w@][\w.:@]+/?[\w.?=%&=-@/$,]*') matches = {} try: if os.path.isfile(large_file): with open(large_file, 'rb') as target_file: print("\nURLs") # 循环读取整个文件的所有chunk while True: file_contents = target_file.read(chunk_size) if not file_contents: break # 读取完所有内容,退出循环 # 获取当前chunk中所有匹配的URL url_matches = url_pattern.findall(file_contents) # 统计每个URL的出现次数 for url in url_matches: # 把二进制URL转成字符串,方便展示(可选,也可直接存二进制) url_str = url.decode('utf-8', errors='ignore') if url_str in matches: matches[url_str] += 1 else: matches[url_str] = 1 # 生成并输出统计表格 tbl = PrettyTable(["URL", "Occurrences"]) tbl.align = 'l' # 左对齐 for url, cnt in matches.items(): tbl.add_row([url, cnt]) # 按出现次数倒序输出表格 print(tbl.get_string(sortby="Occurrences", reversesort=True)) else: print(f"{large_file} is not a valid file") sys.exit("Script Aborted") except Exception as err: print(f"Error occurred: {err}")
关键修改说明
- 修正遍历逻辑:不再遍历字节串的单个字节,而是遍历正则匹配到的URL列表。
- 循环读取文件:通过
while True循环持续读取chunk,直到文件全部读完。 - 合理利用匹配结果:直接使用
url_pattern.findall()返回的URL列表进行统计。 - 优化异常处理:去掉宽泛的
except:,保留顶层的异常捕获并输出具体错误信息;统计时用条件判断替代异常捕获,逻辑更清晰。 - 修复表格输出:先把所有行添加到表格后再统一打印,修正对齐参数,移除错误的
break语句。 - 二进制转字符串:将匹配到的二进制URL转成UTF-8字符串,方便在表格中正常展示(如果有无法解码的字节,忽略错误)。
内容的提问来源于stack exchange,提问作者Java_Assembly55
相关产品推荐
相关产品推荐

