Remove utility and notebook files from repository
This commit is contained in:
-745
@@ -1,745 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "b8a14d71",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"=== Scraping page 1/137: https://www.mql5.com/en/code/mt5/indicators\n",
|
||||
"-- 40 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56228\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Price Time Scale - indicator for MetaTrader 5\n",
|
||||
"[↓] pricetimescale.mq5 ← https://www.mql5.com/en/code/download/56228/pricetimescale.mq5\n",
|
||||
"[✔] Téléchargé: pricetimescale.mq5\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56281\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Candle size - indicator for MetaTrader 5\n",
|
||||
"[↓] candle_size.mq5 ← https://www.mql5.com/en/code/download/56281/candle_size.mq5\n",
|
||||
"[✔] Téléchargé: candle_size.mq5\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56382\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'MACD coloured histogram'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\MACD coloured histogram\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56432\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Candle Counter - indicator for MetaTrader 5\n",
|
||||
"[↓] candle_counter.mq5 ← https://www.mql5.com/en/code/download/56432/candle_counter.mq5\n",
|
||||
"[✔] Téléchargé: candle_counter.mq5\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/60537\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Moving Average based on Heiken-Ashi'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Moving Average based on Heiken-Ashi\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/60369\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Supertrend by KivancOzbilgic'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Supertrend by KivancOzbilgic\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56820\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Divergence Awesome Ocilator'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Divergence Awesome Ocilator\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56909\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Daily Trend'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Daily Trend\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/60194\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'ATR Channels Indicator'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\ATR Channels Indicator\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/54459\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'AlphaTrend'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\AlphaTrend\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56972\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'False Breakups'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\False Breakups\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/60054\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Baseline: iMA + ATR Bands'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Baseline_ iMA + ATR Bands\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/60023\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Show Positions on Custom Chart (or standard chart) for MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Show Positions on Custom Chart (or standard chart) for MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57174\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Divergence DeMarker'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Divergence DeMarker\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/58896\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Change the colour of candles and wick'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Change the colour of candles and wick\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/58845\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Customised bmap chart'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Customised bmap chart\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/59733\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Engulfing Pattern Indicator with Volume Confirmation'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Engulfing Pattern Indicator with Volume Confirmation\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/59792\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Trendline zigzag in qualitative channel'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Trendline zigzag in qualitative channel\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/59744\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Equity and Balance Indicator - History based'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Equity and Balance Indicator - History based\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/58516\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Candle Filter'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Candle Filter\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/58104\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'RSI Divergence'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\RSI Divergence\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/58229\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'EquiPeak Drawdown Tracker'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\EquiPeak Drawdown Tracker\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/59477\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'DailyHighLow Indicator for MQL5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\DailyHighLow Indicator for MQL5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/59368\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Swaps Monitor for a Single Symbol'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Swaps Monitor for a Single Symbol\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/59342\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'ADX Indicator (MQL5)'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\ADX Indicator (MQL5)\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/59268\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Custom MACD: Elevate Your Trading with Real-Time Signal Alerts to Your Phone'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Custom MACD_ Elevate Your Trading with Real-Time Signal Alerts to Your Phone\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/59227\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'BBMA - Bollinger Band Moving Average'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\BBMA - Bollinger Band Moving Average\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/59204\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Range BreakOut Indicator - Indicator Buffer Only'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Range BreakOut Indicator - Indicator Buffer Only\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/59157\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Multi-Day Dynamic VWAP'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Multi-Day Dynamic VWAP\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/58838\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Brooky Trend Strength for MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Brooky Trend Strength for MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/58789\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'SignalAI - Indicator'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\SignalAI - Indicator\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/58636\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Custom MA Cross with RSI Indicator for MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Custom MA Cross with RSI Indicator for MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/58650\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'CTJM Candle Timer'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\CTJM Candle Timer\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/58562\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Volume MA with candle color tracking'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Volume MA with candle color tracking\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57731\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Countdown 2.0'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Countdown 2.0\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57644\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'MACD Divergence'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\MACD Divergence\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57620\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Spreads'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Spreads\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57320\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'AveragePrice'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\AveragePrice\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56678\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Better volume'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Better volume\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/49558\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Volatility Stop'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Volatility Stop\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"=== Scraping page 2/137: https://www.mql5.com/en/code/mt5/indicators/page2\n",
|
||||
"-- 40 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/49404\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'SMI Ergodic Oscillator'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\SMI Ergodic Oscillator\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/49334\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Net Volume'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Net Volume\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/49265\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Know Sure Thing'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Know Sure Thing\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/49182\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Correlation Coefficient'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Correlation Coefficient\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/49029\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Chaikin Money Flow'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Chaikin Money Flow\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/58257\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'ColorXMA_Ishimoku_StDev - indicator for MetaTrader 5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\ColorXMA_Ishimoku_StDev - indicator for MetaTrader 5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/49459\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Volume Oscillator'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Volume Oscillator\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/58231\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'EquiPeak Drawdown Tracker'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\EquiPeak Drawdown Tracker\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/54894\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Kuskus Starlight'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Kuskus Starlight\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/49175\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Chande Kroll Stop'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Chande Kroll Stop\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/49132\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'PriceChanges'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\PriceChanges\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/48962\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Second Bars'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Second Bars\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57975\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Uniformity Factor Indicator'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Uniformity Factor Indicator\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/49985\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Angle and Speed'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Angle and Speed\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/25229\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Pan PrizMA No leverage 72'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Pan PrizMA No leverage 72\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57724\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'PSAR Zigzag (Non lagging)'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\PSAR Zigzag (Non lagging)\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57684\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Ranging Market Detector'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Ranging Market Detector\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57597\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Breakout Finder by LonesomeTheBlue'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Breakout Finder by LonesomeTheBlue\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57377\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'FVG based Momentum Detection'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\FVG based Momentum Detection\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57302\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Trend Zigzag (on ma cross)'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Trend Zigzag (on ma cross)\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57063\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Supertrend'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Supertrend\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/57038\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'BarDuration'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\BarDuration\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56927\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'T3 Moving Average'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\T3 Moving Average\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56869\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Daily Vertical Lines'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Daily Vertical Lines\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56619\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Fibonacci ZigZag'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Fibonacci ZigZag\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56616\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Autoscaling Zigzag'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Autoscaling Zigzag\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56559\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Time To Close v1.01 - MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Time To Close v1.01 - MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/56289\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Self Optimized SMA'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Self Optimized SMA\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/55923\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Intrabar Volume Flow'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Intrabar Volume Flow\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/55521\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Trade Assistant MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Trade Assistant MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/55622\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Portable Moving Average'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Portable Moving Average\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/55519\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Total Power Indicator MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Total Power Indicator MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/55517\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'TD Sequential Ultimate MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\TD Sequential Ultimate MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/55371\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Coppock MT5 indicator'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Coppock MT5 indicator\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/55515\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Support and Resistance MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Support and Resistance MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/55513\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Spread indicator MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Spread indicator MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/55511\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Schaff Trend Cycle MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Schaff Trend Cycle MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/55509\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'RSIOMA MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\RSIOMA MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/55507\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Round Levels MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Round Levels MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"→ Indicateur: https://www.mql5.com/en/code/55504\n",
|
||||
" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: 'Recent High/Low Alert MT5'\n",
|
||||
" ▶ Dossier: mql5_indicators_mt5\\Recent High_Low Alert MT5\n",
|
||||
" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\n",
|
||||
" ▶ 0 images détectées\n",
|
||||
"\n",
|
||||
"=== Scraping page 3/137: https://www.mql5.com/en/code/mt5/indicators/page3\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 4/137: https://www.mql5.com/en/code/mt5/indicators/page4\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 5/137: https://www.mql5.com/en/code/mt5/indicators/page5\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 6/137: https://www.mql5.com/en/code/mt5/indicators/page6\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 7/137: https://www.mql5.com/en/code/mt5/indicators/page7\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 8/137: https://www.mql5.com/en/code/mt5/indicators/page8\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 9/137: https://www.mql5.com/en/code/mt5/indicators/page9\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 10/137: https://www.mql5.com/en/code/mt5/indicators/page10\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 11/137: https://www.mql5.com/en/code/mt5/indicators/page11\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 12/137: https://www.mql5.com/en/code/mt5/indicators/page12\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 13/137: https://www.mql5.com/en/code/mt5/indicators/page13\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 14/137: https://www.mql5.com/en/code/mt5/indicators/page14\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 15/137: https://www.mql5.com/en/code/mt5/indicators/page15\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 16/137: https://www.mql5.com/en/code/mt5/indicators/page16\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 17/137: https://www.mql5.com/en/code/mt5/indicators/page17\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 18/137: https://www.mql5.com/en/code/mt5/indicators/page18\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 19/137: https://www.mql5.com/en/code/mt5/indicators/page19\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 20/137: https://www.mql5.com/en/code/mt5/indicators/page20\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 21/137: https://www.mql5.com/en/code/mt5/indicators/page21\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 22/137: https://www.mql5.com/en/code/mt5/indicators/page22\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 23/137: https://www.mql5.com/en/code/mt5/indicators/page23\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 24/137: https://www.mql5.com/en/code/mt5/indicators/page24\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 25/137: https://www.mql5.com/en/code/mt5/indicators/page25\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 26/137: https://www.mql5.com/en/code/mt5/indicators/page26\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 27/137: https://www.mql5.com/en/code/mt5/indicators/page27\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 28/137: https://www.mql5.com/en/code/mt5/indicators/page28\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 29/137: https://www.mql5.com/en/code/mt5/indicators/page29\n",
|
||||
"-- 0 indicateurs trouvés\n",
|
||||
"\n",
|
||||
"=== Scraping page 30/137: https://www.mql5.com/en/code/mt5/indicators/page30\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ename": "KeyboardInterrupt",
|
||||
"evalue": "",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
|
||||
"Cell \u001b[1;32mIn[5], line 55\u001b[0m\n\u001b[0;32m 53\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m=== Scraping page \u001b[39m\u001b[38;5;132;01m{\u001b[39;00midx\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m/\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mPAGES_TO_SCRAPE\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mpage_url\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 54\u001b[0m driver\u001b[38;5;241m.\u001b[39mget(page_url)\n\u001b[1;32m---> 55\u001b[0m \u001b[43mtime\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msleep\u001b[49m\u001b[43m(\u001b[49m\u001b[43mPAGE_DELAY\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 57\u001b[0m soup \u001b[38;5;241m=\u001b[39m BeautifulSoup(driver\u001b[38;5;241m.\u001b[39mpage_source, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhtml.parser\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 58\u001b[0m tiles \u001b[38;5;241m=\u001b[39m soup\u001b[38;5;241m.\u001b[39mselect(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m.codebase-list__content .code-tile .title > a\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
|
||||
"\u001b[1;31mKeyboardInterrupt\u001b[0m: "
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import time\n",
|
||||
"import re\n",
|
||||
"import requests\n",
|
||||
"from urllib.parse import urljoin, urlparse\n",
|
||||
"from bs4 import BeautifulSoup\n",
|
||||
"from selenium import webdriver\n",
|
||||
"from selenium.webdriver.chrome.options import Options\n",
|
||||
"from selenium.webdriver.chrome.service import Service\n",
|
||||
"\n",
|
||||
"# === CONFIGURATION ===\n",
|
||||
"BASE_URL = \"https://www.mql5.com\"\n",
|
||||
"START_URL = f\"{BASE_URL}/en/code/mt5/indicators\"\n",
|
||||
"# Il y a 137 pages d'indicateurs\n",
|
||||
"PAGES_TO_SCRAPE = 137\n",
|
||||
"DOWNLOAD_ROOT = \"mql5_indicators_mt5\"\n",
|
||||
"PAGE_DELAY = 2 # secondes d’attente après chargement de chaque page\n",
|
||||
"REQ_TIMEOUT = 30 # timeout pour requests.get\n",
|
||||
"\n",
|
||||
"# === UTILITAIRES ===\n",
|
||||
"def safe_mkdir(path):\n",
|
||||
" if not os.path.isdir(path):\n",
|
||||
" os.makedirs(path, exist_ok=True)\n",
|
||||
"\n",
|
||||
"def download_file(url, dest_folder):\n",
|
||||
" safe_mkdir(dest_folder)\n",
|
||||
" filename = os.path.basename(urlparse(url).path)\n",
|
||||
" dest_path = os.path.join(dest_folder, filename)\n",
|
||||
" print(f\"[↓] {filename} ← {url}\")\n",
|
||||
" try:\n",
|
||||
" r = requests.get(url, stream=True, timeout=REQ_TIMEOUT)\n",
|
||||
" r.raise_for_status()\n",
|
||||
" with open(dest_path, \"wb\") as f:\n",
|
||||
" for chunk in r.iter_content(1024):\n",
|
||||
" f.write(chunk)\n",
|
||||
" print(f\"[✔] Téléchargé: {filename}\")\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"[✘] Erreur download {filename}: {e}\")\n",
|
||||
"\n",
|
||||
"# === SETUP SELENIUM HEADLESS ===\n",
|
||||
"chrome_opts = Options()\n",
|
||||
"chrome_opts.add_argument(\"--headless\")\n",
|
||||
"chrome_opts.add_argument(\"--disable-gpu\")\n",
|
||||
"chrome_opts.add_argument(\"--no-sandbox\")\n",
|
||||
"driver = webdriver.Chrome(service=Service(), options=chrome_opts)\n",
|
||||
"\n",
|
||||
"# === CRÉER LE DOSSIER RACINE ===\n",
|
||||
"safe_mkdir(DOWNLOAD_ROOT)\n",
|
||||
"\n",
|
||||
"# === SCRAPING PAGES ===\n",
|
||||
"for idx in range(1, PAGES_TO_SCRAPE + 1):\n",
|
||||
" page_url = START_URL if idx == 1 else f\"{START_URL}/page{idx}\"\n",
|
||||
" print(f\"\\n=== Scraping page {idx}/{PAGES_TO_SCRAPE}: {page_url}\")\n",
|
||||
" driver.get(page_url)\n",
|
||||
" time.sleep(PAGE_DELAY)\n",
|
||||
"\n",
|
||||
" soup = BeautifulSoup(driver.page_source, \"html.parser\")\n",
|
||||
" tiles = soup.select(\".codebase-list__content .code-tile .title > a\")\n",
|
||||
" print(f\"-- {len(tiles)} indicateurs trouvés\")\n",
|
||||
"\n",
|
||||
" for a in tiles:\n",
|
||||
" href = a.get(\"href\")\n",
|
||||
" list_title = a.text.strip()\n",
|
||||
" indicator_url = urljoin(BASE_URL, href)\n",
|
||||
" print(f\"\\n→ Indicateur: {indicator_url}\")\n",
|
||||
" driver.get(indicator_url)\n",
|
||||
" time.sleep(PAGE_DELAY)\n",
|
||||
" esoup = BeautifulSoup(driver.page_source, \"html.parser\")\n",
|
||||
"\n",
|
||||
" # Nom de l’indicateur: priorité au <h1>, sinon titre depuis la liste\n",
|
||||
" h1 = esoup.select_one(\"h1\")\n",
|
||||
" if h1 and h1.text.strip():\n",
|
||||
" name_raw = h1.text.strip()\n",
|
||||
" else:\n",
|
||||
" name_raw = list_title or href.split('/')[-1]\n",
|
||||
" print(f\" [ℹ] Pas de <h1> trouvé, utilisation du titre listé: '{name_raw}'\")\n",
|
||||
" name = re.sub(r\"[\\\\/:*?\\\"<>|]\", \"_\", name_raw)\n",
|
||||
" folder = os.path.join(DOWNLOAD_ROOT, name)\n",
|
||||
" safe_mkdir(folder)\n",
|
||||
" print(f\" ▶ Dossier: {folder}\")\n",
|
||||
"\n",
|
||||
" # Télécharger le code : ZIP ou .mq5/.mq4\n",
|
||||
" zip_link = esoup.find(\"a\", string=re.compile(r\"Download as ZIP\", re.I))\n",
|
||||
" if zip_link and zip_link.get(\"href\"):\n",
|
||||
" download_file(urljoin(BASE_URL, zip_link[\"href\"]), folder)\n",
|
||||
" else:\n",
|
||||
" code_link = esoup.find(\"a\", href=re.compile(r\"\\.mq[45]$\"))\n",
|
||||
" if code_link:\n",
|
||||
" download_file(urljoin(BASE_URL, code_link[\"href\"]), folder)\n",
|
||||
" else:\n",
|
||||
" print(\" [!] Aucun code trouvé (.mq5/.mq4 ou ZIP).\")\n",
|
||||
"\n",
|
||||
" # Télécharger les images de présentation\n",
|
||||
" images = esoup.select(\".codebase-detail img\")\n",
|
||||
" print(f\" ▶ {len(images)} images détectées\")\n",
|
||||
" for img in images:\n",
|
||||
" src = img.get(\"src\") or img.get(\"data-src\")\n",
|
||||
" if not src or not re.search(r\"\\.(png|jpe?g|gif)$\", src, re.I):\n",
|
||||
" continue\n",
|
||||
" download_file(urljoin(BASE_URL, src), folder)\n",
|
||||
"\n",
|
||||
"# === FIN ===\n",
|
||||
"driver.quit()\n",
|
||||
"print(\"\\n=== FIN DU SCRAPING INDICATEURS ===\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "96d1eda1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.18"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
import os
|
||||
|
||||
ROOT = "mql5_experts_mt5"
|
||||
|
||||
def is_valid_image(filename):
|
||||
lower = filename.lower()
|
||||
return (
|
||||
lower.endswith((".png", ".jpg", ".jpeg", ".gif"))
|
||||
and not any(x in lower for x in ["avatar", "indicator", "expert", "logo"])
|
||||
)
|
||||
|
||||
def get_mq5_files(files):
|
||||
return [f for f in files if f.lower().endswith('.mq5')]
|
||||
|
||||
def get_images(files):
|
||||
return [f for f in files if is_valid_image(f)]
|
||||
|
||||
def generate_readme(folder, mq5_files, images):
|
||||
title = os.path.basename(folder)
|
||||
lines = [f"# {title}\n", "## Description"]
|
||||
lines.append(
|
||||
"This folder contains a professional trading expert advisor (EA) for MetaTrader 5.\n\n"
|
||||
"Below are example screenshots of the strategy in action. \n"
|
||||
"*Feel free to explore, test, and improve!*\n\n"
|
||||
"*You can add a detailed description of the strategy, parameters, and usage here.*\n\n"
|
||||
"---\n\n"
|
||||
"If you find this project useful, please consider giving it a star, sharing it, or even sending a small donation to support further development. Thank you!\n"
|
||||
)
|
||||
for img in images:
|
||||
lines.append(f"")
|
||||
lines.append("\n## Files")
|
||||
for mq5 in mq5_files:
|
||||
lines.append(f"- `{mq5}`")
|
||||
lines.append("\n## How to use")
|
||||
lines.append("1. Copy the `.mq5` file to your MetaTrader 5 `Experts` folder.")
|
||||
lines.append("2. Compile in MetaEditor.")
|
||||
lines.append("3. Attach the expert to a chart.")
|
||||
lines.append("4. Configure parameters as needed.\n")
|
||||
return "\n".join(lines)
|
||||
|
||||
for subdir in os.listdir(ROOT):
|
||||
folder = os.path.join(ROOT, subdir)
|
||||
if os.path.isdir(folder):
|
||||
files = os.listdir(folder)
|
||||
mq5_files = get_mq5_files(files)
|
||||
images = get_images(files)
|
||||
if mq5_files: # Only process if there is at least one .mq5 file
|
||||
readme_path = os.path.join(folder, "README.md")
|
||||
new_content = generate_readme(folder, mq5_files, images)
|
||||
# Write or overwrite README.md if missing or different
|
||||
if not os.path.exists(readme_path) or open(readme_path, encoding="utf-8").read() != new_content:
|
||||
with open(readme_path, "w", encoding="utf-8") as f:
|
||||
f.write(new_content)
|
||||
print(f"README.md updated in: {folder}")
|
||||
|
||||
print("Vérification et génération terminées pour tous les dossiers !")
|
||||
-477
@@ -1,477 +0,0 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "c3da1338",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"==> Scraping page 1\n",
|
||||
"==> Scraping page 2\n",
|
||||
"==> Scraping page 3\n",
|
||||
"==> Scraping page 4\n",
|
||||
"==> Scraping page 5\n",
|
||||
"==> Scraping page 6\n",
|
||||
"==> Scraping page 7\n",
|
||||
"==> Scraping page 8\n",
|
||||
"==> Scraping page 9\n",
|
||||
"==> Scraping page 10\n",
|
||||
"==> Scraping page 11\n",
|
||||
"==> Scraping page 12\n",
|
||||
"==> Scraping page 13\n",
|
||||
"==> Scraping page 14\n",
|
||||
"==> Scraping page 15\n",
|
||||
"==> Scraping page 16\n",
|
||||
"==> Scraping page 17\n",
|
||||
"==> Scraping page 18\n",
|
||||
"==> Scraping page 19\n",
|
||||
"==> Scraping page 20\n",
|
||||
"==> Scraping page 21\n",
|
||||
"==> Scraping page 22\n",
|
||||
"==> Scraping page 23\n",
|
||||
"==> Scraping page 24\n",
|
||||
"==> Scraping page 25\n",
|
||||
"==> Scraping page 26\n",
|
||||
"==> Scraping page 27\n",
|
||||
"==> Scraping page 28\n",
|
||||
"==> Scraping page 29\n",
|
||||
"==> Scraping page 30\n",
|
||||
"==> Scraping page 31\n",
|
||||
"==> Scraping page 32\n",
|
||||
"==> Scraping page 33\n",
|
||||
"==> Scraping page 34\n",
|
||||
"==> Scraping page 35\n",
|
||||
"==> Scraping page 36\n",
|
||||
"==> Scraping page 37\n",
|
||||
"==> Scraping page 38\n",
|
||||
"==> Scraping page 39\n",
|
||||
"==> Scraping page 40\n",
|
||||
"==> Scraping page 41\n",
|
||||
"==> Scraping page 42\n",
|
||||
"==> Scraping page 43\n",
|
||||
"==> Scraping page 44\n",
|
||||
"==> Scraping page 45\n",
|
||||
"==> Scraping page 46\n",
|
||||
"==> Scraping page 47\n",
|
||||
"==> Scraping page 48\n",
|
||||
"==> Scraping page 49\n",
|
||||
"==> Scraping page 50\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import time\n",
|
||||
"import requests\n",
|
||||
"from urllib.parse import urljoin, urlparse\n",
|
||||
"from bs4 import BeautifulSoup\n",
|
||||
"from selenium import webdriver\n",
|
||||
"from selenium.webdriver.chrome.service import Service\n",
|
||||
"from selenium.webdriver.common.by import By\n",
|
||||
"from selenium.webdriver.chrome.options import Options\n",
|
||||
"\n",
|
||||
"# === CONFIGURATION ===\n",
|
||||
"BASE_URL = \"https://www.mql5.com\"\n",
|
||||
"START_URL = \"https://www.mql5.com/en/code\"\n",
|
||||
"DOWNLOAD_FOLDER = \"mql5_experts\"\n",
|
||||
"PAGES_TO_SCRAPE = 50\n",
|
||||
"DELAY = 2 # seconds\n",
|
||||
"\n",
|
||||
"# === SETUP CHROMEDRIVER ===\n",
|
||||
"chrome_options = Options()\n",
|
||||
"chrome_options.add_argument(\"--headless\")\n",
|
||||
"driver = webdriver.Chrome(service=Service(), options=chrome_options)\n",
|
||||
"\n",
|
||||
"# === FONCTION POUR TÉLÉCHARGER UN FICHIER ===\n",
|
||||
"def download_file(url, folder_path):\n",
|
||||
" filename = os.path.basename(urlparse(url).path)\n",
|
||||
" filepath = os.path.join(folder_path, filename)\n",
|
||||
" try:\n",
|
||||
" r = requests.get(url, stream=True)\n",
|
||||
" if r.status_code == 200:\n",
|
||||
" with open(filepath, 'wb') as f:\n",
|
||||
" for chunk in r.iter_content(1024):\n",
|
||||
" f.write(chunk)\n",
|
||||
" print(f\"[+] Fichier téléchargé : {filename}\")\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"[!] Erreur lors du téléchargement : {url} -> {e}\")\n",
|
||||
"\n",
|
||||
"# === SCRAPER PRINCIPAL ===\n",
|
||||
"os.makedirs(DOWNLOAD_FOLDER, exist_ok=True)\n",
|
||||
"\n",
|
||||
"for page_num in range(PAGES_TO_SCRAPE):\n",
|
||||
" print(f\"==> Scraping page {page_num+1}\")\n",
|
||||
" page_url = f\"{START_URL}/!{page_num}\" if page_num > 0 else START_URL\n",
|
||||
" driver.get(page_url)\n",
|
||||
" time.sleep(DELAY)\n",
|
||||
"\n",
|
||||
" soup = BeautifulSoup(driver.page_source, \"html.parser\")\n",
|
||||
" items = soup.select(\".title > a\")\n",
|
||||
"\n",
|
||||
" for link in items:\n",
|
||||
" href = link.get(\"href\")\n",
|
||||
" expert_url = urljoin(BASE_URL, href)\n",
|
||||
" driver.get(expert_url)\n",
|
||||
" time.sleep(DELAY)\n",
|
||||
" expert_soup = BeautifulSoup(driver.page_source, \"html.parser\")\n",
|
||||
"\n",
|
||||
" # Récupérer le nom de l'expert\n",
|
||||
" title_tag = expert_soup.select_one(\"h1\")\n",
|
||||
" if not title_tag:\n",
|
||||
" continue\n",
|
||||
" expert_name = title_tag.text.strip().replace(\"/\", \"_\").replace(\"\\\\\", \"_\")\n",
|
||||
" expert_folder = os.path.join(DOWNLOAD_FOLDER, expert_name)\n",
|
||||
" os.makedirs(expert_folder, exist_ok=True)\n",
|
||||
" print(f\"[*] Traitement de : {expert_name}\")\n",
|
||||
"\n",
|
||||
" # Télécharger le fichier .mq5 ou .mq4\n",
|
||||
" code_links = expert_soup.select(\"a\")\n",
|
||||
" for a in code_links:\n",
|
||||
" href = a.get(\"href\", \"\")\n",
|
||||
" if href.endswith(\".mq5\") or href.endswith(\".mq4\"):\n",
|
||||
" full_url = urljoin(BASE_URL, href)\n",
|
||||
" download_file(full_url, expert_folder)\n",
|
||||
"\n",
|
||||
" # Télécharger les images\n",
|
||||
" images = expert_soup.select(\"img\")\n",
|
||||
" for img in images:\n",
|
||||
" src = img.get(\"src\")\n",
|
||||
" if src:\n",
|
||||
" img_url = urljoin(BASE_URL, src)\n",
|
||||
" download_file(img_url, expert_folder)\n",
|
||||
"\n",
|
||||
"driver.quit()\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "9d87c98a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"==> Scraping page 1: https://www.mql5.com/en/code\n",
|
||||
"==> Scraping page 2: https://www.mql5.com/en/code/!1\n",
|
||||
"==> Scraping page 3: https://www.mql5.com/en/code/!2\n",
|
||||
"==> Scraping page 4: https://www.mql5.com/en/code/!3\n",
|
||||
"==> Scraping page 5: https://www.mql5.com/en/code/!4\n",
|
||||
"==> Scraping page 6: https://www.mql5.com/en/code/!5\n",
|
||||
"==> Scraping page 7: https://www.mql5.com/en/code/!6\n",
|
||||
"==> Scraping page 8: https://www.mql5.com/en/code/!7\n",
|
||||
"==> Scraping page 9: https://www.mql5.com/en/code/!8\n",
|
||||
"==> Scraping page 10: https://www.mql5.com/en/code/!9\n",
|
||||
"==> Scraping page 11: https://www.mql5.com/en/code/!10\n",
|
||||
"==> Scraping page 12: https://www.mql5.com/en/code/!11\n",
|
||||
"==> Scraping page 13: https://www.mql5.com/en/code/!12\n",
|
||||
"==> Scraping page 14: https://www.mql5.com/en/code/!13\n",
|
||||
"==> Scraping page 15: https://www.mql5.com/en/code/!14\n",
|
||||
"==> Scraping page 16: https://www.mql5.com/en/code/!15\n",
|
||||
"==> Scraping page 17: https://www.mql5.com/en/code/!16\n",
|
||||
"==> Scraping page 18: https://www.mql5.com/en/code/!17\n",
|
||||
"==> Scraping page 19: https://www.mql5.com/en/code/!18\n",
|
||||
"==> Scraping page 20: https://www.mql5.com/en/code/!19\n",
|
||||
"==> Scraping page 21: https://www.mql5.com/en/code/!20\n",
|
||||
"==> Scraping page 22: https://www.mql5.com/en/code/!21\n",
|
||||
"==> Scraping page 23: https://www.mql5.com/en/code/!22\n",
|
||||
"==> Scraping page 24: https://www.mql5.com/en/code/!23\n",
|
||||
"==> Scraping page 25: https://www.mql5.com/en/code/!24\n",
|
||||
"==> Scraping page 26: https://www.mql5.com/en/code/!25\n",
|
||||
"==> Scraping page 27: https://www.mql5.com/en/code/!26\n",
|
||||
"==> Scraping page 28: https://www.mql5.com/en/code/!27\n",
|
||||
"==> Scraping page 29: https://www.mql5.com/en/code/!28\n",
|
||||
"==> Scraping page 30: https://www.mql5.com/en/code/!29\n",
|
||||
"==> Scraping page 31: https://www.mql5.com/en/code/!30\n",
|
||||
"==> Scraping page 32: https://www.mql5.com/en/code/!31\n",
|
||||
"==> Scraping page 33: https://www.mql5.com/en/code/!32\n",
|
||||
"==> Scraping page 34: https://www.mql5.com/en/code/!33\n",
|
||||
"==> Scraping page 35: https://www.mql5.com/en/code/!34\n",
|
||||
"==> Scraping page 36: https://www.mql5.com/en/code/!35\n",
|
||||
"==> Scraping page 37: https://www.mql5.com/en/code/!36\n",
|
||||
"==> Scraping page 38: https://www.mql5.com/en/code/!37\n",
|
||||
"==> Scraping page 39: https://www.mql5.com/en/code/!38\n",
|
||||
"==> Scraping page 40: https://www.mql5.com/en/code/!39\n",
|
||||
"==> Scraping page 41: https://www.mql5.com/en/code/!40\n",
|
||||
"==> Scraping page 42: https://www.mql5.com/en/code/!41\n",
|
||||
"==> Scraping page 43: https://www.mql5.com/en/code/!42\n",
|
||||
"==> Scraping page 44: https://www.mql5.com/en/code/!43\n",
|
||||
"==> Scraping page 45: https://www.mql5.com/en/code/!44\n",
|
||||
"==> Scraping page 46: https://www.mql5.com/en/code/!45\n",
|
||||
"==> Scraping page 47: https://www.mql5.com/en/code/!46\n",
|
||||
"==> Scraping page 48: https://www.mql5.com/en/code/!47\n",
|
||||
"==> Scraping page 49: https://www.mql5.com/en/code/!48\n",
|
||||
"==> Scraping page 50: https://www.mql5.com/en/code/!49\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import time\n",
|
||||
"import requests\n",
|
||||
"from bs4 import BeautifulSoup\n",
|
||||
"from urllib.parse import urljoin, urlparse\n",
|
||||
"from selenium import webdriver\n",
|
||||
"from selenium.webdriver.chrome.options import Options\n",
|
||||
"from selenium.webdriver.chrome.service import Service\n",
|
||||
"from selenium.webdriver.common.by import By\n",
|
||||
"\n",
|
||||
"# === CONFIGURATION ===\n",
|
||||
"BASE_URL = \"https://www.mql5.com\"\n",
|
||||
"START_URL = \"https://www.mql5.com/en/code\"\n",
|
||||
"DOWNLOAD_FOLDER = \"mql5_experts\"\n",
|
||||
"PAGES_TO_SCRAPE = 50\n",
|
||||
"DELAY = 2\n",
|
||||
"\n",
|
||||
"# === CONFIGURATION SELENIUM HEADLESS ===\n",
|
||||
"chrome_options = Options()\n",
|
||||
"chrome_options.add_argument(\"--headless=new\")\n",
|
||||
"chrome_options.add_argument(\"--disable-gpu\")\n",
|
||||
"chrome_options.add_argument(\"--no-sandbox\")\n",
|
||||
"driver = webdriver.Chrome(service=Service(), options=chrome_options)\n",
|
||||
"\n",
|
||||
"# === CRÉER DOSSIER GLOBAL ===\n",
|
||||
"os.makedirs(DOWNLOAD_FOLDER, exist_ok=True)\n",
|
||||
"\n",
|
||||
"# === TÉLÉCHARGER UN FICHIER ===\n",
|
||||
"def download_file(url, folder_path):\n",
|
||||
" try:\n",
|
||||
" filename = os.path.basename(urlparse(url).path)\n",
|
||||
" filepath = os.path.join(folder_path, filename)\n",
|
||||
" r = requests.get(url, stream=True)\n",
|
||||
" if r.status_code == 200:\n",
|
||||
" with open(filepath, 'wb') as f:\n",
|
||||
" for chunk in r.iter_content(1024):\n",
|
||||
" f.write(chunk)\n",
|
||||
" print(f\"[+] Téléchargé : {filename}\")\n",
|
||||
" else:\n",
|
||||
" print(f\"[!] Erreur {r.status_code} pour {url}\")\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"[!] Exception sur téléchargement : {url} -> {e}\")\n",
|
||||
"\n",
|
||||
"# === SCRAPER PRINCIPAL ===\n",
|
||||
"for page_num in range(PAGES_TO_SCRAPE):\n",
|
||||
" page_url = f\"{START_URL}/!{page_num}\" if page_num > 0 else START_URL\n",
|
||||
" print(f\"==> Scraping page {page_num+1}: {page_url}\")\n",
|
||||
" driver.get(page_url)\n",
|
||||
" time.sleep(DELAY)\n",
|
||||
"\n",
|
||||
" soup = BeautifulSoup(driver.page_source, \"html.parser\")\n",
|
||||
" links = soup.select(\"div.title a\")\n",
|
||||
"\n",
|
||||
" for link in links:\n",
|
||||
" try:\n",
|
||||
" href = link.get(\"href\")\n",
|
||||
" expert_url = urljoin(BASE_URL, href)\n",
|
||||
" driver.get(expert_url)\n",
|
||||
" time.sleep(DELAY)\n",
|
||||
"\n",
|
||||
" expert_soup = BeautifulSoup(driver.page_source, \"html.parser\")\n",
|
||||
"\n",
|
||||
" # === NOM DE L'EXPERT ===\n",
|
||||
" title_tag = expert_soup.select_one(\"h1\")\n",
|
||||
" if not title_tag:\n",
|
||||
" continue\n",
|
||||
" expert_name = title_tag.text.strip().replace(\"/\", \"_\").replace(\"\\\\\", \"_\")\n",
|
||||
" expert_folder = os.path.join(DOWNLOAD_FOLDER, expert_name)\n",
|
||||
" os.makedirs(expert_folder, exist_ok=True)\n",
|
||||
" print(f\"[*] Traitement de : {expert_name}\")\n",
|
||||
"\n",
|
||||
" # === LIEN DE TÉLÉCHARGEMENT ZIP OU MQ5 ===\n",
|
||||
" download_link = expert_soup.find(\"a\", string=lambda s: s and \"Download as ZIP\" in s)\n",
|
||||
" if not download_link:\n",
|
||||
" download_link = expert_soup.find(\"a\", href=lambda href: href and (href.endswith(\".mq5\") or href.endswith(\".mq4\")))\n",
|
||||
" if download_link:\n",
|
||||
" file_url = urljoin(BASE_URL, download_link[\"href\"])\n",
|
||||
" download_file(file_url, expert_folder)\n",
|
||||
" else:\n",
|
||||
" print(f\"[!] Aucun fichier à télécharger pour {expert_name}\")\n",
|
||||
"\n",
|
||||
" # === TÉLÉCHARGER IMAGES PRÉSENTATION ===\n",
|
||||
" images = expert_soup.select(\"img\")\n",
|
||||
" for img in images:\n",
|
||||
" src = img.get(\"src\")\n",
|
||||
" if src and any(ext in src for ext in ['.png', '.jpg', '.jpeg']):\n",
|
||||
" img_url = urljoin(BASE_URL, src)\n",
|
||||
" download_file(img_url, expert_folder)\n",
|
||||
"\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"[!] Erreur sur expert : {link.get('href')} -> {e}\")\n",
|
||||
"\n",
|
||||
"driver.quit()\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "71beeefd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "67a5e405",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7978c290",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "raw",
|
||||
"id": "9d3732a9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import re\n",
|
||||
"import time\n",
|
||||
"import requests\n",
|
||||
"from urllib.parse import urljoin, urlparse\n",
|
||||
"from bs4 import BeautifulSoup\n",
|
||||
"\n",
|
||||
"# === CONFIGURATION ===\n",
|
||||
"BASE_URL = \"https://www.mql5.com\"\n",
|
||||
"START_PATH = \"/en/code/mt5/experts\"\n",
|
||||
"START_URL = BASE_URL + START_PATH\n",
|
||||
"DOWNLOAD_ROOT = \"mql5_experts_mt5\"\n",
|
||||
"PAGES_TO_SCRAPE = 50 # nombre de pages à parcourir\n",
|
||||
"PAGE_DELAY = 1.0 # délai entre chaque requête détail\n",
|
||||
"REQ_TIMEOUT = 30 # timeout pour requests\n",
|
||||
"\n",
|
||||
"# === FONCTIONS UTILES ===\n",
|
||||
"def safe_mkdir(path):\n",
|
||||
" \"\"\"Crée un dossier s’il n’existe pas.\"\"\"\n",
|
||||
" os.makedirs(path, exist_ok=True)\n",
|
||||
"\n",
|
||||
"def download_file(session, url, dest_folder):\n",
|
||||
" \"\"\"Télécharge un fichier (zip, .mq4/.mq5, image) via requests.\"\"\"\n",
|
||||
" safe_mkdir(dest_folder)\n",
|
||||
" filename = os.path.basename(urlparse(url).path)\n",
|
||||
" dest_path = os.path.join(dest_folder, filename)\n",
|
||||
" print(f\"[↓] {filename} ← {url}\")\n",
|
||||
" try:\n",
|
||||
" resp = session.get(url, stream=True, timeout=REQ_TIMEOUT)\n",
|
||||
" resp.raise_for_status()\n",
|
||||
" with open(dest_path, \"wb\") as f:\n",
|
||||
" for chunk in resp.iter_content(1024):\n",
|
||||
" f.write(chunk)\n",
|
||||
" print(f\"[✔] OK: {filename}\")\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"[✘] Erreur download {filename}: {e}\")\n",
|
||||
"\n",
|
||||
"# === PRÉPARATION ===\n",
|
||||
"session = requests.Session()\n",
|
||||
"session.headers.update({\"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64)\"})\n",
|
||||
"safe_mkdir(DOWNLOAD_ROOT)\n",
|
||||
"\n",
|
||||
"# === SCRAPING ===\n",
|
||||
"for page in range(1, PAGES_TO_SCRAPE + 1):\n",
|
||||
" # 1) Charger la page de listing\n",
|
||||
" page_url = START_URL if page == 1 else f\"{START_URL}/page{page}\"\n",
|
||||
" print(f\"\\n=== PAGE {page}/{PAGES_TO_SCRAPE} : {page_url}\")\n",
|
||||
" resp = session.get(page_url, timeout=REQ_TIMEOUT)\n",
|
||||
" resp.raise_for_status()\n",
|
||||
" soup = BeautifulSoup(resp.text, \"html.parser\")\n",
|
||||
"\n",
|
||||
" # 2) Sélectionner les tuiles d’experts\n",
|
||||
" container = soup.select_one(\"div.codebase-list__content\")\n",
|
||||
" if not container:\n",
|
||||
" print(\" [!] Conteneur introuvable, on passe.\")\n",
|
||||
" continue\n",
|
||||
"\n",
|
||||
" tiles = container.select(\"div.code-tile\")\n",
|
||||
" print(f\" • {len(tiles)} experts détectés sur cette page\")\n",
|
||||
"\n",
|
||||
" for tile in tiles:\n",
|
||||
" # 3) Lien et titre\n",
|
||||
" a = tile.select_one(\"div.title > a\")\n",
|
||||
" if not a or not a.get(\"href\"):\n",
|
||||
" continue\n",
|
||||
" rel_link = a[\"href\"]\n",
|
||||
" # ne garder que /en/code/<id> ou /en/code/mt5/experts/<id>\n",
|
||||
" if not re.match(r\"^/en/code(/mt5/experts)?/\\d+\", rel_link):\n",
|
||||
" continue\n",
|
||||
"\n",
|
||||
" title = a.get_text(strip=True)\n",
|
||||
" detail_url = urljoin(BASE_URL, rel_link)\n",
|
||||
" print(f\"\\n→ EA : {title}\")\n",
|
||||
" print(f\" URL : {detail_url}\")\n",
|
||||
"\n",
|
||||
" # Dossier où tout va être téléchargé\n",
|
||||
" safe_name = re.sub(r'[\\\\/:\\*\\?\"<>\\|]', '_', title)\n",
|
||||
" folder = os.path.join(DOWNLOAD_ROOT, safe_name)\n",
|
||||
"\n",
|
||||
" # 4) Charger la page détail\n",
|
||||
" dresp = session.get(detail_url, timeout=REQ_TIMEOUT)\n",
|
||||
" dresp.raise_for_status()\n",
|
||||
" dsoup = BeautifulSoup(dresp.text, \"html.parser\")\n",
|
||||
"\n",
|
||||
" # 5) Télécharger le ZIP si disponible\n",
|
||||
" zip_link = dsoup.find(\"a\", string=re.compile(r\"Download as ZIP\", re.I))\n",
|
||||
" if zip_link and zip_link.get(\"href\"):\n",
|
||||
" download_file(session, urljoin(BASE_URL, zip_link[\"href\"]), folder)\n",
|
||||
" else:\n",
|
||||
" # sinon le premier .mq5/.mq4\n",
|
||||
" code_link = dsoup.find(\"a\", href=re.compile(r\"\\.mq[45]$\", re.I))\n",
|
||||
" if code_link:\n",
|
||||
" download_file(session, urljoin(BASE_URL, code_link[\"href\"]), folder)\n",
|
||||
" else:\n",
|
||||
" print(\" [!] Aucun ZIP ni .mq5/.mq4 trouvé\")\n",
|
||||
"\n",
|
||||
" # 6) Télécharger toutes les images intégrées\n",
|
||||
" images = dsoup.find_all(\"img\", src=re.compile(r\"\\.(png|jpe?g|gif)$\", re.I))\n",
|
||||
" print(f\" • {len(images)} images détectées\")\n",
|
||||
" for img in images:\n",
|
||||
" src = img.get(\"src\") or img.get(\"data-src\")\n",
|
||||
" if src:\n",
|
||||
" download_file(session, urljoin(BASE_URL, src), folder)\n",
|
||||
"\n",
|
||||
" time.sleep(PAGE_DELAY)\n",
|
||||
"\n",
|
||||
"print(\"\\n=== TÉLÉCHARGEMENT TERMINÉ ===\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e35fd575",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.18"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Reference in New Issue
Block a user