Récupérer son prix de carburant (encore) avec le multiscraping

Salut @Pbranly

Voici le code multiscrape pour récupérer les infos depuis le site web :

multiscrape:
  - name: carburants_feillens
    resource: "https://carbu.com/france/index.php/station/intermarche/feillens/01570/16195"
    scan_interval: 3600
    sensor:
      - unique_id: carburants_feillens
        select: "[itemtype='http://data-vocabulary.org/Organization'] h1"
        value_template: "{{ value }}"
        attributes:
          - name: sp98_name
            select: ".col-xs-12:nth-of-type(1) h2"
          - name: sp98_price
            select: ".col-xs-12:nth-of-type(1) h1.price"
            value_template: "{{ value|replace(',','.') }}"
          - name: sp98_date
            select: ".col-xs-12:nth-of-type(1) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
          - name: sp95_e10_name
            select: ".col-xs-12:nth-of-type(3) h2.title"
          - name: sp95_e10_price
            select: ".col-xs-12:nth-of-type(3) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: sp95_e10_date
            select: ".col-xs-12:nth-of-type(3) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
          - name: bio_e85_name
            select: ".col-xs-12:nth-of-type(4) h2"
          - name: bio_e85_price
            select: ".col-xs-12:nth-of-type(4) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: bio_e85_date
            select: ".col-xs-12:nth-of-type(4) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
          - name: diesel_name
            select: ".col-xs-12:nth-of-type(5) h2"
          - name: diesel_price
            select: ".col-xs-12:nth-of-type(5) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: diesel_date
            select: ".col-xs-12:nth-of-type(5) p"
            value_template: "{{ value.split(' ')[0] }}"
  - name: carburants_auchan
    resource: "https://carbu.com/france/index.php/station/auchan/macon/71000/6438"
    scan_interval: 3600
    sensor:
      - unique_id: carburants_auchan
        select: "[itemtype='http://data-vocabulary.org/Organization'] h1"
        value_template: "{{ value }}"
        attributes:
          - name: sp98_name
            select: ".col-xs-12:nth-of-type(1) h2"
          - name: sp98_price
            select: ".col-xs-12:nth-of-type(1) h1.price"
            value_template: "{{ value|replace(',','.') }}"
          - name: sp98_date
            select: ".col-xs-12:nth-of-type(1) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
          - name: sp95_e10_name
            select: ".col-xs-12:nth-of-type(3) h2"
          - name: sp95_e10_price
            select: ".col-xs-12:nth-of-type(3) h1.price"
            value_template: "{{ value|replace(',','.') }}"
          - name: sp95_e10_date
            select: ".col-xs-12:nth-of-type(3) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
          - name: gpl_name
            select: ".col-xs-12:nth-of-type(5) h2"
          - name: gpl_price
            select: ".col-xs-12:nth-of-type(5) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: gpl_date
            select: ".col-xs-12:nth-of-type(5) p"
            value_template: "{{ value.split(' ')[0] }}"
          - name: diesel_name
            select: ".col-xs-12:nth-of-type(4) h2"
          - name: diesel_price
            select: ".col-xs-12:nth-of-type(4) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: diesel_date
            select: ".col-xs-12:nth-of-type(4) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
  - name: carburants_bien
    resource: "https://carbu.com/france/index.php/station/atac/saint-benigne/01190/12119"
    scan_interval: 3600
    sensor:
      - unique_id: carburants_bien
        select: "[itemtype='http://data-vocabulary.org/Organization'] h1"
        value_template: "{{ value }}"
        attributes:
          - name: sp98_name
            select: ".col-xs-12:nth-of-type(1) h2"
          - name: sp98_price
            select: ".col-xs-12:nth-of-type(1) h1.price"
            value_template: "{{ value|replace(',','.') }}"
          - name: sp98_date
            select: ".col-xs-12:nth-of-type(1) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
          - name: sp95_e10_name
            select: ".col-xs-12:nth-of-type(2) h2"
          - name: sp95_e10_price
            select: ".col-xs-12:nth-of-type(2) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: sp95_e10_date
            select: ".col-xs-12:nth-of-type(2) p"
            value_template: "{{ value.split(' ')[0] }}"
          - name: diesel_name
            select: ".col-xs-12:nth-of-type(4) h2"
          - name: diesel_price
            select: ".col-xs-12:nth-of-type(4) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: diesel_date
            select: ".col-xs-12:nth-of-type(4) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
  - name: carburants_replonges
    resource: "https://carbu.com/france/index.php/station/intermarche/replonges/01750/12321"
    scan_interval: 3600
    sensor:
      - unique_id: carburants_replonges
        select: "[itemtype='http://data-vocabulary.org/Organization'] h1"
        value_template: "{{ value }}"
        attributes:
          - name: sp95_e5_name
            select: ".col-xs-12:nth-of-type(2) h2"
          - name: sp95_e5_price
            select: ".col-xs-12:nth-of-type(2) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: sp95_e5_date
            select: ".col-xs-12:nth-of-type(2) p"
            value_template: "{{ value.split(' ')[0] }}"
          - name: sp95_e10_name
            select: ".col-xs-12:nth-of-type(3) h2.title"
          - name: sp95_e10_price
            select: ".col-xs-12:nth-of-type(3) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: sp95_e10_date
            select: ".col-xs-12:nth-of-type(3) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
          - name: diesel_name
            select: ".col-xs-12:nth-of-type(4) h2"
          - name: diesel_price
            select: ".col-xs-12:nth-of-type(4) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: diesel_date
            select: ".col-xs-12:nth-of-type(4) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
  - name: carburants_fleurville
    resource: "https://carbu.com/france/index.php/station/total-access/fleurville/71260/10173"
    scan_interval: 3600
    sensor:
      - unique_id: carburants_fleureville
        select: "[itemtype='http://data-vocabulary.org/Organization'] h1"
        value_template: "{{ value }}"
        attributes:
          - name: sp98_name
            select: ".col-xs-12:nth-of-type(1) h2"
          - name: sp98_price
            select: ".col-xs-12:nth-of-type(1) h1.price"
            value_template: "{{ value|replace(',','.') }}"
          - name: sp98_date
            select: ".col-xs-12:nth-of-type(1) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
          - name: sp95_e10_name
            select: ".col-xs-12:nth-of-type(3) h2.title"
          - name: sp95_e10_price
            select: ".col-xs-12:nth-of-type(3) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: sp95_e10_date
            select: ".col-xs-12:nth-of-type(3) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
          - name: bio_e85_name
            select: ".col-xs-12:nth-of-type(4) h2"
          - name: bio_e85_price
            select: ".col-xs-12:nth-of-type(4) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: bio_e85_date
            select: ".col-xs-12:nth-of-type(4) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
          - name: diesel_name
            select: ".col-xs-12:nth-of-type(5) h2"
          - name: diesel_price
            select: ".col-xs-12:nth-of-type(5) h1"
            value_template: "{{ value|replace(',','.') }}"
          - name: diesel_date
            select: ".col-xs-12:nth-of-type(5) p"
            value_template: "{{ value.split(' ')[0] }}"

*à modifier suivant ta ville

Voici le code pour la card :

              type: custom:vertical-stack-in-card
              card_mod:
                style: |
                  ha-card {
                   --ha-card-background: rgba(0, 0, 0, 0.1);
                  ha-card {
                    margin-top: 0em;
                      }         
              mode: vertical
              cards:
                - type: picture-entity
                  entity: binary_sensor.dalg_nas
                  image: /local/images/essence.jpg
                  show_name: true
                  show_state: false
                  name: Station Service
                  tap_action:
                    action: none
                  hold_action:
                    action: none
                - type: divider
                  style:
                    height: 2px
                    width: 100%
                    margin-left: auto
                    margin-right: auto
                    background: rgba(255, 255, 255, 0.5)
                - type: custom:flex-table-card
                  sort_by: diesel_price
                  entities:
                    include: sensor.carburants*
                  columns:
                    - data: state
                      icon: mdi:gas-station
                      align: left
                    - name: Diesel
                      data: diesel_price
                      align: center
                    - name: Update
                      data: diesel_date
                      align: center
                  css:
                    tbody tr:nth-child(odd): 'background-color: rgba(255, 255, 255, 0.2)'
                    tbody tr:nth-child(even): 'background-color: rgba(255, 255, 255, 0.1)'
                    tbody tr:nth-child(1): 'color: #00ff00'
                    tbody tr:nth-child(5): 'color: #FF0000'
                  card_mod:
                    style: |
                      ha-card {
                      border-radius: 10px;
                      padding-bottom: 10px;
                      background-color: rgba(0, 0, 0, 0.1)
                      }
                      :host {
                      font-size: 13px;
                      border-radius: 10px;
                      }
                - type: divider
                  style:
                    height: 2px
                    width: 100%
                    margin-left: auto
                    margin-right: auto
                    background: rgba(255, 255, 255, 0.5)
                - type: custom:flex-table-card
                  sort_by: sp95_e10_price
                  entities:
                    include: sensor.carburants*
                  columns:
                    - data: state
                      icon: mdi:gas-station
                      align: left
                    - name: SP95
                      data: sp95_e10_price
                      align: center
                    - name: Update
                      data: sp95_e10_date
                      align: center
                  css:
                    tbody tr:nth-child(odd): 'background-color: rgba(255, 255, 255, 0.2)'
                    tbody tr:nth-child(even): 'background-color: rgba(255, 255, 255, 0.1)'
                    tbody tr:nth-child(1): 'color: #00ff00'
                    tbody tr:nth-child(5): 'color: #FF0000'
                  card_mod:
                    style: |
                      ha-card {
                      border-radius: 10px;
                      background-color: rgba(0, 0, 0, 0.1)
                      }
                      :host {
                      font-size: 13px;
                      border-radius: 10px;
                      }

Et voici l’image de la pompe à copier dans le dossier www/image

1 « J'aime »

Merci beaucoup
quel est l’objet de " ```
entity: binary_sensor.dalg_nas

philippe

C’est une entité bidon juste pour insérer l’image.
Y’a surement moyen de faire « plus propre » mais ça fonctionne très bien comme ça :metal:

Si je comprends bien, il faut ajouter chaque station individuelle, manuellement comme sensor? Pas d’automatisme comme code postal ou quoi?

Oui, faut ajouter chaque station de ton choix manuellement en créant un sensor pour chacune.

De mon coté depuis j’ai fait quelques ajustements mineurs dont les images des enseignes
image
En jouant avec value_template c’est assez simple

  sensor:
    - unique_id: carburants_auchan
      select: "[itemtype='http://data-vocabulary.org/Organization'] h1"
      value_template: "<img src='/local/images/brand/auchan.png' style='height:20px;'> {{ value }}"
3 « J'aime »

voila le resultat avec le fork de @vingerha
merci pour le modèle


Philippe

1 « J'aime »

Salut Pulpy,

Tu as fait exactement ce que je voulais faire…sauf que mon code ne récupère pas mon image…vois tu quelque chose qui n’irait pas ? Sachant que j’arrive à récupérer l’image pour une autre card que je gardais justement car je la trouvais sympa avec l’image. Cela me permettrait de grouper les 2.

Merci pour ton aide

multiscrape:
  - name: carburants_intermarche_lentigny
    resource: "https://carbu.com/france/index.php/station/intermarche/lentigny/42155/17043"
    scan_interval: 3600
    sensor:
      - unique_id: carburants_intermarche_lentigny
        select: "[itemtype='http://data-vocabulary.org/Organization'] h1"
        value_template: "<img src='/local/images/Logo_intermarche2.png' style='height:20px;'> {{ value }}"
        name: Intermarché Lentigny
        picture: /local/images/Logo_intermarche2.png
        attributes:
          - name: sp98_name
            select: ".col-xs-12:nth-of-type(1) h2"
          - name: sp98_price
            select: ".col-xs-12:nth-of-type(1) h1.price"
            value_template: "{{ value|replace(',','.') }}"
          - name: sp98_date
            select: ".col-xs-12:nth-of-type(1) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
          - name: sp95_name
            select: ".col-xs-12:nth-of-type(3) h2"
          - name: sp95_price
            select: ".col-xs-12:nth-of-type(3) h1.price"
            value_template: "{{ value|replace(',','.') }}"
          - name: sp95_date
            select: ".col-xs-12:nth-of-type(3) p.sources"
            value_template: "{{ value.split(' ')[0] }}"
          - name: B7_name
            select: ".col-xs-12:nth-of-type(6) h2"
          - name: B7_price
            select: ".col-xs-12:nth-of-type(6) h1.price"
            value_template: "{{ value|replace(',','.') }}"
          - name: B7_date
            select: ".col-xs-12:nth-of-type(6) p.sources"
            value_template: "{{ value.split(' ')[0] }}"

et pour la card

type: custom:flex-table-card
sort_by: b7_price
entities:
  - entity: sensor.carburants_leclerc_riorges
  - entity: sensor.carburants_carrefour_riorges
  - entity: sensor.carburants_carrefour_roanne
  - entity: sensor.carburants_carrefour_mably
  - entity: sensor.carburants_carrefour_le_coteau
  - entity: sensor.carburants_intermarche_commelle
  - entity: sensor.carburants_intermarche_lentigny
  - entity: sensor.carburants_intermarche_riorges
  - entity: sensor.carburants_super_u_le_coteau
columns:
  - data: name
    icon: mdi:gas-station
    align: left
  - name: Diesel
    data: b7_price
    align: center
  - name: SP95
    data: sp95_price
    align: center
  - name: SP98
    data: sp98_price
    align: center
  - name: Date
    data: b7_date
    align: center
css:
  tbody tr:nth-child(odd): 'background-color: rgba(255, 255, 255, 0.1)'
  tbody tr:nth-child(even): 'background-color: rgba(255, 255, 255, 0.2)'
  tbody tr:nth-child(1): 'color: #00ff00'
  tbody tr:nth-child(9): 'color: #f00020'
card_mod: null
style: |
  :host {
    font-size: 13px;
    border-radius: 10px;
    border-style: solid;
    border-width: 2px 2px 0px 2px;
    border-color: #ffffff;
  }

Salut,

C’est assez logique, tu mets l’image+texte dans le champ value_template (qui correspond à state dans un template)

Et tu n’utilise pas state mais le champ name pour l’affichage

1 « J'aime »

Comme d’habitude, encore merci pour ton aide!

Hello à tous.

Une petite évolution sur la carte issue du multiscraping :
Affichage de tous les mini/maxi par stations, avec possibilité de tri/filtrage des carburants et des stations
image

Il y a quelques adaptations à faire par rapport à la config initiale :

  • ajouter picture (sans mise en forme) à l’entité
    (extrait du template)
- name: carburants_auchan2
  resource: "https://carbu.com/france/index.php/station/auchan/xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  scan_interval: 3600
  sensor:
    - unique_id: carburants_auchan2
      select: "[itemtype='http://data-vocabulary.org/Organization'] h1"
      value_template: "{{value}}"
      picture: "/local/images/brands/auchan.png"
      attributes:
      [...]
  • faire un groupe des stations à afficher. En triant le groupe, on triera l’affichage
group:
  carburants:
    name: "carburants"
    entities:
      - sensor.carburants_auchan
      - sensor.carburants_auchan2
      - sensor.carburants_leclerc
      - sensor.carburants_intermarche
  • Et remplacer la carte
type: custom:stack-in-card
cards:
  - type: markdown
    content: >-
      {% set items = {0:'e10', 1:'sp98', 2:'gpl'} -%}
      {% set prices = namespace(minima=[],maxima=[]) %}
      {% for i in range(items|length) -%}
        {% set tmp = expand('group.carburants')
            |selectattr('attributes.'+items[i]+'_price', 'ne', '-') 
            |map(attribute='attributes.'+items[i]+'_price')|list -%}
        {%- set prices.minima = prices.minima + [min(tmp)] -%}
        {%- set prices.maxima = prices.maxima + [max(tmp)] -%}
      {% endfor -%}

      {% set carburants_entities = expand('group.carburants') | map(attribute='entity_id')|list %}
      <table class="red"><thead><tr> <th
      colspan="2">Enseigne</th>
      {% for j in range(items|length) -%}
        {{ '<th>'+items[j]|upper+' €/L</th>' }}
      {% endfor -%}
      <th>Date</th> </tr></thead><tbody>
        {% for carburants_entity in carburants_entities -%}
          <tr>
          <td><img src="{{state_attr(carburants_entity, 'entity_picture')}}" height="20"></td>
          <td>{{states(carburants_entity)}}</td>
          {% for k in range(items|length) -%}
            {% set price=state_attr(carburants_entity, items[k]+'_price') -%}
            <td>
            {% if price==prices.minima[k] -%}
              {{ '<font color=green>'+price+'</font>' }}
            {% elif  price==prices.maxima[k] -%}
              {{ '<font color=red>'+price+'</font>' }}
            {% else -%}
              {{price}}
            {% endif -%}
            </td>
          {% endfor -%}
          <td>{{ state_attr(carburants_entity, 'e10_date') }}</td>
          </tr>
        {% endfor -%}
      </tr></tbody></table>
  • Pour trier / filter les carburants, il suffit d’éditer la liste :
    {% set items = {0:'e10', 1:'sp98', 2:'gpl'} -%}
    Pour ajouter un carburant il ajouter une position 1. Le nom du carburant doit correspondre au prefixe de e85_name.
    {% set items = {0:'e10', 3:'sp98', 2:'gpl', 1:'e85'} -%}
    Il me reste une connerie à corriger : avoir une couleur de fond des lignes alternatives pour améliorer la lisibilité
1 « J'aime »

Punaise ça m’a pris un temps fou alors que @Clemalex avait déjà donné la solution sur le forum.
Je hais les CSS !!!

image

  - type: markdown
    card_mod:
      style:
        ha-markdown:
          $:
            ha-markdown-element: |
              tr:nth-of-type(even) {
                  background-color: #292929 !important;
              }
    content: >-
      {% set items = {1:'e10', 0:'sp98', 2:'gpl'} -%} {% set prices =
      namespace(minima=[],maxima=[]) %} {% for i in range(items|length) -%}
        {% set tmp = expand('group.carburants')
            |selectattr('attributes.'+items[i]+'_price', 'ne', '-') 
            |map(attribute='attributes.'+items[i]+'_price')|list -%}
        {%- set prices.minima = prices.minima + [min(tmp)] -%}
        {%- set prices.maxima = prices.maxima + [max(tmp)] -%}
      {% endfor -%}

      {% set carburants_entities = expand('group.carburants') |
      map(attribute='entity_id')|list %} <table><thead><tr> <th
      colspan="2">Station</th> {% for j in range(items|length) -%}
        {{ '<th>'+items[j]|upper+' €/L</th>' }}
      {% endfor -%} <th>Date</th> </tr></thead><tbody>
        {% for carburants_entity in carburants_entities -%}
          <tr>
          <td><img src="{{state_attr(carburants_entity, 'entity_picture')}}" height="20"></td>
          <td>{{states(carburants_entity)}}</td>
          {% for k in range(items|length) -%}
            {% set price=state_attr(carburants_entity, items[k]+'_price') -%}
            <td align='center'>
            {% if price==prices.minima[k] -%}
              {{ '<font color=green>'+price+'</font>' }}
            {% elif  price==prices.maxima[k] -%}
              {{ '<font color=#B90000>'+price+'</font>' }}
            {% else -%}
              {{price}}
            {% endif -%}
            </td>
          {% endfor -%}
          <td>{{ state_attr(carburants_entity, 'e10_date') }}</td>
          </tr>
        {% endfor -%}
      </tr></tbody></table>

Perso, j’enlèverai le nom de l’enseigne.

Le logo suffit non ?.. :innocent: :blush:

:+1:

Salut
Juste avec l’enseigne il faut quand même un moyen de différencier les 2 Auchan.

Moi je les ai trié dans l’ordre kilométrique.

Donc ça fait :

Intermarché
Intermarché
Géant
Leclerc
Carrefour

Mais je sais que le 1er intermarché est le plus proche du domicile.

1 « J'aime »

Je viens de tester le multiscraping et cette card pour récupérer mes prix carburant à côté de chez moi : SUPER ! (sans mauvais jeu de mots…)
Merci @Pulpy-Luke !
Par contre j’ai deux petites questions :
1 - Est-il possible de modifier le nom des enseignes ? J’ai parfois des noms à rallonge ou alors juste « du canal ». J’aimerai bien customiser les noms d’enseignes. J’ai essayé de modifier le nom de l’entité mais rien de change car je pense que le nom de l’enseigne vient directement du multicraping si j’ai bien compris…
2 - Est-il possible d’effectuer un tri automatique par prix du moins cher au plus cher ? J’ai bien la couleur verte et rouge mais cela n’est pas super lisible avec le fond blanc.

Voici ce que cela donne :

Encore merci !

Ah je viens de voir ton message concernant le nom de la station.
Mais comme je suis avec une card ‹ markdown › (et non avec une card ‹ flex-table-card ›), je ne comprends pas comment faire la modification…

Le champ state contient le nom qui effectivement est récupérer des infos issues de la page web. Tu peux ajouter les noms à la main/ en dur si tu veux

xxxxx
value_template: "Ici mon nom à moi en dur"
xxxxxx

Avec les premières versions et la carte flex-table-card tu pourrais (mais du coup sans les couleurs rouge/verte)
Maintenant avec plusieurs carburants, c’est pas terrible je trouve, parce que le moins cher du SP95 c’est pas forcement le même que le moins cher de l’E10.
Par contre tu peux changer la couleur rouge/verte par ce que tu veux green/B90000

            {% if price==prices.minima[k] -%}
              {{ '<font color=green>'+price+'</font>' }}
            {% elif  price==prices.maxima[k] -%}
              {{ '<font color=#B90000>'+price+'</font>' }}
            {% else -%}
              {{price}}
            {% endif -%}
1 « J'aime »

Merci @Pulpy-Luke !
C’est top !

Est-ce qu’on peut transformer cette ligne :

{{ '<font color=#32CD32>'+price+'</font>' }}

pour que le prix s’affiche en gras ?

Et dernière question, je n’ai pas de date pour carrefour Chalon Nord car ils ne proposent pas le E10. J’ai vu dans le code que la date se basait sur le E10.

<td>{{ state_attr(carburants_entity, 'e10_date') }}</td>

Est-il possible de mentionner que si pas dispo en E10 alors se référer au sp95 ?

tu peux adapter en faisant
{{ '<font color=#32CD32><b>'+price+'</b></font>' }}

Non (peut être mais j’ai pas testé), mais si tu as du SP95 partout, tu peux te baser sur info à la place => sp95_date

1 « J'aime »