Contents

Historical Typhoon Data Download for Taiwan

The cover image is a downloaded typhoon satellite image. It is a satellite water vapor cloud image produced by the Central Weather Administration (CWA) using CCU/SSL. The image was captured at 07:10 on July 11, 2026, and was obtained from the Weather Image Archive of the Department of Atmospheric Sciences at Chinese Culture University (Atmospheric Science Research and Application Databank).

This is a small program that was originally written to download typhoon satellite images and related data. Its initial purpose was to collect image data for image recognition research. Since the program was developed at an earlier stage, it still contains several relatively immature implementation approaches. Therefore, this article serves only as a record and reference for the data download process, and does not provide an in-depth discussion of the program architecture or optimization methods. The programming language used in this project is Python.

Tip
This project was developed in September 2024.

Data Sources

Before downloading the data, it is necessary to clearly define the data sources and download objectives. The goal of this project is to collect satellite images covering the Taiwan region and classify the images into two categories, “with typhoon” and “without typhoon,” based on whether a typhoon affected the region. This classification facilitates subsequent model training by allowing the model to distinguish between different data categories.

Based on these requirements, the Atmospheric Science Research and Application Databank was selected as the primary source for satellite images, while the Typhoon Database was used to obtain typhoon-related information.

Atmospheric Science Research and Application Databank

The Atmospheric Science Research and Application Databank (ASRAD) is currently maintained by the Department of Atmospheric Sciences at Chinese Culture University. It provides a wide range of atmospheric observation and satellite-related datasets. According to its website, the development history of this database is described as follows.

In 1987, the National Science Council established the “Subtropical Data Center” at the Department of Atmospheric Sciences, National Taiwan University, initiating the collection and service of atmospheric research data. Since 2011, the operation was taken over by the National Applied Research Laboratories’ National Science and Technology Center for Disaster Reduction, and the database was expanded into the “Atmospheric and Hydrological Research Database.” In 2018, the database was transferred to the Department of Atmospheric Sciences at Chinese Culture University. In 2022, it was merged with the “Space Science Research Database” and renamed the “Atmospheric Science Research and Application Databank.” In September 2023, it was officially incorporated into the core facilities of the National Science and Technology Council. In addition to expanding its services and research fields, the database integrates multiple atmospheric observation experiments, continuously preserving and providing atmospheric research data to support atmospheric science research and applications both domestically and internationally.

This database provides various types of meteorological and remote sensing data, including satellite cloud images, water vapor cloud images, visible and infrared satellite imagery, radar reflectivity images, surface meteorological observations, radiosonde data, numerical weather analysis charts, and typhoon-related products. It is suitable for applications such as weather analysis, typhoon research, climate studies, image recognition, and atmospheric science education. For researchers who need to construct meteorological image datasets or perform long-term time-series analysis, it serves as a convenient and comprehensive data source.

https://Josh-test-lab.github.io/posts/Historical%20Typhoon%20Data%20Download%20for%20Taiwan/ASRAD.png
Atmospheric Science Research and Application Databank - Data Catalog https://asrad.pccu.edu.tw/catalog/.

Typhoon Database

The Typhoon Database is established and maintained by the Central Weather Administration (CWA). It integrates historical observation and analysis data related to typhoons in the western North Pacific and provides researchers, government agencies, and the general public with access to historical typhoon records and related meteorological information. According to its website, the database is described as follows.

The Typhoon Database collects the names and identification numbers of typhoons that have occurred in the western North Pacific over the years. During periods when typhoon warnings are issued by the Central Weather Administration, various meteorological datasets are collected and presented in textual or graphical formats. These include typhoon warning summaries, typhoon track maps, warning bulletins, satellite imagery, radar images, daily accumulated rainfall maps, regional rainfall maps, skew-T diagrams, comprehensive typhoon rainfall information, synoptic weather charts, hourly variations of meteorological elements at observation stations, bar charts of maximum mean wind and maximum gusts, bar charts of total rainfall, bar charts of consecutive 24-hour accumulated rainfall, and surface weather analysis charts. Registered research users can further access advanced datasets, including typhoon track data, meteorological station observations, dropsonde data, and reanalysis products such as hourly typhoon track maps, wind field distributions at different stages, and pressure field distributions at different stages.

This database provides comprehensive records of typhoon events. In this project, the basic typhoon information and warning issuance periods are mainly used to determine whether satellite images were affected by typhoons. In addition, typhoon intensity information is used for subsequent image classification, dividing the dataset into four categories: “Super Typhoon,” “Moderate Typhoon,” “Mild Typhoon,” and “No Typhoon.”

https://Josh-test-lab.github.io/posts/Historical%20Typhoon%20Data%20Download%20for%20Taiwan/TD.png
Typhoon Database - Typhoon Warning List https://rdc28.cwa.gov.tw/TDB/public/warning_typhoon_list/.

Data Download

In this project, Python was used to develop the data downloading program. The requests package was utilized to send HTTP requests to the website and retrieve satellite images and typhoon-related data. Compared with manually downloading files one by one, programmatic downloading significantly improves efficiency and facilitates large-scale data collection and automated processing in subsequent steps.

Satellite Cloud Images

Since ASRAD stores satellite images according to a fixed directory structure and file-naming convention, the corresponding URL can be generated based on the date and time information to retrieve satellite images at a specific time. In this project, the “Water Vapor Color Satellite Image” covering the Taiwan region was selected as the data source. After downloading, the images were saved using their original filenames.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
### import module
import os
import requests
import raise_error_type

### function
# from ASRAD get Taiwan's water vapor color satellite image
# the result is an .jpg image 
def get_taiwan_water_vapor_color_satellite_image(year: str = '2024', month: str = '09', day: str = '05', hour: str = '00', minute: str = '00'):
    filename = year + month + day + '_' + hour + minute + '.PCCU.WVP.jpg'
    url = f'https://asrad.pccu.edu.tw/catalog/pccu/{year}/{month}/{day}/{filename}'
    response = requests.get(url)

    save_dir = 'water_vapor_color_satellite_image'
    if not os.path.exists(save_dir):
        os.mkdir(save_dir)
    if response.status_code == 200:
        file_path = f'{save_dir}\\{filename}'
        with open(file = file_path, mode = 'wb') as jpg_file:
            jpg_file.write(response.content)
        print(f'Successful download \"{file_path}\".')
    else:
        raise raise_error_type.ResponseError(f'request failed with status code {response.status_code}')

Typhoon Data

The Typhoon Database website provides an API for retrieving the typhoon list data. Since the website returns data in JSON format, the downloaded content can be directly converted into Python objects, making it convenient for subsequent analysis and processing.

Two functions were implemented in this project. The first function, get_taiwan_warning_typhon_data(), is used to retrieve the list of historical typhoons that resulted in the issuance of marine or land typhoon warnings in the Taiwan region. The second function, get_northwest_pacific_typhon_data(), retrieves all typhoon records in the western North Pacific region.

Both functions obtain data from the Central Weather Administration through HTTP POST requests. The returned JSON data are then parsed and provided for further processing within the program.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
### import module
import requests
import json
import raise_error_type

### function
# from CWA get Taiwan's warning typhoon list
# the result is a json 
def get_taiwan_warning_typhon_data():
    url = 'https://rdc28.cwa.gov.tw/TDB/public/warning_typhoon_list/get_warning_typhoon'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Mobile Safari/537.36',
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'X-Requested-With': 'XMLHttpRequest'
    }
    response = requests.post(url, headers = headers, data = {'year': 'all'})

    if response.status_code == 200:
        decoded_content = response.content.decode('utf-8-sig') # decode by 'utf-8-sig'
        data = json.loads(decoded_content)
        return(data)
    else:
        raise raise_error_type.ResponseError(f'request failed with status code {response.status_code}')

# from CWA get northwest Pacific's typhoon list
# the result is a json 
def get_northwest_pacific_typhon_data():
    url = 'https://rdc28.cwa.gov.tw/TDB/public/typhoon_list/get_typhoon'
    headers = {
        'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Mobile Safari/537.36',
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'X-Requested-With': 'XMLHttpRequest'
    }
    response = requests.post(url, headers = headers, data = {'year': 'all'})

    if response.status_code == 200:
        decoded_content = response.content.decode('utf-8-sig') # decode by 'utf-8-sig'
        data = json.loads(decoded_content)
        return(data)
    else:
        raise raise_error_type.ResponseError(f'request failed with status code {response.status_code}')

Download and Classification

After implementing the two data downloading functions described above, the program can proceed with batch data downloading and classification.

The function get_newest_taiwan_warning_typhon() first checks whether the typhoon warning data downloaded on the current day already exists locally. If the data are available, they are loaded directly; otherwise, the function calls the aforementioned API to retrieve the latest data and saves them as a CSV file. This approach reduces unnecessary repeated downloads and avoids wasting computational time and network resources.

The function download_satellite_image() is responsible for batch downloading satellite images. It first creates a one-minute interval time series from the specified start date to the current time, and then sequentially calls the satellite image downloading function to retrieve images for each timestamp. Since corresponding satellite images are not available for every time point, an exception handling mechanism is implemented to skip unavailable images and ensure that the entire downloading process can continue without interruption.

Finally, the program reads all successfully downloaded satellite images one by one and compares the acquisition time extracted from each filename with the periods of typhoon warnings. If an image timestamp falls within a typhoon warning period, the image is moved to the corresponding folder based on the maximum intensity of that typhoon: “Super Typhoon,” “Moderate Typhoon,” or “Mild Typhoon.” If the image does not correspond to any typhoon warning period, it is classified into the “No Typhoon” category.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
### import module
import os
import datetime
import pandas as pd
import raise_error_type
from tqdm import tqdm
import shutil # move file

### function
def get_newest_taiwan_warning_typhon(): # it will return a csv file path
    filename = 'warning_typhon_list_' + f'{datetime.datetime.now().strftime("%Y-%m-%d")}' + '.csv'
    #filename = f'{datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S")}' + '.csv'

    # check whether the newest warning typhoon list exists
    if os.path.exists(filename):
        print(f'The newest Taiwan\'s warning typhoon list has exist at \"{filename}\".')
        return filename
    else:
        print(f'Did not find the newest Taiwan\'s warning typhoon list, using crawler method and downloading.')
        # download data form CWA by using crawler method
        warning_typhon = get_taiwan_warning_typhon_data() # it is a json file
        warning_typhon = pd.DataFrame(warning_typhon)

        # save the list to file
        warning_typhon.to_csv(filename, index = False, encoding = 'utf-8')
        print(f'The newest Taiwan\'s warning typhoon list has save at \"{filename}\".')
        return filename

def download_satellite_image():
    # generate date range
    start_date = '2026-07-09'
    end_date = datetime.datetime.today()
    date_range = pd.date_range(start = start_date, end = end_date, freq = 'min')

    # download image
    for date in date_range:
        year = str(date.year)
        month = format(date.month)
        day = format(date.day)
        hour = format(date.hour)
        minute = format(date.minute)
        try:
            get_taiwan_water_vapor_color_satellite_image(
                year = year,
                month = month,
                day = day,
                hour = hour,
                minute = minute
            )
        except raise_error_type.ResponseError as error:
            print(f'Skipped as raise_error_type.ResponseError:{error}')

def format(i):
    return str(i) if i > 9 else str(f'0{i}')

### main program
## warning tyhoon list
path = get_newest_taiwan_warning_typhon()
warning_typhoon = pd.read_csv(path, encoding='utf-8')
warning_typhoon.dropna(subset = ['max_intensity', 'sea_start_datetime', 'sea_end_datetime'], inplace = True)

## satellite image download
download_satellite_image()

# make classify folders
for dir in ['Super Typhoon', 'Moderate Typhoon', 'Mild Typhoon', 'No Typhoon']:
    if not os.path.exists(dir):
        os.makedirs(dir)

# define a mapping of intensity to folder names
intensity_folders = {
    's': 'Super Typhoon',
    'm': 'Moderate Typhoon',
    'w': 'Mild Typhoon'
}

# classify images
for img in tqdm(os.listdir('water_vapor_color_satellite_image')): # classify from each image
    img_path = os.path.join('water_vapor_color_satellite_image', img)
    if os.path.isfile(img_path): # check if it is a file
        img_time = datetime.datetime.strptime(img[0:13], '%Y%m%d_%H%M') # change str to time
        for row in warning_typhoon.itertuples():
            sea_start = datetime.datetime.strptime(row.sea_start_datetime, '%Y-%m-%d %H:%M:%S')
            sea_end = datetime.datetime.strptime(row.sea_end_datetime, '%Y-%m-%d %H:%M:%S')
            intensity = row.max_intensity
            if sea_start <= img_time <= sea_end:
                # determine the folder based on intensity
                folder_name = intensity_folders.get(intensity)
                new_img_path = os.path.join(folder_name, img)
                shutil.move(img_path, new_img_path) # move the image to the new folder
                break
            else:
                new_img_path = os.path.join('No Typhoon', img)
                shutil.move(img_path, new_img_path)
                break

print('Successful download and classify all images.')
input('Press any key to continue...')

Conclusion

Although this program was originally developed as an automated tool for image downloading and data collection during the early stage of image recognition research, there are still several aspects of the program structure and error handling that can be further improved. Potential improvements include implementing a more robust download retry mechanism, data caching, parallel downloading, and more precise determination of the affected areas of typhoons. Nevertheless, this workflow provides an efficient approach for constructing labeled meteorological image datasets, which can serve as a foundation for subsequent image classification, deep learning model training, and other atmospheric science applications.

Meteorological data typically exhibit strong temporal and spatial continuity. By effectively combining automated data collection techniques with artificial intelligence methods, more valuable information can be extracted from large-scale historical observational datasets. This article mainly documents the procedures for data acquisition and organization, and aims to provide a simple reference for researchers who are conducting meteorological image analysis or related studies.

References

Warning
The last update time of this article is July 17, 2026, and the content may be outdated. Please be aware. If you notice any errors or broken images, feel free to leave a comment for corrections.