This commit is contained in:
ls
2024-10-18 11:54:55 +08:00
parent ed6d4cc177
commit 6189eefad2
6 changed files with 12876 additions and 0 deletions

16
scripts/Dockerfile Normal file
View File

@@ -0,0 +1,16 @@
FROM python:3.12.7-slim-bookworm
# 设置工作目录
WORKDIR /app
# 复制要求的文件
COPY . /app
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 设置环境变量
ENV FLASK_APP=main.py
# 启动 Flask 应用
CMD ["flask", "run", "--host=0.0.0.0"]

245
scripts/esa.py Normal file
View File

@@ -0,0 +1,245 @@
import os
import requests
import csv
import mysql.connector
from bs4 import BeautifulSoup
import re
# 设置下载目录
download_dir = 'downloaded_files'
os.makedirs(download_dir, exist_ok=True)
# MySQL 连接配置
db_config = {
'host': 'localhost',
'user': 'your_username',
'password': 'your_password',
'database': 'your_database'
}
def save_to_mysql(data):
"""保存数据到 MySQL 数据库"""
connection = mysql.connector.connect(**db_config)
cursor = connection.cursor()
insert_query = """
INSERT INTO your_table (
sequence_number, test_object_type, test_start_date, test_end_date, test_object_name,
test_object_model, test_object_quantity, test_nature, test_purpose, device_name,
data_provider, test_commissioner, failure_criteria, failure_quantity, test_result_description,
outcome, source_project_name, source_project_type, classification, component_name,
component_model, component_batch_number, manufacturer, is_domestic, component_maturity,
wafer_material, wafer_batch_number, package_material, package_technology, is_flip_chip,
manufacturing_process, process_feature_size, process_platform, process_code, process_version,
quality_grade, reinforcement_measures, working_principle, supply_capacity, application_experience,
specification_manual, device_image, electronic_system_classification, electronic_system_name,
electronic_system_model, manufacturer, electronic_system_function, electronic_system_reinforcement_measures,
electronic_system_image, material_name, material_model, material_components, material_purpose,
material_manufacturer, material_physical_structure, material_usage_experience, irradiation_test_outline,
outline_expert_category, standard_specifications, test_steps_description, irradiation_process_power,
dc_bias_condition_description, ac_bias_condition_description, clock_frequency, test_pattern,
other_bias_conditions, irradiation_bias_schematic, test_method, test_schematic,
test_instrument_name, test_instrument_model, test_instrument_manufacturer, test_instrument_certificate,
test_software_name, test_software_developer, test_software_version, test_site_photo,
tester_name, tester_organization, tester_phone, device_operator, third_party_person, third_party_organization,
third_party_phone, other_notes, lead_aluminum_shielding, dose_rate, total_dose, dose_equivalent_material,
test_object_number, test_parameter_name, test_parameter_unit, test_parameter_result,
is_accelerated_test_data, is_annealing_data, annealing_temperature, annealing_time, raw_data,
data_processing_method, other_notes_additional
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
"""
cursor.execute(insert_query, data)
connection.commit()
cursor.close()
connection.close()
# 获取网页内容
url = 'https://esarad.esa.int/'
def scrape():
response = requests.get(url)
# 确保请求成功
if response.status_code == 200:
# 解析网页内容
soup = BeautifulSoup(response.content, 'html.parser')
# 找到所有表格
tables = soup.find_all('table')
# 提取第一个表格的内容
for row in tables[0].find_all('tr')[2:]: # 跳过标题行
cells = row.find_all(['td', 'th'])
if len(cells) >= 6: # 确保有至少六列
folder_name = cells[1].get_text(strip=True) # 第2列
file_id = cells[0].get_text(strip=True) # 第1列
download_url = f'https://esarad.esa.int/?id={file_id}&handler=DownloadDb'
# 创建文件夹
folder_path = os.path.join(download_dir, folder_name)
os.makedirs(folder_path, exist_ok=True)
# 下载文件并获取文件名
file_response = requests.get(download_url)
if file_response.status_code == 200:
# 从响应头获取文件名
content_disposition = file_response.headers.get('Content-Disposition')
filename = ''
if content_disposition:
match = re.search(r'filename="([^"]+)"', content_disposition)
if match:
filename = match.group(1)
if not filename: # 如果没有找到,则使用默认文件名
filename = f'{file_id}.pdf'
file_path = os.path.join(folder_path, filename)
with open(file_path, 'wb') as f:
f.write(file_response.content)
print(f'ESA Downloaded: {file_path}')
# 创建 CSV 文件
csv_file_path = os.path.join(folder_path, 'data.csv')
with open(csv_file_path, 'w', newline='', encoding='utf-8') as csvfile:
writer = csv.writer(csvfile)
# 写入标题行
writer.writerow([
'序号', '试验对象类型', '试验开始日期', '试验结束日期', '试验对象名称',
'试验对象型号', '试验对象数量', '试验性质', '试验目的', '装置名称',
'数据提供单位', '试验委托单位', '失效判据', '失效数量', '试验结果描述',
'成果', '来源项目名称', '来源项目类型', '分类', '元器件名称',
'元器件型号', '元器件批号', '生产单位', '是否国产', '元器件成熟度',
'晶圆材料', '晶圆批号', '封装材料', '封装技术', '是否倒装',
'制造工艺', '工艺特征尺寸', '工艺平台', '工艺代号', '工艺版本',
'质量等级', '加固措施', '工作原理', '供货能力', '应用经历',
'规范手册', '器件图片', '电子系统分类', '电子系统名称', '电子系统型号',
'生产单位', '电子系统功能', '电子系统加固措施', '电子系统图片', '材料名称',
'材料型号', '材料组分', '材料用途', '材料生产单位', '材料物理结构',
'材料使用经历', '辐照试验大纲', '大纲审核专家类别', '辐照试验所依据的标准规范',
'试验步骤(过程)描述', '辐照过程是否加电', '直流偏置条件描述', '交流偏置条件描述',
'时钟频率', '测试图形', '其他偏置条件', '辐照偏置原理图', '测试方式',
'测试原理图', '试验用仪器名称', '试验用仪器型号', '试验用仪器生产厂家',
'试验用仪器检定证书', '试验用软件名称', '试验用软件开发单位',
'试验用软件版本号', '试验现场照片', '测试人员姓名', '测试人员单位',
'测试人员电话', '装置运行人员', '第三方人员', '第三方人员单位',
'第三方人员电话', '其他需要说明的事项', '是否采用铅铝屏蔽', '剂量率',
'总剂量', '剂量等效材料', '试验对象编号', '测试参数名称',
'测试参数单位', '测试参数结果', '是否为加速试验后数据', '是否为退火数据',
'退火温度', '退火时间', '原始数据', '数据处理方法', '其他需要说明的事项'
])
# 写入数据行并保存到数据库
data_row = [
file_id, # 序号
'', # 试验对象类型(可以根据需要填充)
cells[11].get_text(strip=True), # 试验开始日期第12列
'', # 试验结束日期(可以根据需要填充)
'', # 试验对象名称(可以根据需要填充)
cells[1].get_text(strip=True), # 试验对象型号第2列
'', # 试验对象数量(可以根据需要填充)
cells[5].get_text(strip=True), # 试验性质第6列
'', # 试验目的(可以根据需要填充)
'', # 装置名称(可以根据需要填充)
'', # 数据提供单位(可以根据需要填充)
'', # 试验委托单位(可以根据需要填充)
'', # 失效判据(可以根据需要填充)
'', # 失效数量(可以根据需要填充)
'', # 试验结果描述(可以根据需要填充)
'', # 成果(可以根据需要填充)
'', # 来源项目名称(可以根据需要填充)
'', # 来源项目类型(可以根据需要填充)
'', # 分类(可以根据需要填充)
'', # 元器件名称(可以根据需要填充)
'', # 元器件型号(可以根据需要填充)
'', # 元器件批号(可以根据需要填充)
cells[3].get_text(strip=True), # 生产单位第4列
'', # 是否国产(可以根据需要填充)
'', # 元器件成熟度(可以根据需要填充)
'', # 晶圆材料(可以根据需要填充)
'', # 晶圆批号(可以根据需要填充)
'', # 封装材料(可以根据需要填充)
'', # 封装技术(可以根据需要填充)
'', # 是否倒装(可以根据需要填充)
'', # 制造工艺(可以根据需要填充)
'', # 工艺特征尺寸(可以根据需要填充)
'', # 工艺平台(可以根据需要填充)
'', # 工艺代号(可以根据需要填充)
'', # 工艺版本(可以根据需要填充)
'', # 质量等级(可以根据需要填充)
'', # 加固措施(可以根据需要填充)
'', # 工作原理(可以根据需要填充)
'', # 供货能力(可以根据需要填充)
'', # 应用经历(可以根据需要填充)
'', # 规范手册(可以根据需要填充)
'', # 器件图片(可以根据需要填充)
'', # 电子系统分类(可以根据需要填充)
'', # 电子系统名称(可以根据需要填充)
'', # 电子系统型号(可以根据需要填充)
'', # 生产单位(可以根据需要填充)
'', # 电子系统功能(可以根据需要填充)
'', # 电子系统加固措施(可以根据需要填充)
'', # 电子系统图片(可以根据需要填充)
'', # 材料名称(可以根据需要填充)
'', # 材料型号(可以根据需要填充)
'', # 材料组分(可以根据需要填充)
'', # 材料用途(可以根据需要填充)
'', # 材料生产单位(可以根据需要填充)
'', # 材料物理结构(可以根据需要填充)
'', # 材料使用经历(可以根据需要填充)
'', # 辐照试验大纲(可以根据需要填充)
'', # 大纲审核专家类别(可以根据需要填充)
'', # 辐照试验所依据的标准规范(可以根据需要填充)
'', # 试验步骤(过程)描述(可以根据需要填充)
'', # 辐照过程是否加电(可以根据需要填充)
'', # 直流偏置条件描述(可以根据需要填充)
'', # 交流偏置条件描述(可以根据需要填充)
'', # 时钟频率(可以根据需要填充)
'', # 测试图形(可以根据需要填充)
'', # 其他偏置条件(可以根据需要填充)
'', # 辐照偏置原理图(可以根据需要填充)
'', # 测试方式(可以根据需要填充)
'', # 测试原理图(可以根据需要填充)
'', # 试验用仪器名称(可以根据需要填充)
'', # 试验用仪器型号(可以根据需要填充)
'', # 试验用仪器生产厂家(可以根据需要填充)
'', # 试验用仪器检定证书(可以根据需要填充)
'', # 试验用软件名称(可以根据需要填充)
'', # 试验用软件开发单位(可以根据需要填充)
'', # 试验用软件版本号(可以根据需要填充)
'', # 试验现场照片(可以根据需要填充)
'', # 测试人员姓名(可以根据需要填充)
'', # 测试人员单位(可以根据需要填充)
'', # 测试人员电话(可以根据需要填充)
'', # 装置运行人员(可以根据需要填充)
'', # 第三方人员(可以根据需要填充)
'', # 第三方人员单位(可以根据需要填充)
'', # 第三方人员电话(可以根据需要填充)
'', # 其他需要说明的事项(可以根据需要填充)
'', # 是否采用铅铝屏蔽(可以根据需要填充)
'', # 剂量率(可以根据需要填充)
'', # 总剂量(可以根据需要填充)
'', # 剂量等效材料(可以根据需要填充)
'', # 试验对象编号(可以根据需要填充)
'', # 测试参数名称(可以根据需要填充)
'', # 测试参数单位(可以根据需要填充)
'', # 测试参数结果(可以根据需要填充)
'', # 是否为加速试验后数据(可以根据需要填充)
'', # 是否为退火数据(可以根据需要填充)
'', # 退火温度(可以根据需要填充)
'', # 退火时间(可以根据需要填充)
'', # 原始数据(可以根据需要填充)
'', # 数据处理方法(可以根据需要填充)
'' # 其他需要说明的事项(可以根据需要填充)
]
writer.writerow(data_row)
save_to_mysql(data_row)
print(f'CSV created and data saved to MySQL: {csv_file_path}')
else:
print(f'Failed to download: {download_url}')
else:
print(f'Error: {response.status_code}')

12116
scripts/index.html Normal file

File diff suppressed because it is too large Load Diff

96
scripts/main.py Normal file
View File

@@ -0,0 +1,96 @@
from flask import Flask, jsonify
from concurrent.futures import ThreadPoolExecutor
from nasa1 import scrape as scrape_nasa1
from nasa2 import scrape as scrape_nasa2
from esa import scrape as scrape_esa
from threading import Lock
app = Flask(__name__)
executor = ThreadPoolExecutor()
lock = Lock() # 创建一个锁
scrape_running = False # 爬虫执行状态标志
def run_nasa1():
try:
scrape_nasa1()
finally:
global scrape_running
scrape_running = False
def run_nasa2():
try:
scrape_nasa2()
finally:
global scrape_running
scrape_running = False
def run_esa():
try:
scrape_esa()
finally:
global scrape_running
scrape_running = False
def run_all():
try:
scrape_esa()
finally:
global scrape_running
scrape_running = False
@app.route('/scrape/nasa', methods=['GET'])
def nasa():
global scrape_running
if scrape_running:
return jsonify({"message": "NASA scraping is already in progress."})
with lock: # 只允许一个线程进入
scrape_running=True
executor.submit(run_nasa1) # 异步执行爬虫
# asyncio.create_task(scrape_nasa1()) # 异步执行爬虫
return jsonify({"message": "NASA scraping started."})
# 执行完成,重置状态
@app.route('/scrape/nasa2', methods=['GET'])
def nasa2():
global scrape_running
if scrape_running:
return jsonify({"message": "NASA scraping is already in progress."})
with lock: # 只允许一个线程进入
scrape_running=True
executor.submit(run_nasa2) # 异步执行爬虫
# asyncio.create_task(scrape_nasa2())
return jsonify({"message": "NASA scraping started."})
@app.route('/scrape/esa', methods=['GET'])
def esa():
global scrape_running
if scrape_running:
return jsonify({"message": "ESA scraping is already in progress."})
with lock: # 只允许一个线程进入
scrape_running=True
executor.submit(scrape_esa) # 异步执行爬虫
# asyncio.create_task(scrape_esa())
return jsonify({"message": "ESA scraping started."})
@app.route('/scrape/all', methods=['GET'])
def scrape_all():
global scrape_running
if scrape_running:
return jsonify({"message": "All scraping is already in progress."})
with lock: # 只允许一个线程进入
scrape_running = True
executor.submit(scrape_all) # 异步执行爬虫
return jsonify({"message": "All scraping started."})
if __name__ == '__main__':
app.run(debug=True, use_reloader=False)

214
scripts/nasa1.py Normal file
View File

@@ -0,0 +1,214 @@
import requests
import os
import time
import re
import csv
# 定义 API URL
api_url = 'https://radhome.gsfc.nasa.gov/radhome/dev/parts.cfc?method=getParts'
# 设置请求头
headers = {
'accept': 'application/json, text/javascript, */*; q=0.01',
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
'user-agent': 'Mozilla/5.0',
'x-requested-with': 'XMLHttpRequest',
}
# 获取当前时间戳
current_timestamp = str(int(time.time() * 1000))
# 设置请求数据
data = {
'_search': 'false',
'nd': current_timestamp,
'rows': '10000',
'page': '1',
'sidx': 'partnumber',
'sord': 'asc',
}
# 创建文件夹以保存文件
os.makedirs('downloaded_files', exist_ok=True)
# 文件前缀
file_prefix = 'https://radhome.gsfc.nasa.gov/radhome/papers/'
# CSV 表头
csv_header = [
"序号", "试验对象类型", "试验开始日期", "试验结束日期", "试验对象名称", "试验对象型号",
"试验对象数量", "试验性质", "试验目的", "装置名称", "数据提供单位", "试验委托单位",
"失效判据", "失效数量", "试验结果描述", "成果", "来源项目名称", "来源项目类型",
"分类", "元器件名称", "元器件型号", "元器件批号", "生产单位", "是否国产",
"元器件成熟度", "晶圆材料", "晶圆批号", "封装材料", "封装技术", "是否倒装",
"制造工艺", "工艺特征尺寸", "工艺平台", "工艺代号", "工艺版本", "质量等级",
"加固措施", "工作原理", "供货能力", "应用经历", "规范手册", "器件图片",
"电子系统分类", "电子系统名称", "电子系统型号", "生产单位", "电子系统功能",
"电子系统加固措施", "电子系统图片", "材料名称", "材料型号", "材料组分",
"材料用途", "材料生产单位", "材料物理结构", "材料使用经历", "辐照试验大纲",
"大纲审核专家类别", "辐照试验所依据的标准规范", "试验步骤(过程)描述", "辐照过程是否加电",
"直流偏置条件描述", "交流偏置条件描述", "时钟频率", "测试图形", "其他偏置条件",
"辐照偏置原理图", "测试方式", "测试原理图", "试验用仪器名称", "试验用仪器型号",
"试验用仪器生产厂家", "试验用仪器检定证书", "试验用软件名称", "试验用软件开发单位",
"试验用软件版本号", "试验现场照片", "测试人员姓名", "测试人员单位", "测试人员电话",
"装置运行人员", "第三方人员", "第三方人员单位", "第三方人员电话", "其他需要说明的事项",
"是否采用铅铝屏蔽", "剂量率", "总剂量", "剂量等效材料", "试验对象编号", "测试参数名称",
"测试参数单位", "测试参数结果", "是否为加速试验后数据", "是否为退火数据",
"退火温度", "退火时间", "原始数据", "数据处理方法", "其他需要说明的事项"
]
def scrape():
# 发送请求
response = requests.post(api_url, headers=headers, data=data)
response.raise_for_status() # 检查请求是否成功
# 解析 JSON 数据
json_data = response.json()
# 遍历数据并下载文件
for row in json_data['ROWS']:
part_number = row[0] # 部件编号
file_links_str = row[4] # 文件链接
# 使用正则表达式分隔文件名
file_links = re.split(r';|(?<=\.pdf)', file_links_str)
# 创建目录
part_number_dir = os.path.join('downloaded_files', part_number)
os.makedirs(part_number_dir, exist_ok=True)
# 创建 CSV 文件
csv_file_path = os.path.join(part_number_dir, 'data.csv')
with open(csv_file_path, 'w', newline='', encoding='utf-8') as csv_file:
csv_writer = csv.writer(csv_file)
csv_writer.writerow(csv_header) # 写入表头
# 填写 CSV 数据
csv_row = [
"", # 序号
"", # 试验对象类型
row[3], # 试验开始日期
"", # 试验结束日期
"", # 试验对象名称
row[1], # 试验对象型号
"", # 试验对象数量
row[6], # 试验性质
"", # 试验目的
"", # 装置名称
"", # 数据提供单位
"", # 试验委托单位
"", # 失效判据
"", # 失效数量
"", # 试验结果描述
"", # 成果
"", # 来源项目名称
"", # 来源项目类型
"", # 分类
"", # 元器件名称
"", # 元器件型号
"", # 元器件批号
row[2], # 生产单位
"", # 是否国产
"", # 元器件成熟度
"", # 晶圆材料
"", # 晶圆批号
"", # 封装材料
"", # 封装技术
"", # 是否倒装
"", # 制造工艺
"", # 工艺特征尺寸
"", # 工艺平台
"", # 工艺代号
"", # 工艺版本
"", # 质量等级
"", # 加固措施
"", # 工作原理
"", # 供货能力
"", # 应用经历
"", # 规范手册
"", # 器件图片
"", # 电子系统分类
"", # 电子系统名称
"", # 电子系统型号
"", # 生产单位
"", # 电子系统功能
"", # 电子系统加固措施
"", # 电子系统图片
"", # 材料名称
"", # 材料型号
"", # 材料组分
"", # 材料用途
"", # 材料生产单位
"", # 材料物理结构
"", # 材料使用经历
"", # 辐照试验大纲
"", # 大纲审核专家类别
"", # 辐照试验所依据的标准规范
"", # 试验步骤(过程)描述
"", # 辐照过程是否加电
"", # 直流偏置条件描述
"", # 交流偏置条件描述
"", # 时钟频率
"", # 测试图形
"", # 其他偏置条件
"", # 辐照偏置原理图
"", # 测试方式
"", # 测试原理图
"", # 试验用仪器名称
"", # 试验用仪器型号
"", # 试验用仪器生产厂家
"", # 试验用仪器检定证书
"", # 试验用软件名称
"", # 试验用软件开发单位
"", # 试验用软件版本号
"", # 试验现场照片
"", # 测试人员姓名
"", # 测试人员单位
"", # 测试人员电话
"", # 装置运行人员
"", # 第三方人员
"", # 第三方人员单位
"", # 第三方人员电话
"", # 其他需要说明的事项
"", # 是否采用铅铝屏蔽
"", # 剂量率
"", # 总剂量
"", # 剂量等效材料
"", # 试验对象编号
"", # 测试参数名称
"", # 测试参数单位
"", # 测试参数结果
"", # 是否为加速试验后数据
"", # 是否为退火数据
"", # 退火温度
"", # 退火时间
"", # 原始数据
"", # 数据处理方法
"", # 其他需要说明的事项
]
# 写入 CSV 行
csv_writer.writerow(csv_row)
# 下载文件
for file_name in file_links:
file_name = file_name.strip() # 去除空格
if file_name:
# 拼接文件完整 URL
file_url = file_name if file_name.startswith('http') else file_prefix + file_name
try:
# 下载文件
file_response = requests.get(file_url)
file_response.raise_for_status()
# 保存文件
file_path = os.path.join(part_number_dir, os.path.basename(file_url))
with open(file_path, 'wb') as file:
file.write(file_response.content)
print(f"NASA Download file: {file_path}")
except requests.RequestException as e:
print(f"NASA Download file error : {file_url}error: {e}")
# 输出数据
# for row in json_data['ROWS']:
# print(row)

189
scripts/nasa2.py Normal file
View File

@@ -0,0 +1,189 @@
import requests
from lxml import html
import os
import csv
# 定义页面 URL
url = 'https://radhome.gsfc.nasa.gov/radhome/papers/TIDPart.html'
# 创建文件夹以保存文件
os.makedirs('downloaded_files', exist_ok=True)
# CSV 表头
csv_header = [
"序号", "试验对象类型", "试验开始日期", "试验结束日期", "试验对象名称", "试验对象型号",
"试验对象数量", "试验性质", "试验目的", "装置名称", "数据提供单位", "试验委托单位",
"失效判据", "失效数量", "试验结果描述", "成果", "来源项目名称", "来源项目类型",
"分类", "元器件名称", "元器件型号", "元器件批号", "生产单位", "是否国产",
"元器件成熟度", "晶圆材料", "晶圆批号", "封装材料", "封装技术", "是否倒装",
"制造工艺", "工艺特征尺寸", "工艺平台", "工艺代号", "工艺版本", "质量等级",
"加固措施", "工作原理", "供货能力", "应用经历", "规范手册", "器件图片",
"电子系统分类", "电子系统名称", "电子系统型号", "生产单位", "电子系统功能",
"电子系统加固措施", "电子系统图片", "材料名称", "材料型号", "材料组分",
"材料用途", "材料生产单位", "材料物理结构", "材料使用经历", "辐照试验大纲",
"大纲审核专家类别", "辐照试验所依据的标准规范", "试验步骤(过程)描述", "辐照过程是否加电",
"直流偏置条件描述", "交流偏置条件描述", "时钟频率", "测试图形", "其他偏置条件",
"辐照偏置原理图", "测试方式", "测试原理图", "试验用仪器名称", "试验用仪器型号",
"试验用仪器生产厂家", "试验用仪器检定证书", "试验用软件名称", "试验用软件开发单位",
"试验用软件版本号", "试验现场照片", "测试人员姓名", "测试人员单位", "测试人员电话",
"装置运行人员", "第三方人员", "第三方人员单位", "第三方人员电话", "其他需要说明的事项",
"是否采用铅铝屏蔽", "剂量率", "总剂量", "剂量等效材料", "试验对象编号", "测试参数名称",
"测试参数单位", "测试参数结果", "是否为加速试验后数据", "是否为退火数据",
"退火温度", "退火时间", "原始数据", "数据处理方法", "其他需要说明的事项"
]
def scrape():
# 发送请求
response = requests.get(url)
response.raise_for_status()
# 使用 lxml 解析 HTML
tree = html.fromstring(response.text)
# 找到目标表格
table = tree.xpath('/html/body/table[3]')[0] # 获取第一个表格
# 遍历表格行,跳过表头
for row in table.xpath('.//tr')[1:]: # 跳过表头
columns = row.xpath('.//td')
if len(columns) < 8:
continue # 跳过不完整的行
part_number = columns[2].text_content().strip() # 第三列 Part Number
file_link_tag = columns[7].xpath('//a') # 第八列的 <a> 标签
# 获取文件名和下载链接
file_url = 'https://radhome.gsfc.nasa.gov/' + file_link_tag[0].get('href')
# 创建目录
part_number_dir = os.path.join('downloaded_files', part_number)
os.makedirs(part_number_dir, exist_ok=True)
# 创建 CSV 文件
csv_file_path = os.path.join(part_number_dir, 'data.csv')
with open(csv_file_path, 'w', newline='', encoding='utf-8') as csv_file:
csv_writer = csv.writer(csv_file)
csv_writer.writerow(csv_header) # 写入表头
# 填写 CSV 数据
csv_row = [
"", # 序号
"", # 试验对象类型
columns[8].text_content().strip(), # 试验开始日期
"", # 试验结束日期
"", # 试验对象名称
columns[2].text_content().strip(), # 试验对象型号
"", # 试验对象数量
columns[4].text_content().strip(), # 试验性质
"", # 试验目的
"", # 装置名称
"", # 数据提供单位
"", # 试验委托单位
"", # 失效判据
"", # 失效数量
"", # 试验结果描述
"", # 成果
"", # 来源项目名称
"", # 来源项目类型
"", # 分类
"", # 元器件名称
"", # 元器件型号
"", # 元器件批号
columns[5].text_content().strip(), # 生产单位
"", # 是否国产
"", # 元器件成熟度
"", # 晶圆材料
"", # 晶圆批号
"", # 封装材料
"", # 封装技术
"", # 是否倒装
"", # 制造工艺
"", # 工艺特征尺寸
"", # 工艺平台
"", # 工艺代号
"", # 工艺版本
"", # 质量等级
"", # 加固措施
"", # 工作原理
"", # 供货能力
"", # 应用经历
"", # 规范手册
"", # 器件图片
"", # 电子系统分类
"", # 电子系统名称
"", # 电子系统型号
"", # 生产单位
"", # 电子系统功能
"", # 电子系统加固措施
"", # 电子系统图片
"", # 材料名称
"", # 材料型号
"", # 材料组分
"", # 材料用途
"", # 材料生产单位
"", # 材料物理结构
"", # 材料使用经历
"", # 辐照试验大纲
"", # 大纲审核专家类别
"", # 辐照试验所依据的标准规范
"", # 试验步骤(过程)描述
"", # 辐照过程是否加电
"", # 直流偏置条件描述
"", # 交流偏置条件描述
"", # 时钟频率
"", # 测试图形
"", # 其他偏置条件
"", # 辐照偏置原理图
"", # 测试方式
"", # 测试原理图
"", # 试验用仪器名称
"", # 试验用仪器型号
"", # 试验用仪器生产厂家
"", # 试验用仪器检定证书
"", # 试验用软件名称
"", # 试验用软件开发单位
"", # 试验用软件版本号
"", # 试验现场照片
"", # 测试人员姓名
"", # 测试人员单位
"", # 测试人员电话
"", # 装置运行人员
"", # 第三方人员
"", # 第三方人员单位
"", # 第三方人员电话
"", # 其他需要说明的事项
"", # 是否采用铅铝屏蔽
"", # 剂量率
"", # 总剂量
"", # 剂量等效材料
"", # 试验对象编号
"", # 测试参数名称
"", # 测试参数单位
"", # 测试参数结果
"", # 是否为加速试验后数据
"", # 是否为退火数据
"", # 退火温度
"", # 退火时间
"", # 原始数据
"", # 数据处理方法
"", # 其他需要说明的事项
]
# 写入 CSV 行
csv_writer.writerow(csv_row)
try:
# 下载文件
file_response = requests.get(file_url)
file_response.raise_for_status()
# 保存文件
file_path = os.path.join(part_number_dir, os.path.basename(file_url))
with open(file_path, 'wb') as file:
file.write(file_response.content)
print(f"NASA2 Download file: {file_path}")
except requests.RequestException as e:
print(f"NASA2 Download file error: {file_url}error: {e}")
# 输出数据
# for row in table.xpath('.//tr')[1:]:
# columns = row.xpath('.//td')
# print([col.text_content().strip() for col in columns]) # 打印每一行的数据