解析TLE文件时核心变量为空的技术问题求助
TLE解析变量为空问题排查与解决
问题核心原因
- 行参数传递错误:原代码中
Satellite类初始化时,误将卫星名字行当作TLE数据行解析,从非数据行提取的内容无法转换为数字,导致变量返回None。 - 未处理空行:原解析函数未过滤TLE文件中的空行,导致读取的行序列混乱,无法拿到正确的TLE数据行。
修复后的代码
import requests from sqlalchemy import create_engine, Column, Integer, Float, String from sqlalchemy.orm import declarative_base from sqlalchemy.orm import sessionmaker class Satellite: def __init__(self, name, tle_line1, tle_line2): self.name = name self.tle_line1 = tle_line1 self.tle_line2 = tle_line2 # 从TLE第一行解析字段 self.satellite_catalog_number = self.parse_int(tle_line1[2:7]) self.classification = tle_line1[7] self.international_designator = tle_line1[9:17] self.epoch_year = self.parse_int(tle_line1[18:20]) self.epoch_day = self.parse_float(tle_line1[20:32]) self.first_derivative_mean_motion = self.parse_float(tle_line1[33:43]) # 处理二阶导数的科学计数法格式 second_deriv = tle_line1[44:52].strip() self.second_derivative_mean_motion = self.parse_float(self.convert_sci_notation(second_deriv)) # 处理B*的科学计数法格式 bstar_val = tle_line1[53:61].strip() self.bstar = self.parse_float(self.convert_sci_notation(bstar_val)) self.element_set_number = self.parse_int(tle_line1[64:68]) # 从TLE第二行解析字段 self.inclination = self.parse_float(tle_line2[8:16]) self.raan = self.parse_float(tle_line2[17:25]) self.eccentricity = self.parse_float(f"0.{tle_line2[26:33]}") self.arg_of_perigee = self.parse_float(tle_line2[34:42]) self.mean_anomaly = self.parse_float(tle_line2[43:51]) self.mean_motion = self.parse_float(tle_line2[52:63]) self.revolution_number = self.parse_int(tle_line2[63:68]) def convert_sci_notation(self, value): # 转换TLE特有的科学计数格式(如00000-0 → 0e-0,98086-4 → 98086e-4) if not value: return "0" if '-' in value: parts = value.split('-') return f"{parts[0]}e-{parts[1]}" if len(parts) ==2 else value if '+' in value: parts = value.split('+') return f"{parts[0]}e+{parts[1]}" if len(parts)==2 else value return value def parse_float(self, value): try: return float(value.strip()) except (ValueError, TypeError): return None def parse_int(self, value): try: return int(value.strip()) except (ValueError, TypeError): return None def __str__(self): return f"Name: {self.name}\nSatellite Catalog Number: {self.satellite_catalog_number}\n" \ f"Classification: {self.classification}\nInternational Designator: {self.international_designator}\n" \ f"Epoch Year: {self.epoch_year}\nEpoch Day: {self.epoch_day}\n" \ f"First Derivative of Mean Motion: {self.first_derivative_mean_motion}\n" \ f"Second Derivative of Mean Motion: {self.second_derivative_mean_motion}\n" \ f"B* Drag Term: {self.bstar}\nElement Set Number: {self.element_set_number}\n\n" \ f"Inclination: {self.inclination}\nRAAN: {self.raan}\nEccentricity: {self.eccentricity}\n" \ f"Argument of Perigee: {self.arg_of_perigee}\nMean Anomaly: {self.mean_anomaly}\n" \ f"Mean Motion: {self.mean_motion}\nRevolution Number: {self.revolution_number}\n" def parse_tle_file(file_path): with open(file_path, 'r') as file: # 过滤空行,仅保留有效数据行 lines = [line.strip() for line in file if line.strip()] satellites = [] i = 0 # 每3行对应一组卫星数据:名字行、TLE行1、TLE行2 while i + 2 < len(lines): name_line = lines[i] tle_line1 = lines[i+1] tle_line2 = lines[i+2] if name_line.startswith('0') and tle_line1.startswith('1') and tle_line2.startswith('2'): name = name_line[2:].strip() satellite = Satellite(name, tle_line1, tle_line2) satellites.append(satellite) i += 3 return satellites # 使用示例 tle_file_path = 'C:/Users/avelascoe/Documents/Indra/BaseTLELEO/Follow/3le20210612.txt' satellites = parse_tle_file(tle_file_path) for satellite in satellites: print(satellite) # 数据库连接配置 mydb = { "user": "root", "password": "root", "host": "localhost", "port": "3306", "database": "prueba", } connection_string = f'mysql+mysqlconnector://{mydb["user"]}:{mydb["password"]}@{mydb["host"]}:{mydb["port"]}/{mydb["database"]}' engine = create_engine(connection_string) Base = declarative_base() class SatelliteModel(Base): __tablename__ = 'satellites2' id = Column(Integer, primary_key=True) name = Column(String(255)) satellite_catalog_number = Column(Integer) classification = Column(String(1)) international_designator = Column(String(8)) epoch_year = Column(Integer) epoch_day = Column(Float) first_derivative_mean_motion = Column(Float) second_derivative_mean_motion = Column(Float) bstar = Column(Float) element_set_number = Column(Integer) inclination = Column(Float) raan = Column(Float) eccentricity = Column(Float) arg_of_perigee = Column(Float) mean_anomaly = Column(Float) mean_motion = Column(Float) revolution_number = Column(Integer) def __init__(self, satellite): self.name = satellite.name self.satellite_catalog_number = satellite.satellite_catalog_number self.classification = satellite.classification self.international_designator = satellite.international_designator self.epoch_year = satellite.epoch_year self.epoch_day = satellite.epoch_day self.first_derivative_mean_motion = satellite.first_derivative_mean_motion self.second_derivative_mean_motion = satellite.second_derivative_mean_motion self.bstar = satellite.bstar self.element_set_number = satellite.element_set_number self.inclination = satellite.inclination self.raan = satellite.raan self.eccentricity = satellite.eccentricity self.arg_of_perigee = satellite.arg_of_perigee self.mean_anomaly = satellite.mean_anomaly self.mean_motion = satellite.mean_motion self.revolution_number = satellite.revolution_number def __str__(self): return f"Name: {self.name}\nSatellite Catalog Number: {self.satellite_catalog_number}\n" \ f"Classification: {self.classification}\nInternational Designator: {self.international_designator}\n" \ f"Epoch Year: {self.epoch_year}\nEpoch Day: {self.epoch_day}\n" \ f"First Derivative of Mean Motion: {self.first_derivative_mean_motion}\n" \ f"Second Derivative of Mean Motion: {self.second_derivative_mean_motion}\n" \ f"B* Drag Term: {self.bstar}\nElement Set Number: {self.element_set_number}\n\n" \ f"Inclination: {self.inclination}\nRAAN: {self.raan}\nEccentricity: {self.eccentricity}\n" \ f"Argument of Perigee: {self.arg_of_perigee}\nMean Anomaly: {self.mean_anomaly}\n" \ f"Mean Motion: {self.mean_motion}\nRevolution Number: {self.revolution_number}\n" Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() for satellite in satellites: satellite_entry = SatelliteModel(satellite) session.add(satellite_entry) session.commit() session.close()
关键修复点
- 行参数修正:
Satellite类现在接收正确的TLE数据行(tle_line1和tle_line2)进行字段解析,不再使用名字行。 - 空行过滤:解析函数先过滤文件中的空行,确保每3行是一组完整的卫星数据。
- 科学计数法转换:新增
convert_sci_notation方法,将TLE特有的科学计数格式转换为Python可识别的格式,避免转换失败。
验证结果
修复后运行代码,所有目标字段(satellite_catalog_number、epoch_year、mean_motion等)都会正确提取并转换,不再为空,且能正常存入数据库。
内容的提问来源于stack exchange,提问作者Sly_Cooper
相关产品推荐
相关产品推荐

