Bonjour,
Suite au passage à l’offre Tempo d’EDF, j’ai installé 2 intégrations :
- RTE Tempo qui me permet de savoir les jours Bleu / Blanc / Rouge.
- Tarifs EDF qui permet d’avoir les tarifs du jour en cours ainsi que la couleur du jour, déjà donné par RTE Tempo.
Tarifs EDF ne donne que le tarif du jour mais pas avant le changement d’horaire (passage en heure pleine à 6h00 du matin).
J’ai réalisé une automation qui permet de sauver le tarif en cours dans la bonne couleur de journée, donc avec du retard je dois pouvoir avoir les tarifs à jour.
Voir ici :
Toutefois, Tarif EDF ne se met pas à jour à l’heure qu’il faut et fait des trucs bizarre.
Le mieux serait d’aller chercher les informations sur le compte EDF de l’utilisateur.
J’ai commencé avec ha-multiscrape :
Mais impossible de se connecter avec cet outils.
J’en suis donc à tenter de me connecter avec Browserless Chromium
Voir l’article :
C’est prometteur, si j’arrive à me connecter, je pourrais récupérer les informations du compte, avec prix de l’abonnement, le nombre de KVA e les tarifs.
Message aux modérateurs : je sais qu’il y a pas mal de sujets qui se téléscopes mais ici je ne parlerais que de Browserless Chromium et c’est vraiment un sujet à part !
- Aller sur la page : [GUIDE] Scraping dynamic websites with browserless + multiscrape. v2 update - Community Guides - Home Assistant Community
- Ajouter le dépot : Link to Add repository – My Home Assistant
- Installer le module complémentaire « Browserless Chromium »
- Se rendre sur la page : http://homeassistant.local:3000/debugger/
Voici mon script :
Il fonctionne jusqu’au moment ou je souhaite cliquer sur « suivant » et la il dit qu’il y a une erreur, je suspecte un système anti-robot.
Si certains d’entre vous peuvent aider je suis preneur. Si on se loggue, derrière ça devient facile de récupérer les informations.
const URL_CONTRAT_EDF = "https://particulier.edf.fr/fr/accueil/espace-client/selecteur-contrat.html?goto=%2Ffr%2Faccueil%2Fespace-client%2Fmes-contrats.html";
// Constantes de login
const LOGIN_USERNAME = 'monmail@mail.fr';
const LOGIN_PASSWORD = 'monmotdepasse';
// Constantes de recherche d'éléments dans la page
const SELECTOR_BUTTON_ACCEPT_COOKIE = '#popin_tc_privacy_button_3';
const SELECTOR_INPUT_USERNAME = '#email';
const SELECTOR_INPUT_PASSWORD = '#password';
const SELECTOR_BUTTON_USERNAME_NEXT = '#username-next-button';
// Activer le plugin Stealth
// const puppeteer_extra = require('puppeteer-extra');
// puppeteer_extra.use(require('puppeteer-extra-plugin-anonymize-ua')());
// const StealthPlugin = require('puppeteer-extra-plugin-stealth');
// puppeteer_extra.use(StealthPlugin());
export default async ({ page }: { page: Page }) => {
// Naviguer vers la page Contrat EDF
// Définir les en-têtes personnalisés
// await page.setCacheEnabled(false);
// await page.setJavaScriptEnabled(true);
// await page.setExtraHTTPHeaders({
// 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
// 'Accept-Language': 'en-GB,en-NZ;q=0.9,en-AU;q=0.8,en;q=0.7,en-US;q=0.6'
// });
//await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36');
//await page.setUserAgent('Chrome/114.0.0.0');
console.log("================================================> Navigation vers la page Contrat EDF...");
await page.goto(URL_CONTRAT_EDF);
// Attendre que les cookies soient affichés et cliquer sur "Accepter" les cookies
console.log("================================================> Attendre pour accepter les cookies...");
await page.waitForSelector(SELECTOR_BUTTON_ACCEPT_COOKIE);
await page.click(SELECTOR_BUTTON_ACCEPT_COOKIE); // Accepter les cookies
console.log("================================================> Cookies acceptés");
// Attendre que le champ email soit visible
console.log("================================================> Attendre pour remplir le login...");
await page.waitForSelector(SELECTOR_INPUT_USERNAME);
// Cliquer sur le champs login pour que la page valide
await page.mouse.move(134, 122);
await page.mouse.move(136, 144);
await page.click(SELECTOR_INPUT_USERNAME);
await page.$eval(SELECTOR_INPUT_USERNAME, (el, value) => { el.value = value; }, LOGIN_USERNAME);
// Remplir le champ email avec le nom d'utilisateur
await page.click(SELECTOR_INPUT_USERNAME);
console.log("================================================> Login rempli");
// Attendre que la check soit visible
//await page.waitForSelector('span.ico.ico-sm.ico-r-valider.valide', { visible: true });
// Attendre que le bouton ne soit plus grisé
// Attendre que le bouton soit activé (cliquable)
console.log("================================================> Attendre que le bouton SUIVANT soit visible");
await page.waitForSelector(SELECTOR_BUTTON_USERNAME_NEXT, { visible: true });
// Attendre que le bouton ne soit plus grisé et qu'il soit cliquable
console.log("================================================> Attendre que le bouton SUIVANT soit actif");
// await page.waitForFunction(
// (selector) => {
// const button = document.querySelector(selector);
// // Vérifier si l'élément existe et s'il est activé
// if (button) {
// // Faire un cast explicite pour que TypeScript reconnaisse les propriétés
// const buttonElement = button as HTMLButtonElement | HTMLInputElement;
// // Vérification si l'élément est activé (non désactivé)
// const isEnabled = !buttonElement.disabled;
// // Vérification si la propriété pointer-events est active (pas 'none')
// const isPointerEventsActive = window.getComputedStyle(button).pointerEvents !== 'none';
// return isEnabled && isPointerEventsActive;
// }
// return false;
// },
// { timeout: 10000 }, // Timeout de 10 secondes
// SELECTOR_BUTTON_USERNAME_NEXT
// );
delay(2000);
console.log("================================================> Clic sur le bouton SUIVANT...");
// Cliquer sur le bouton Next
//await page.click(SELECTOR_BUTTON_USERNAME_NEXT);
await page.evaluate(() =>
{
const button = document.querySelector('#username-next-button');
if (button)
{
const event = new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window
});
button.dispatchEvent(event); // Déclenche l'événement comme un clic réel
console.log("================================================> Bouton SUIVANT cliqué !");
}
else
{
console.log("================================================> Bouton SUIVANT non trouvé !");
}
});
console.log("================================================> Attendre que le mot de passe soit visible...");
// Attendre que le champ mot de passe soit visible
await page.waitForSelector(SELECTOR_INPUT_PASSWORD);
// Remplir le champ mot de passe avec le mot de passe de l'utilisateur
console.log("================================================> Remplir le mot de passe...");
await page.$eval(SELECTOR_INPUT_PASSWORD, (el, value) => { el.value = value; }, LOGIN_PASSWORD);
console.log("================================================> Mot de passe rempli !");
// Cliquer sur suivant
//await page.click('#popin_tc_privacy_button_3'); // Accepter les cookies
// // Attendre que le champ mot de passe soit visible
// await page.waitForSelector(PASSWORD_SELECTOR);
// // Remplir le champ mot de passe
// await page.$eval(PASSWORD_SELECTOR, (el, value) => { el.value = value; }, LOGIN_PASSWORD);
// // Attendre que le bouton de connexion soit visible et cliquer dessus
// await page.waitForSelector(BUTTON_SELECTOR);
// await page.click(BUTTON_SELECTOR);
// // Attendre que la page suivante se charge après la soumission
// await page.waitForNavigation();
console.log("================================================> Connexion réussie !");
};
// Fonction pour une pause (delay) en millisecondes
function delay(ms)
{
return new Promise(resolve => setTimeout(resolve, ms));
}
Pour le moment; j’ai ça :
Autre solution avec ha-multiscrapper : convertir le fichier pdf en texte et en extraire les variables que l’on souhaite.
- name: Tarifs EDF Tempo
# Créer un compte sur : https://app.pdf.co/signup
resource: https://api.pdf.co/v1/pdf/convert/to/text
log_response: true
method: POST
headers:
Content-Type: application/json
x-api-key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # Remplacez par votre clé API obtenue sur PDF.co
payload: >
{
"url": "https://particulier.edf.fr/content/dam/2-Actifs/Documents/Offres/Grille_prix_Tarif_Bleu.pdf",
"inline": true,
"pages": "1" # Uniquement la page PDF
}
scan_interval: 30 # Mise à jour quotidienne
sensor:
- unique_id: tarif_bleu_texte_entier
name: Tarif Bleu Texte Entier
select: "#power"
value_template: "{{ value_json['text'] }}" # Extraction du champ 'text'