Skip to content

Instantly share code, notes, and snippets.

@Cqoicebordel
Last active July 28, 2020 12:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Cqoicebordel/e2618751305b8f27e64ed56ce48d6fcc to your computer and use it in GitHub Desktop.
Save Cqoicebordel/e2618751305b8f27e64ed56ce48d6fcc to your computer and use it in GitHub Desktop.
Récupérer des données Linky après update de juillet 2020

Ceci est un guide pour récupérer automatiquement des données depuis Enedis, en utilisant Python3 et Selenium.

C'est un gros hack, juste en attendant la mise à dispo d'une API pour les utilisateurs.

Avant toute chose, il faut :

  • Vous munir de votre login/mdp Enedis
  • Récupérer vos valeurs spécifiques d'Enedis (voir plus bas)
  • Récupérer le ChromeDriver correspondant à votre plateforme (https://chromedriver.chromium.org/downloads)
  • Installer le ChromeDriver dans un répertoire présent dans votre PATH (regardez ailleurs pour plus de détails sur l'installation de Selenium)
  • Installer Selenium pour Python3

Une fois que vous avez fait ça, il vous faut lancer setup.py (python3 setup.py) après remplis les valeurs qui vous correspondent. A noter, spécifiquement, le chemin de profile. Ce sera un chemin qu'il faudra réutiliser dans le cron, et qui contient un profile Chrome complet. Connectez-vous à Enedis, et attendez que la page de mesures Enedis sois totalement chargée avant de fermer Chrome.

Une fois le setup fait, il vous faut remplir les paramètres du deuxième fichier. C'est ce fichier qu'il faudra lancer dans un cron (avec sous Linux DISPLAY=:0 python3 /chemin/vers/main.py).

Les paramètres personnes et prms viennent de l'URL du JSON. Pour les récupérer, allez sur votre page Enedis de mesures, ouvrez les outils de développement. Filtrez par XHR. Actualisez la page, et attendez que les mesures chargent. Dans les outils de devs, trouvez la ligne donnees-energie?dateDebut…, et cliquez dessus. En haut, vous trouverez la Request URL, et vous aurez quelque chose du genre :
https://apps.lincs.enedis.fr/mes-mesures/api/private/v1/personnes/KRT22PUD/prms/06205681943608/donnees-energie?dateDebut=9-8-2017&dateFin=24-7-2020&mesuretypecode=CONS
Là, vous pourrez récupérer les valeurs suivant /personnes/ et /prms/.

Une fois tous ces paramètres remplis, lancez le script avec python3 main.py.

/!\ Ce script est fait pour remplir le fichier JSON de github.com/KiboOst/php-LinkyAPI
/!\ Je n'ai fait ce script que pour moi. Et je n'ai pas activé les demi-heures. Du coup, il n'y a rien dans le script pour gérer ça. Cette partie est laissée comme exercice au lecteur ;)

#! python3
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
import datetime
import time
from dateutil.relativedelta import relativedelta
import re
import json
# Là où est stocké le profil Chrome. Chemin complet
cheminProfile = "/var/www/enedis/python/profile/"
# Mot de passe de votre compte Enedis
motDePasse = '1qcS2RJUaoTs5l05UUnY='
# Valeurs récupérées de l'URL
personnes = 'KRT22PUD'
prms = '06205681943608'
# Chemin complet du fichier JSON de php-LinkyAPI
cheminJSON = '/var/www/enedis/php-LinkyAPI-master/linkyLog.json'
# Nettoie la valeur des mois pour suivre le "format" de php-LinkyAPI
def replaceMonth(string):
replaced = string.replace("Janvier", "Jan")
replaced = replaced.replace("Février", "Feb")
replaced = replaced.replace("Mars", "Mar")
replaced = replaced.replace("Avril", "Apr")
replaced = replaced.replace("Mai", "May")
replaced = replaced.replace("Juin", "Jun")
replaced = replaced.replace("Juillet", "Jul")
replaced = replaced.replace("Août", "Aug")
replaced = replaced.replace("Septembre", "Sep")
replaced = replaced.replace("Octobre", "Oct")
replaced = replaced.replace("Novembre", "Nov")
replaced = replaced.replace("Décembre", "Dec")
return replaced
# Transforme une date JJ/MM/AA en JJ/MM/AAAA, pour suivre php-LinkyAPI
def replaceYear(string):
return re.sub('([0-9]{2}/[0-9]{2})/([0-9]{2})', r'\1/20\2', string)
chrome_options = Options()
chrome_options.add_argument("user-data-dir="+cheminProfile)
browser = webdriver.Chrome('chromedriver',options=chrome_options)
# Cette ligne met juste le navigateur dans un coin. Si vous voulez garder la fenêtre devant vous, hésitez pas à la commenter
browser.set_window_position(-5000, -5000)
# Charge la page de login
browser.get('https://mon-compte.enedis.fr/auth/XUI/#login/&realm=/enedis&forward=true&spEntityID=SP-ODW-PROD&goto=/SSOPOST/metaAlias/enedis/providerIDP?ReqID%3Da491c3a31c12ea083f9338aic58454h%26index%3Dnull%26acsURL%3Dhttps://apps.lincs.enedis.fr/saml/SSO%26spEntityID%3DSP-ODW-PROD%26binding%3Durn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST&AMAuthCookie=')
# Attend que la page soit chargée avant de rentrer le mdp et de presser "entrer"
idElement2 = WebDriverWait(browser, 10).until(EC.visibility_of_element_located((By.ID, "idToken2")))
idElement2.send_keys(motDePasse)
idElement2.send_keys(Keys.RETURN);
# Temps nécessaire au chargement complet de la page de compte Enedis. C'est important que la page soit totalement chargée, donc n'hésitez pas à l'adapter à votre cas.
time.sleep(5)
today = datetime.date.today()
twoMago = today - relativedelta(months=26)
# dd/mm/YY
d0 = twoMago.strftime("%d-%m-%Y")
d1 = today.strftime("%d-%m-%Y")
# Téléchargement et nettoyage du JSON
browser.get('about:blank')
browser.get('https://apps.lincs.enedis.fr/mes-mesures/api/private/v1/personnes/'+personnes+'/prms/'+prms+'/donnees-energie?dateDebut='+d0+'&dateFin='+d1+'&mesuretypecode=CONS')
source = browser.page_source
source = re.sub('<[^(){}]*>', '', source)
source = re.sub("\'", '\"', source)
jsoned = json.loads(source)
# Afficher les trois derniers jours de valeurs. Permet de tester sans modifier de fichier (si vous commentez la suite du code, évidemment)
#print('"' + jsoned['1']["CONS"]["aggregats"]["JOUR"]["labels"][-3].split()[1] + '": "' + str(jsoned['1']["CONS"]["aggregats"]["JOUR"]["datas"][-3]) + 'kWh",')
#print('"' + jsoned['1']["CONS"]["aggregats"]["JOUR"]["labels"][-2].split()[1] + '": "' + str(jsoned['1']["CONS"]["aggregats"]["JOUR"]["datas"][-2]) + 'kWh",')
#print('"' + jsoned['1']["CONS"]["aggregats"]["JOUR"]["labels"][-1].split()[1] + '": "' + str(jsoned['1']["CONS"]["aggregats"]["JOUR"]["datas"][-1]) + 'kWh"')
browser.close()
# Charge le fichier JSON de php-LinkyAPI
with open(cheminJSON, 'r') as log:
logData = json.load(log)
# Remplis les 3 derniers jours
logData["days"][replaceYear(jsoned['1']["CONS"]["aggregats"]["JOUR"]["labels"][-3].split()[1])] = str(jsoned['1']["CONS"]["aggregats"]["JOUR"]["datas"][-3]) + 'kWh'
logData["days"][replaceYear(jsoned['1']["CONS"]["aggregats"]["JOUR"]["labels"][-2].split()[1])] = str(jsoned['1']["CONS"]["aggregats"]["JOUR"]["datas"][-2]) + 'kWh'
logData["days"][replaceYear(jsoned['1']["CONS"]["aggregats"]["JOUR"]["labels"][-1].split()[1])] = str(jsoned['1']["CONS"]["aggregats"]["JOUR"]["datas"][-1]) + 'kWh'
# Remplis les 2 derniers mois
logData["months"][replaceMonth(jsoned['1']["CONS"]["aggregats"]["MOIS"]["labels"][-2])] = str(jsoned['1']["CONS"]["aggregats"]["MOIS"]["datas"][-2]) + 'kWh'
logData["months"][replaceMonth(jsoned['1']["CONS"]["aggregats"]["MOIS"]["labels"][-1])] = str(jsoned['1']["CONS"]["aggregats"]["MOIS"]["datas"][-1]) + 'kWh'
# Remplis les 2 dernières années
logData["years"][jsoned['1']["CONS"]["aggregats"]["ANNEE"]["labels"][-2]] = str(jsoned['1']["CONS"]["aggregats"]["ANNEE"]["datas"][-2]) + 'kWh'
logData["years"][jsoned['1']["CONS"]["aggregats"]["ANNEE"]["labels"][-1]] = str(jsoned['1']["CONS"]["aggregats"]["ANNEE"]["datas"][-1]) + 'kWh'
# Met à jour la date de mise à jour
now = datetime.datetime.now()
logData["Update"] = now.strftime("%d/%m/%Y %H:%M:%S")
# Enregistre le nouveau fichier JSON
with open(cheminJSON, 'w') as log:
json.dump(logData, log, indent=4)
#! python3
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
cheminProfile = "/var/www/enedis/python/profile/"
chrome_options = Options()
chrome_options.add_argument("user-data-dir="+cheminProfile)
browser = webdriver.Chrome('chromedriver',options=chrome_options)
browser.set_window_position(-5000, -5000)
browser.get('https://mon-compte-particulier.enedis.fr/suivi-de-mesures/')
@carmelo42
Copy link

Je viens de tester le script, et j'obtiens une erreur SSL dans le navigateur Chrome qui se lance :

https://zupimages.net/up/20/31/tmd4.png

une idée ?

@Cqoicebordel
Copy link
Author

Pas la moindre.
Peut-être qu'il faut bypasser cette erreur (cliquer sur "paramètres avancés" et faire "continuer") pour que ce soit accepté. Et espérer que cette préférence soit enregistrée.
Sinon, il peut y avoir un flag (chrome:flags) pour le SSL, pour réactiver les anciens protocoles (TLS1.0, TLS1.1).
A tester, donc :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment