PARTAGE prévisions nombres d'heures de soleil sur 7 jours Script Python3

Bonjour,

Depuis le 24/06 le script ne semble plus fonctionner pour le vent, ok pour les heures d’ensolleiment

Je suis le seul ou d’autres on constaté le souci ?

Hello,

p’tet qu’il n’y a pas vent par chez toi :face_with_hand_over_mouth:
image

chez moi je récupère bien l’info …
Je trouve que ce script à mon niveau est l’une des plus belles trouvailles
Si simple et si efficace ; merci encore à son auteur

Bonjour,
A priori le site meteoblue a changé son design et certaines infos n’arrivaient plus chez moi en Debian 12 et Core 4.5.2.
J’ai modifié avec l’aide de l’iA si comme moi vous utilisez encore je peux partager le code en espérant ne pas froisser l’auteur :hand_with_index_finger_and_thumb_crossed:
Bien cordialement

Bonsoir,

Vas y go aucun risque et il serait content que tu le fasse.

1 « J'aime »

Bonjour,
Voici donc le code d’Olive réactualisé pour qu’il fonctionne chez moi, n’étant pas dev il reste sûrement des ajustements que chacun pourra faire mais la base est là.

J’en profite pour rappeler que pour installer la librairie depuis debian 12 c’est :
sudo apt install python3-bs4
Ce n’est pas de moi et déjà donné dans un autre message mais ça vous évitera de tout relire.

#! /usr/bin/env python3
import requests
from sys import argv
from bs4 import BeautifulSoup

res = requests.get(argv[1])
soupe = BeautifulSoup(res.content, "html.parser")

# séparation horizontale entre colonnes
print("<table style='border-collapse:separate; border-spacing:6px 0;'>", end='')

# -------------------- JOURS --------------------
jours = soupe.find_all('time', class_='date')[:7]

print("<tr>", end='')
print("<td style='color:blue; text-align:right; font-weight:bold;'>Jours :</td>", end='')

for j in jours:
    short_day = j.find('div', class_='tab-day-short').text.strip()
    long_day = j.find('div', class_='tab-day-long').text.strip()

    print(
        "<td style='color:red; font-weight:bold; text-align:center;'>"
        f"{short_day}<br>"
        f"<span style='font-weight:normal; font-size:0.9em;'>{long_day}</span>"
        "</td>",
        end=''
    )
print("</tr>", end='')

# -------------------- DONNÉES --------------------
jours_data = soupe.find_all('div', class_='tab-content')[:7]

vent, direction, tmax, tmin, pluie, soleil = [], [], [], [], [], []

for day in jours_data:
    # Vent + direction
    vent_div = day.find('div', class_='wind')
    if vent_div:
        vitesse = vent_div.get_text(strip=True)
        span = vent_div.find('span')
        dir_val = span.get('class', [])[-1] if span and len(span.get('class', [])) > 1 else 'N/A'
    else:
        vitesse, dir_val = 'N/A', 'N/A'

    vent.append(vitesse)
    direction.append(dir_val)

    # Températures
    tmax.append(day.find('div', class_='tab-temp-max').text.strip())
    tmin.append(day.find('div', class_='tab-temp-min').text.strip())

    # Pluie (texte normal, l'espacement est géré par le tableau)
    pluie.append(day.find('div', class_='tab-precip').text.strip())

    # Soleil
    soleil.append(day.find('div', class_='tab-sun').text.strip())

# -------------------- AFFICHAGE --------------------
def print_row(label, values):
    print("<tr>", end='')
    print(f"<td style='color:blue; text-align:right; font-weight:bold;'>{label} :</td>", end='')
    for v in values:
        print(f"<td style='color:red; text-align:center;'>{v}</td>", end='')
    print("</tr>", end='')

print_row("Vent", vent)
print_row("Direction", direction)
print_row("Tmax", tmax)
print_row("Tmin", tmin)
print_row("Pluie", pluie)
print_row("Soleil", soleil)

print("</table>", end='')

Voici le rendu à l’écran :


Bien cordialement

2 « J'aime »

Hello
super
merci pour ton code

je me suis empressé de le balancer à chatgpt et on l’a revu ensemble
j’étais dans la peau d’un dev :lying_face:

image

2 « J'aime »

Bonjour,
Il faut partager alors :smiley:

1 « J'aime »

Hello
oui ça serait sympa de partager

@rennais35000 @nonohugo
hello
désolé , comme c’est l’autre AI qui a fait le taf , et que je lui ai juste dit :
j’aimerais des flèches ds le sens du vent , j’aimerais des couleurs , j’aimerais un tableau et en plus elle est toujours force de propositions que je me suis dit que mon code n’intéresserait personne
Je pense que je vais encore travailler dur en mettant des couleurs en fonction de la pluie :joy:
image

alors je partage …

#! /usr/bin/env python3
import requests
from sys import argv
from bs4 import BeautifulSoup
import re

# ==================== RÉCUPÉRATION PAGE ====================
res = requests.get(argv[1])
soupe = BeautifulSoup(res.content, "html.parser")

# ==================== TABLE ====================
print("<table style='border-collapse:separate; border-spacing:4px 2px; "
      "background-color:transparent; border-radius:8px; overflow:hidden; "
      "font-family:sans-serif; font-size:14px;'>", end='')

# -------------------- JOURS --------------------
jours = soupe.find_all('time', class_='date')[:7]

print("<tr>", end='')
print("<td style='text-align:left; font-weight:bold; background-color:transparent; padding:6px;'>Jours :</td>", end='')

for j in jours:
    short_day = j.find('div', class_='tab-day-short').text.strip()
    long_day = j.find('div', class_='tab-day-long').text.strip()

    print(
        f"<td style='font-weight:bold; text-align:center; background-color:transparent; padding:6px;'>"
        f"{short_day}<br>"
        f"<span style='font-weight:normal; font-size:0.8em;'>{long_day}</span>"
        "</td>",
        end=''
    )
print("</tr>", end='')

# -------------------- DONNÉES --------------------
jours_data = soupe.find_all('div', class_='tab-content')[:7]

vent, direction, tmax, tmin, pluie, soleil = [], [], [], [], [], []

for day in jours_data:
    # Vent + direction
    vent_div = day.find('div', class_='wind')
    if vent_div:
        vitesse = vent_div.get_text(strip=True).replace("km/h","").strip()
        span = vent_div.find('span')
        dir_val = span.get('class', [])[-1] if span and len(span.get('class', [])) > 1 else 'N'
    else:
        vitesse, dir_val = '0', 'N'

    vent.append(vitesse)
    direction.append(dir_val)

    # Températures
    tmax.append(day.find('div', class_='tab-temp-max').text.strip())
    tmin.append(day.find('div', class_='tab-temp-min').text.strip())

    # Pluie
    pluie.append(day.find('div', class_='tab-precip').text.strip())

    # Soleil
    soleil.append(day.find('div', class_='tab-sun').text.strip())

# ==================== COULEURS ====================
COLORS = {
    "Tmax": "#FF4C4C",
    "Tmin": "#4C9EFF",
    "Pluie": "#AA00FF",
    "Soleil": "#FFAA33"
}

ICONS = {
    "Vent": "💨",
    "Direction": "🧭",
    "Tmax": "⬆️",
    "Tmin": "⬇️",
    "Pluie": "🌧️",
    "Soleil": "☀️"
}

# ==================== UTILITAIRES ====================
def wind_arrow(dir_val):
    """Flèche dans le sens du vent + lettre"""
    mapping = {"n":0,"ne":45,"e":90,"se":135,"s":180,"sw":225,"w":270,"nw":315}
    key = dir_val.lower()
    angle = (mapping.get(key,0)+180)%360
    return f"<span style='display:inline-block; transform:rotate({angle}deg); font-size:1.3em;'>↑</span> {dir_val.upper()}"

def vent_color(speed):
    """Couleur selon vitesse maximale si plusieurs valeurs"""
    try:
        numbers = [float(n) for n in re.findall(r'\d+\.?\d*', speed)]
        s = max(numbers) if numbers else 0
    except:
        s = 0
    if s < 30:
        return "green"
    elif s <= 50:
        return "orange"
    else:
        return "red"

# ==================== AFFICHAGE ====================
def print_row(label, values, row_index):
    bg = "rgba(255,255,255,0.05)" if row_index % 2 == 1 else "transparent"
    size = "1.1em" if label in ["Tmax","Tmin"] else "1em"

    print("<tr>", end='')

    print(
        f"<td style='background-color:{bg}; text-align:left; font-weight:bold; font-size:{size}; "
        f"padding:6px; border-radius:4px 0 0 4px;'>{ICONS.get(label,'')} {label} :</td>",
        end=''
    )

    for i, v in enumerate(values):
        if label == "Vent":
            display_val = v
            color = vent_color(v)
        elif label == "Direction":
            display_val = wind_arrow(direction[i])
            color = vent_color(vent[i])
        else:
            display_val = v
            color = COLORS.get(label,"white")

        print(
            f"<td style='background-color:{bg}; color:{color}; text-align:center; font-weight:bold; "
            f"padding:6px; font-size:{size}; border-radius:0 4px 4px 0;'>{display_val}</td>",
            end=''
        )

    print("</tr>", end='')

# -------------------- APPEL DES LIGNES --------------------
rows = [("Vent", vent), ("Direction", direction), ("Tmax", tmax),
        ("Tmin", tmin), ("Pluie", pluie), ("Soleil", soleil)]

for idx, (label, values) in enumerate(rows):
    print_row(label, values, idx)

print("</table>", end='')

#! /usr/bin/env python3
import requests
from sys import argv
from bs4 import BeautifulSoup
import re

# ==================== RÉCUPÉRATION PAGE ====================
res = requests.get(argv[1])
soupe = BeautifulSoup(res.content, "html.parser")

# ==================== TABLE ====================
print("<table style='border-collapse:separate; border-spacing:4px 2px; "
      "font-family:sans-serif; font-size:14px;'>", end='')

# -------------------- JOURS --------------------
jours = soupe.find_all('time', class_='date')[:7]

print("<tr>", end='')
print("<td style='font-weight:bold; padding:6px;'>Jours :</td>", end='')

for j in jours:
    short_day = j.find('div', class_='tab-day-short').text.strip()
    long_day = j.find('div', class_='tab-day-long').text.strip()

    print(
        f"<td style='font-weight:bold; text-align:center; padding:6px;'>"
        f"{short_day}<br>"
        f"<span style='font-size:0.8em; opacity:.7;'>{long_day}</span>"
        "</td>",
        end=''
    )
print("</tr>", end='')

# -------------------- DONNÉES --------------------
jours_data = soupe.find_all('div', class_='tab-content')[:7]

vent, direction, tmax, tmin, pluie, soleil = [], [], [], [], [], []

for day in jours_data:
    vent_div = day.find('div', class_='wind')
    if vent_div:
        vitesse = vent_div.get_text(strip=True).replace("km/h", "").strip()
        span = vent_div.find('span')
        dir_val = span.get('class', [])[-1] if span and len(span.get('class', [])) > 1 else 'N'
    else:
        vitesse, dir_val = '0', 'N'

    vent.append(vitesse)
    direction.append(dir_val)

    tmax.append(day.find('div', class_='tab-temp-max').text.strip())
    tmin.append(day.find('div', class_='tab-temp-min').text.strip())
    pluie.append(day.find('div', class_='tab-precip').text.strip())
    soleil.append(day.find('div', class_='tab-sun').text.strip())

# ==================== COULEURS & ICONES ====================
COLORS = {
    "Tmax": "#FF6B5A",
    "Tmin": "#6FA8FF"
}

ICONS = {
    "Vent": "💨",
    "Direction": "🧭",
    "Tmax": "⬆️",
    "Tmin": "⬇️",
    "Pluie": "🌧️",
    "Soleil": "☀️"
}

# ==================== UTILITAIRES ====================
def wind_arrow(dir_val):
    mapping = {"n":0,"ne":45,"e":90,"se":135,"s":180,"sw":225,"w":270,"nw":315}
    angle = (mapping.get(dir_val.lower(), 0) + 180) % 360
    return (
        f"<span style='display:inline-block; transform:rotate({angle}deg); font-size:1.4em;'>↑</span> "
        f"<span style='font-size:.75em; opacity:.7;'>{dir_val.upper()}</span>"
    )

def vent_color(speed):
    nums = [float(n) for n in re.findall(r'\d+\.?\d*', speed)]
    s = max(nums) if nums else 0
    if s < 30:
        return "#3CFF3C"
    elif s <= 50:
        return "#FFA500"
    else:
        return "#FF4040"

def format_vent(value):
    nums = re.findall(r'\d+\.?\d*', value)
    if len(nums) >= 2:
        return f"{nums[0]} <span style='opacity:.7;'>↯{nums[-1]}</span>"
    return value

def pluie_bg(value):
    nums = [float(n) for n in re.findall(r'\d+\.?\d*', value)]
    p = max(nums) if nums else 0
    if p == 0:
        return "#3B003B"
    elif p <= 2:
        return "#FFD700"
    elif p <= 5:
        return "#FF8C00"
    else:
        return "#FF0000"

def soleil_bar(value, max_h=10):
    nums = re.findall(r'\d+', value)
    h = int(nums[0]) if nums else 0
    ratio = min(h / max_h, 1)
    width = int(ratio * 100)

    return (
        f"<div style='background:#333; border-radius:4px; height:10px; width:80%; margin:auto;'>"
        f"<div style='background:#FFD700; height:100%; width:{width}%; border-radius:4px;'></div>"
        f"</div>"
        f"<div style='font-size:.85em; margin-top:2px;'>{h} h</div>"
    )

# ==================== AFFICHAGE ====================
def print_row(label, values, row_index):
    bg = "rgba(255,255,255,0.04)" if row_index % 2 else "transparent"
    size = "1.1em" if label in ["Tmax","Tmin"] else "1em"

    print("<tr>", end='')
    print(
        f"<td style='background-color:{bg}; font-weight:bold; padding:6px;'>{ICONS.get(label,'')} {label} :</td>",
        end=''
    )

    for i, v in enumerate(values):
        cell_bg = bg
        text_color = "white"

        if label == "Vent":
            display = format_vent(v)
            text_color = vent_color(v)
        elif label == "Direction":
            display = wind_arrow(direction[i])
            text_color = vent_color(vent[i])
        elif label == "Pluie":
            display = v
            cell_bg = pluie_bg(v)
            text_color = "black"
        elif label == "Soleil":
            display = soleil_bar(v)
        else:
            display = v
            text_color = COLORS.get(label, "white")

        print(
            f"<td style='background-color:{cell_bg}; color:{text_color}; "
            f"text-align:center; font-weight:bold; padding:6px; font-size:{size};'>"
            f"{display}</td>",
            end=''
        )

    print("</tr>", end='')

# -------------------- APPEL DES LIGNES --------------------
rows = [
    ("Vent", vent),
    ("Direction", direction),
    ("Tmax", tmax),
    ("Tmin", tmin),
    ("Pluie", pluie),
    ("Soleil", soleil)
]

for idx, (label, values) in enumerate(rows):
    print_row(label, values, idx)

print("</table>", end='')

image

comment on va être bouffé dans 5 , 10 , 15 ans ?

2 « J'aime »

Bonjour et merci pour le partage, Petite remarque : La flêche « Est » n’est pas top chez moi.

Hello,
T’inquiète , je vais aller voir qui de droit et lui dire qu’elle nous a fait un boulot de débutant …

Hello,
Tant qu’à faire, j’ai passé les heures de soleil en orange car en thème light on voit rien et j’ai mis le vert plus foncé pour la même raison.
if s < 30:
return « #00bc00 »
Pour sa flèche est, je pense que ça vient aussi du navigateur car chez moi c’est correct.

1 « J'aime »

voici sa modif …

#! /usr/bin/env python3
import requests
from sys import argv
from bs4 import BeautifulSoup
import re

# ==================== RÉCUPÉRATION PAGE ====================
res = requests.get(argv[1])
soupe = BeautifulSoup(res.content, "html.parser")

# ==================== TABLE ====================
print("<table style='border-collapse:separate; border-spacing:4px 2px; "
      "font-family:sans-serif; font-size:14px;'>", end='')

# -------------------- JOURS --------------------
jours = soupe.find_all('time', class_='date')[:7]

print("<tr>", end='')
print("<td style='font-weight:bold; padding:6px; min-width:70px;'>Jours :</td>", end='')

for j in jours:
    short_day = j.find('div', class_='tab-day-short').text.strip()
    long_day = j.find('div', class_='tab-day-long').text.strip()

    print(
        f"<td style='font-weight:bold; text-align:center; padding:6px; min-width:70px;'>"
        f"{short_day}<br>"
        f"<span style='font-size:0.8em; opacity:.7;'>{long_day}</span>"
        "</td>",
        end=''
    )
print("</tr>", end='')

# -------------------- DONNÉES --------------------
jours_data = soupe.find_all('div', class_='tab-content')[:7]

vent, direction, tmax, tmin, pluie, soleil = [], [], [], [], [], []

for day in jours_data:
    vent_div = day.find('div', class_='wind')
    if vent_div:
        vitesse = vent_div.get_text(strip=True).replace("km/h", "").strip()
        span = vent_div.find('span')
        dir_val = span.get('class', [])[-1] if span and len(span.get('class', [])) > 1 else 'N'
    else:
        vitesse, dir_val = '0', 'N'

    vent.append(vitesse)
    direction.append(dir_val)

    tmax.append(day.find('div', class_='tab-temp-max').text.strip())
    tmin.append(day.find('div', class_='tab-temp-min').text.strip())
    pluie.append(day.find('div', class_='tab-precip').text.strip())
    soleil.append(day.find('div', class_='tab-sun').text.strip())

# ==================== COULEURS & ICONES ====================
COLORS = {
    "Tmax": "#FF6B5A",
    "Tmin": "#6FA8FF"
}

ICONS = {
    "Vent": "💨",
    "Direction": "🧭",
    "Tmax": "⬆️",
    "Tmin": "⬇️",
    "Pluie": "🌧️",
    "Soleil": "☀️"
}

# ==================== UTILITAIRES ====================
def wind_arrow(dir_val):
    mapping = {"n":0,"ne":45,"e":90,"se":135,"s":180,"sw":225,"w":270,"nw":315}
    angle = (mapping.get(dir_val.lower(), 0) + 180) % 360

    return (
        f"<span style='display:inline-block; transform:rotate({angle}deg); font-size:1.4em;'>↑</span>"
        f"<span style='margin-left:5px; font-size:.75em; opacity:.7;'>{dir_val.upper()}</span>"
    )

def vent_color(speed):
    nums = [float(n) for n in re.findall(r'\d+\.?\d*', speed)]
    s = max(nums) if nums else 0
    if s < 30:
        return "#3CFF3C"
    elif s <= 50:
        return "#FFA500"
    else:
        return "#FF4040"

def format_vent(value):
    nums = re.findall(r'\d+\.?\d*', value)
    if len(nums) >= 2:
        return f"{nums[0]} <span style='opacity:.7;'>↯{nums[-1]}</span>"
    return value

def pluie_bg(value):
    nums = [float(n) for n in re.findall(r'\d+\.?\d*', value)]
    p = max(nums) if nums else 0
    if p == 0:
        return "#3B003B"
    elif p <= 2:
        return "#FFD700"
    elif p <= 5:
        return "#FF8C00"
    else:
        return "#FF0000"

def soleil_bar(value, max_h=10):
    nums = re.findall(r'\d+', value)
    h = int(nums[0]) if nums else 0
    ratio = min(h / max_h, 1)
    width = int(ratio * 100)

    return (
        f"<div style='background:#333; border-radius:4px; height:10px; width:100%; margin:0 auto;'>"
        f"<div style='background:#FFD700; height:100%; width:{width}%; border-radius:4px;'></div>"
        f"</div>"
        f"<div style='font-size:.85em; margin-top:2px; text-align:center;'>{h} h</div>"
    )

# ==================== AFFICHAGE ====================
def print_row(label, values, row_index):
    bg = "rgba(255,255,255,0.04)" if row_index % 2 else "transparent"
    size = "1.1em" if label in ["Tmax", "Tmin"] else "1em"

    print("<tr>", end='')
    print(
        f"<td style='background-color:{bg}; font-weight:bold; padding:6px; min-width:70px;'>"
        f"{ICONS.get(label,'')} {label} :</td>",
        end=''
    )

    for i, v in enumerate(values):
        cell_bg = bg
        text_color = "white"

        if label == "Vent":
            display = format_vent(v)
            text_color = vent_color(v)
        elif label == "Direction":
            display = wind_arrow(direction[i])
            text_color = vent_color(vent[i])
        elif label == "Pluie":
            display = re.sub(r"(mm)", r"<span style='font-size:0.88em;'>\1</span>", v)
            cell_bg = pluie_bg(v)
            text_color = "black"
        elif label == "Soleil":
            display = soleil_bar(v)
        else:
            display = v
            text_color = COLORS.get(label, "white")

        print(
            f"<td style='background-color:{cell_bg}; color:{text_color}; text-align:center; "
            f"font-weight:bold; padding:6px; font-size:{size}; min-width:70px;'>"
            f"{display}</td>",
            end=''
        )

    print("</tr>", end='')

# -------------------- APPEL DES LIGNES --------------------
rows = [
    ("Vent", vent),
    ("Direction", direction),
    ("Tmax", tmax),
    ("Tmin", tmin),
    ("Pluie", pluie),
    ("Soleil", soleil)
]

for idx, (label, values) in enumerate(rows):
    print_row(label, values, idx)

print("</table>", end='')

son commentaire : (ligne 78)

:dart: Ce que ça fait

  • margin-left:5px → espace clair et constant
  • Aucun chevauchement, même pour E
  • Pas de flex, pas de structure lourde
  • S’intègre parfaitement à ton tableau existant

:bulb: Tu peux ajuster :

  • 4px → plus serré
  • 6–8px → plus aéré
1 « J'aime »

8 messages ont été scindés en un nouveau sujet : PARTAGE prévisions nombres d’heures de soleil sur 7 jours en PHP