如何从复杂分隔符TXT文件创建DataFrame及处理Avast病毒更新数据?
没问题,我帮你一步步解决这两个问题——先搞定复杂分隔符TXT转DataFrame,再处理Avast病毒更新数据的爬取和格式化:
解决方案
一、从含复杂分隔符的TXT文件创建DataFrame
针对你提供的Avast数据格式(混合了-、空格、逗号作为分隔符),这里有两种实用方法:
方法1:用pandas直接读取(适合规则化场景)
如果你的TXT每行格式统一是「日期 - 版本号 病毒项1, 病毒项2, ...」,可以用正则表达式作为分隔符,直接通过pandas.read_csv读取:
import pandas as pd # 正则匹配「-(前后带空格)」或者「,(后面带空格)」作为分隔符 df = pd.read_csv('avast_updates.txt', sep=r'\s*-\s*|,\s*', header=None, engine='python')
不过这种方式会把同一行的多个病毒项拆成不同列,后续需要做行转列的额外处理,适合快速初步解析。
方法2:逐行解析后构建DataFrame(更灵活精准)
如果分隔规则有变化或者需要精细化处理(比如拆分病毒类型和名称),逐行解析是更稳妥的选择,能完全匹配你期望的输出结构:
import pandas as pd import re data_records = [] with open('avast_updates.txt', 'r', encoding='utf-8') as txt_file: for line in txt_file: line = line.strip() if not line: # 跳过空行 continue # 第一步:拆分日期和后续内容(只拆分第一个「-」,避免病毒项里的符号干扰) date_str, content_str = re.split(r'\s*-\s*', line, maxsplit=1) # 第二步:拆分版本号(比如180328-2)和病毒项列表 version_num, virus_items_str = re.split(r'\s+', content_str, maxsplit=1) # 第三步:拆分多个病毒项(用「, 」分割) virus_items = virus_items_str.split(', ') # 每个病毒项单独生成一条记录 for item in virus_items: # 拆分病毒类型(比如PwrSh、ELF)和具体名称+标签 virus_type, virus_details = item.split(':', maxsplit=1) data_records.append({ 'date': date_str, 'virus_type': virus_type, 'virus_details': virus_details.strip() }) # 转成DataFrame final_df = pd.DataFrame(data_records) print(final_df)
运行后,DataFrame的每条记录对应一个病毒条目,完全符合你想要的结构化数据。
二、爬取Avast官网病毒更新历史并格式化
要爬取Avast官网的病毒更新板块,我们可以用requests获取页面内容,BeautifulSoup解析HTML,再用上面的逻辑格式化数据:
步骤1:获取页面内容
import requests from bs4 import BeautifulSoup import time # 替换成Avast病毒更新历史的实际页面URL target_url = "https://www.avast.com/en-us/virus-update-history" # 模拟浏览器请求头,避免被反爬 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } # 发送请求(添加间隔避免频繁请求) time.sleep(1) response = requests.get(target_url, headers=headers) response.raise_for_status() # 检查请求是否成功 soup = BeautifulSoup(response.text, 'html.parser')
步骤2:提取并格式化更新数据
首先需要查看Avast官网的HTML结构,找到存放更新历史的容器(比如某个class的<div>或<li>),然后提取内容并解析:
# 示例:假设更新条目都在class为"virus-update-item"的div里(实际需要根据页面源码调整) update_entries = soup.find_all('div', class_='virus-update-item') parsed_results = [] for entry in update_entries: # 提取条目文本并清理多余空格 raw_text = ' '.join(entry.get_text().split()) if not raw_text: continue # 复用之前的逐行解析逻辑 date_str, content_str = re.split(r'\s*-\s*', raw_text, maxsplit=1) version_num, virus_items_str = re.split(r'\s+', content_str, maxsplit=1) virus_items = virus_items_str.split(', ') for item in virus_items: virus_type, virus_details = item.split(':', maxsplit=1) parsed_results.append({ 'date': date_str, 'virus_type': virus_type, 'virus_details': virus_details.strip() }) # 转成DataFrame或输出成你想要的纯文本格式 result_df = pd.DataFrame(parsed_results) # 输出纯文本格式 for _, row in result_df.iterrows(): print(f"{row['date']} {row['virus_type']} {row['virus_details']}")
注意事项
- 页面结构可能会随时间变化,爬取前一定要查看Avast官网的HTML源码,调整
BeautifulSoup的查找规则; - 如果页面是动态加载的(比如滚动加载更多内容),需要用
selenium或playwright来获取动态渲染的内容; - 爬取时不要过于频繁,避免触发反爬机制,建议每次请求间隔1-2秒。
内容的提问来源于stack exchange,提问作者Sagar Howal
相关产品推荐
相关产品推荐

