Created
June 3, 2026 09:05
-
-
Save sunmeat/9ebc72323c408650e6756106e6e2409d to your computer and use it in GitHub Desktop.
парсинг HTML з використанням регулярок на С++ (версія для мак ос)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <string> | |
| #include <regex> | |
| #include <vector> | |
| #include <cstdio> | |
| #include <cstdlib> | |
| using namespace std; | |
| // https://wttr.in/odesa | |
| string read_file(const string& path) { | |
| FILE* file = fopen(path.c_str(), "rb"); | |
| if (!file) return ""; | |
| fseek(file, 0, SEEK_END); | |
| long file_size = ftell(file); | |
| fseek(file, 0, SEEK_SET); | |
| if (file_size <= 0) { | |
| fclose(file); | |
| return ""; | |
| } | |
| string content(file_size, '\0'); | |
| fread(&content[0], 1, file_size, file); | |
| fclose(file); | |
| return content; | |
| } | |
| // завантажує URL у файл через curl (замість URLDownloadToFileA на Windows) | |
| bool download_file(const string& url, const string& out_path) { | |
| string cmd = "curl -s -o \"" + out_path + "\" \"" + url + "\""; | |
| return system(cmd.c_str()) == 0; | |
| } | |
| string extract(const string& text, const string& pattern) { | |
| smatch m; | |
| if (regex_search(text, m, regex(pattern))) | |
| return m[1].str(); | |
| return ""; | |
| } | |
| string decode_entities(const string& s) { | |
| string r = regex_replace(s, regex("/"), "/"); | |
| r = regex_replace(r, regex(" "), " "); | |
| r = regex_replace(r, regex("""), "\""); | |
| r = regex_replace(r, regex("&"), "&"); | |
| r = regex_replace(r, regex("<"), "<"); | |
| r = regex_replace(r, regex(">"), ">"); | |
| return r; | |
| } | |
| string translate_desc(const string& desc) { | |
| vector<pair<string, string>> translations = { | |
| {"Sunny", "Сонячно"}, | |
| {"Clear", "Ясно"}, | |
| {"Clear sky", "Ясно"}, | |
| {"Mainly clear", "Переважно ясно"}, | |
| {"Partly cloudy", "Мінлива хмарність"}, | |
| {"Mostly cloudy", "Переважно хмарно"}, | |
| {"Cloudy", "Хмарно"}, | |
| {"Overcast", "Суцільна хмарність"}, | |
| {"Patchy rain nearby", "Місцями дощ"}, | |
| {"Patchy rain possible", "Можливий місцями дощ"}, | |
| {"Rain", "Дощ"}, | |
| {"Light rain", "Невеликий дощ"}, | |
| {"Moderate rain", "Помірний дощ"}, | |
| {"Heavy rain", "Сильний дощ"}, | |
| {"Light drizzle", "Слабка мряка"}, | |
| {"Drizzle", "Мряка"}, | |
| {"Freezing drizzle", "Крижана мряка"}, | |
| {"Freezing rain", "Крижаний дощ"}, | |
| {"Sleet", "Мокрий сніг"}, | |
| {"Light snow", "Невеликий сніг"}, | |
| {"Moderate snow", "Помірний сніг"}, | |
| {"Heavy snow", "Сильний сніг"}, | |
| {"Blizzard", "Завірюха"}, | |
| {"Blowing snow", "Заметіль"}, | |
| {"Snow shower", "Снігопад"}, | |
| {"Light snow showers", "Невеликі снігопади"}, | |
| {"Snow", "Сніг"}, | |
| {"Thunder", "Гроза"}, | |
| {"Thunderstorm", "Гроза"}, | |
| {"Thundery outbreaks", "Можливі грози"}, | |
| {"Fog", "Туман"}, | |
| {"Mist", "Імла"}, | |
| {"Haze", "Димка"}, | |
| {"Ice pellets", "Крупа"}, | |
| {"Windy", "Вітряно"}, | |
| {"Strong winds", "Сильний вітер"}, | |
| {"Storm", "Шторм"}, | |
| {"Tropical storm", "Тропічний шторм"}, | |
| // Російськомовні варіанти | |
| {"Солнечно", "Сонячно"}, | |
| {"Ясно", "Ясно"}, | |
| {"Малооблачно", "Мінлива хмарність"}, | |
| {"Переменная облачность", "Мінлива хмарність"}, | |
| {"Облачно", "Хмарно"}, | |
| {"Пасмурно", "Суцільна хмарність"}, | |
| {"Дождь", "Дощ"}, | |
| {"Небольшой дождь", "Невеликий дощ"}, | |
| {"Слабый дождь", "Невеликий дощ"}, | |
| {"Умеренный дождь", "Помірний дощ"}, | |
| {"Сильный дождь", "Сильний дощ"}, | |
| {"Ливень", "Злива"}, | |
| {"Морось", "Мряка"}, | |
| {"Снег", "Сніг"}, | |
| {"Небольшой снег", "Невеликий сніг"}, | |
| {"Снегопад", "Снігопад"}, | |
| {"Метель", "Завірюха"}, | |
| {"Сильная метель", "Сильна завірюха"}, | |
| {"Гроза", "Гроза"}, | |
| {"Туман", "Туман"}, | |
| {"Сильный туман", "Густий туман"}, | |
| {"Дымка", "Димка"}, | |
| {"Крупа", "Крупа"}, | |
| {"Град", "Град"}, | |
| {"Ветрено", "Вітряно"}, | |
| {"Шторм", "Шторм"} | |
| }; | |
| for (const auto& p : translations) { | |
| if (desc.find(p.first) != string::npos) | |
| return p.second; | |
| } | |
| return desc; | |
| } | |
| void show_weather(const string& city, const string& city_label) { | |
| string url = "https://wttr.in/" + city; | |
| string file = "/tmp/wttr_" + city + ".html"; // на macOS пишемо у /tmp замість поточної папки | |
| if (!download_file(url, file)) { | |
| cerr << "Помилка завантаження для: " << city_label << "\n"; | |
| return; | |
| } | |
| string html = read_file(file); | |
| if (html.empty()) { | |
| cerr << "Не вдалося прочитати файл для: " << city_label << "\n"; | |
| return; | |
| } | |
| string block = extract(html, "<div class=\"term-container\">([\\s\\S]*?)</div>"); | |
| if (block.empty()) { | |
| cerr << "Дані не знайдено для: " << city_label << "\n"; | |
| return; | |
| } | |
| block = decode_entities(block); | |
| string desc_raw = extract(block, "> ([A-Z][a-z A-Z]+)\\n"); | |
| string temp_main = extract(block, "<span[^>]*>([+-]?\\d+)</span>\\("); | |
| string temp_feel = extract(block, "\\(<span[^>]*>([+-]?\\d+)</span>\\)"); | |
| string wind_speed = extract(block, "term-fg1\">[^<]+</span>\\s*<span[^>]*>(\\d+)</span>"); | |
| string description = translate_desc(desc_raw); | |
| string sign_main = (!temp_main.empty() && temp_main[0] != '-' && temp_main[0] != '+') ? "+" : ""; | |
| string sign_feel = (!temp_feel.empty() && temp_feel[0] != '-' && temp_feel[0] != '+') ? "+" : ""; | |
| cout << "+------------------------------------------+\n"; | |
| cout << "| " << city_label << "\n"; | |
| cout << "+------------------------------------------+\n"; | |
| cout << " Стан: " << description << "\n"; | |
| cout << " Температура: " << sign_main << temp_main << " C" | |
| << " (відчувається " << sign_feel << temp_feel << " C)\n"; | |
| cout << " Вітер: " << wind_speed << " км/год\n\n"; | |
| } | |
| int main() { | |
| cout << "=== Погода в Україні ===\n\n"; | |
| cout << "Завантажуємо дані...\n\n"; | |
| vector<pair<string, string>> cities = { | |
| { "odesa", "Одеса" }, | |
| { "kharkiv", "Харків" }, | |
| { "zhytomyr", "Житомир" }, | |
| // додайте інші міста за бажанням | |
| }; | |
| for (const auto& c : cities) | |
| show_weather(c.first, c.second); | |
| cout << "Введіть назву свого міста (бажано латиницею):\n"; | |
| string user_city; | |
| getline(cin, user_city); | |
| if (!user_city.empty()) | |
| show_weather(user_city, user_city); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment