Метод: 4 джерела → одна база → Power Query

Парсер котирувань і фундаменталу по тікеру — як я це складаю

Чотири джерела з вашого завдання поводяться по-різному: одне віддає дані готовим масивом, друге — звичайним HTML, третє має 15–30 окремих сторінок на тікер, четверте ховає таблицю за скриптом. Тому «написати парсер» — це насправді чотири різні збирачі й одна спільна база. Нижче — як я їх розділяю, що робить кожен і в якому вигляді це доходить до вашого Excel.

1. Чим саме відрізняються ваші чотири джерела

ДжерелоЩо забираємоЯк віддається насправдіРизик блокування
Yahoo Finance
history по тікеру
дата, open, high, low, close, adj close, volume за діапазон Сторінка малює таблицю скриптом. Стабільніше брати не HTML, а той самий запит даних, який робить сама сторінка — відповідь приходить готовим масивом рядків, без розбору вёрстки. Діапазон дат — це два параметри часу в запиті, тобто period1/period2 у вашому ж прикладі. середній тримає, поки темп людський
Finviz
картка тікера
Sector, Industry, Country Звичайний HTML, три поля в шапці. Найлегше джерело з чотирьох, але найчутливіше до частоти: саме воно першим починає віддавати порожнечу замість даних. високий при частих запитах
GuruFocus
term-сторінки
значення з H1 + блок Annual Data + блок Quarterly Data 15–30 окремих сторінок на один тікер (zscore, roe, ebitda-margin, fcf-per-share, eps-without-nri, eps-diluted…). Структура однакова, тому один розбірник на всі — але це ×30 запитів на кожен тікер, і саме тут вирішується, живий парсер чи забанений. високий через кількість сторінок
MarketWatch
holdings фонду
блок Top 10 holdings 3–5 сторінок на тікер фонду. Таблиця тримається на своїй розмітці, змінюється рідше за решту. середній
Практичний висновок з таблиці: вузьке місце проєкту — не код розбору, а темп. Один тікер по третьому джерелу — це до 30 запитів. Сто тікерів — три тисячі. Тому планувальник у мене керує не «раз на добу запустити все», а чергою завдань, де кожен рядок знає, коли його востаннє оновлювали.

2. «Симулятор поведінки людини» — що це насправді

Ви написали це вимогою, і це правильна вимога. Розкладаю її на те, що реально працює, бо під цією назвою часто продають одну випадкову паузу:

Темп і ритм

Схожість на браузер

Поведінка при опорі

Чесно про межу: жодна імітація не дає вічної гарантії. Якщо джерело поставить капчу або закриє доступ, чесна відповідь — не «обійдемо», а «ось з якою швидкістю воно віддає дані спокійно» і «ось що робимо, коли перестало». Це закладено в конструкцію, а не дописується потім.

3. База даних: чотири джерела — чотири таблиці, один довідник

Головна помилка на таких проєктах — скласти все в одну широку таблицю. Через місяць у неї не можна ні дописати нову метрику, ні перерахувати історію. Розкладаю так:

tickers            id, ticker, sector, industry, country, updated_at
                   -- довідник; sector/industry/country з джерела 2

quotes_daily       ticker, date, open, high, low, close, adj_close, volume
                   -- джерело 1; ключ (ticker, date) -> повторний запуск не дублює

fundamentals       ticker, term, period_type, period_end, value, unit, fetched_at
                   -- джерело 3; period_type = annual | quarterly
                   -- term = zscore | roe | ebitda-margin | ...
                   -- ключ (ticker, term, period_type, period_end)

fund_holdings      fund_ticker, rank, holding_name, weight_pct, fetched_at
                   -- джерело 4, Top 10 holdings

fetch_log          source, ticker, url, http_status, rows, started_at, finished_at, note
                   -- звідки видно, що саме не забралося і чому
Чому саме так: fundamentals у «довгому» вигляді (одна метрика — один рядок) означає, що нову метрику з GuruFocus додають без зміни структури таблиці — просто з’являється новий term. Широка таблиця на 30 колонок вимагала б переробки бази щоразу.

4. Як це підключається до Excel через Power Query

Power Query добре працює з MySQL/PostgreSQL на вашому хостингу, але є два місця, де такі підключення зазвичай ламаються, і їх краще закрити одразу:

  1. Окремий користувач бази тільки на читання. Excel підключається логіном, який фізично не може нічого змінити. Це не формальність: файл ходить по людях.
  2. Excel читає не таблиці, а представлення (view). Ви тягнете v_quotes, v_fundamentals_wide, v_holdings — і коли всередині бази щось зміниться, ваш файл не розсиплеться: представлення лишається тим самим.

Одне з представлень зручно віддати одразу «широким», щоб у Excel не робити півот руками:

v_fundamentals_wide:
  ticker | period_end | roe | ebitda_margin | zscore | fcf_per_share | eps_diluted
  AAPL   | 2025-09-30 | ... | ...           | ...    | ...           | ...

Доступ до бази ззовні відкривається не «всім», а з вашої IP-адреси або через SSH-тунель — з боку Excel це виглядає так само просто, а база не стоїть відкритою в інтернет.

5. Налаштування, які ви назвали — де вони живуть

НалаштуванняДе змінюється
Список тікерівтаблиця tickers — додали рядок, наступний прохід його підхопив
Діапазон дат (джерело 1)конфіг: «глибина історії» при першому завантаженні + «докачувати з останньої дати» далі
Періодичність оновленняокремо по кожному джерелу: котирування — щодня після закриття, фундаментал — раз на тиждень, holdings — раз на тиждень
Темп / поведінкаконфіг: пауза-від, пауза-до, розмір пачки, пауза між пачками, ліміт спроб
Набір term-сторінокдовідник у базі — додати метрику можна без правки коду

6. Перевірка якості — щоб у базу не потрапляло сміття

7. Чого я не обіцяю

Не обіцяю, що парсер працюватиме роками без дотику. Він тримається на чужій розмітці й чужих правилах доступу: сайт змінить сторінку — розбірник треба поправити. Обіцяю інше: щоб така поломка була видимою (лог і зупинка джерела, а не тихі нулі в базі), а правка — дешевою (окремий розбірник на джерело, а не один моноліт).

Так само не обіцяю нескінченну швидкість: чим агресивніший темп, тим швидше прилетить блокування. Правильна відповідь — не «швидше», а «рівно і без зупинок».

Це опис методу, а не готовий висновок про ваш проєкт: конкретні значення пауз, глибина історії та список term-сторінок узгоджуються з вами перед стартом. Для запуску потрібні доступ до хостингу (база + можливість тримати фоновий процес за розкладом) і ваш список тікерів.