风玫瑰数据爬虫及图片生成

爬虫代码

import requests
import xlwings as xw

url_template = "https://hz.hjhj-e.com/api/windRose/findBySearch?areaId={areaId}&timeRange=2&year=2024"
#头
headers = {
    "Accept": "application/json, text/plain, */*",
    "Accept-Encoding": "gzip, deflate, br, zstd",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
    "Auth": "bf6eb886-9cce-46e8-9f95-37039133583a",
    "Connection": "keep-alive",
    "Referer": "https://hz.hjhj-e.com/home/meteorologicalData/windRose/",
    "Sec-Fetch-Dest": "empty",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Site": "same-origin",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0",
    "key": "3213c59c4ab693019b7b477fd764d0ab173215557139559",
    "sec-ch-ua": '"Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": '"Windows"'
}
#cookies数据
cookies = {}
excel_path = "F:/work/QRA/2024风频数据.xlsx"  
app = xw.App(visible=False)
wb = xw.Book(excel_path)
sheet = wb.sheets[0]

row = 1
for _ in range(3208):  
    area_id = int(sheet[f"B{row}"].value)
    if not area_id: 
        break
    url = url_template.format(areaId=area_id)
    response = requests.get(url, headers=headers, cookies=cookies)
    try:
        if response.status_code == 200:
            print(f"请求成功!AreaID: {area_id},目前为第{row}个数据")
            data = response.json()
            d16 = data['data']['data'][0]['d16']

            column_sums = [sum(row[i] for row in d16) for i in range(16)]
            total_sum = sum(column_sums)
            if total_sum == 0:
                print(f'{area_id}为空')
            else:
                percentages = [round(value / total_sum, 4) for value in column_sums]
                for col, percentage in enumerate(percentages, start=4): 
                    sheet[row - 1, col].value = percentage

        else:
            print(f"请求失败,状态码: {response.status_code},AreaID: {area_id}")
    except KeyError as e:
        print({e})
    row += 1  
wb.save()
wb.close()
app.quit()

爬取的数据

生成风玫瑰

import xlwings as xw
import matplotlib.pyplot as plt
import numpy as np
import os

EXCEL_FILE_PATH = "2023风频数据.xlsx"

def load_excel_data():
    try:
        app = xw.App(visible=False)
        wb = app.books.open(EXCEL_FILE_PATH)
        sheet = wb.sheets[0]
        data = sheet.range("C1:C3203").value
        wb.close()
        app.quit()
        return [str(item) for item in data if item]  
    except Exception as e:
        raise RuntimeError(f"加载 Excel 数据失败:{e}")

def find_row_in_excel(column, value):
    try:
        app = xw.App(visible=False)
        wb = app.books.open(EXCEL_FILE_PATH)
        sheet = wb.sheets[0]
        if column == "B":
            data_range = sheet.range("B1:B3203").value
            data_range = [int(cell) if cell is not None else None for cell in data_range]
        elif column == "C":
            data_range = sheet.range("C1:C3203").value
        else:
            raise ValueError("无效的列名")
        for i, cell_value in enumerate(data_range):
            if str(cell_value) == str(value):
                row = sheet.range(f"A{i+1}:Z{i+1}").value
                if column == "B":
                    graph_title = sheet.range(f"C{i+1}").value
                    wb.close()
                    app.quit()
                    return row, graph_title
                else:
                    graph_title = None
                    wb.close()  
                    app.quit()  
                    return row, graph_title
        wb.close()  
        app.quit()  
        return None, None
    except Exception as e:
        raise RuntimeError(f"查找失败:{e}")

def generate_wind_rose(wind_frequencies, title="16-Way Wind Rose"):

    try:
        # 定义 16 个风向标签和对应的角度
        wind_directions_labels = [
            "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE",
            "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"
        ]
        wind_directions_rad = np.deg2rad(np.linspace(0, 360, 17)[:-1])

        # 创建极坐标图
        fig, ax = plt.subplots(figsize=(6, 6), subplot_kw={'projection': 'polar'})

        # 绘制柱状图
        ax.bar(
            wind_directions_rad, wind_frequencies,
            width=np.deg2rad(360 / 16),  # 每个柱状宽度为 360° / 16
            edgecolor='black', alpha=0.7, color='skyblue'
        )

        ax.set_theta_zero_location("N")  
        ax.set_theta_direction(-1)  
        ax.set_xticks(wind_directions_rad)  
        ax.set_xticklabels(wind_directions_labels, fontsize=10, weight="bold") 

        ax.tick_params(axis='x', pad=15)  
        ax.tick_params(axis='y', labelsize=8) 

        ax.set_title(title, va='bottom', fontsize=14)
        fig.tight_layout(pad=3)  

        output_dir = "wind_rose_images"
        os.makedirs(output_dir, exist_ok=True)  
        output_path = os.path.join(output_dir, "wind_rose.png")
        plt.savefig(output_path, dpi=100, bbox_inches='tight')
        plt.close(fig)
        return output_path
    except Exception as e:
        raise RuntimeError(f"风玫瑰图生成失败:{e}")

留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注