Contenu | Rechercher | Menus

Annonce

DVD, clés USB et t-shirts Ubuntu-fr disponibles sur la boutique En Vente Libre

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 16/06/2021, à 15:39

alex2423

[Python][Request] Comment parser une page HTML avec le RGPD ?

Hello tout le monde,

Je souhaiterais récupérer le numéro produit d'un titre financier à partir de son code financier sur le site Quantalys en utilisant la libraire Request en Python

Exemple à cette adresse pour le code LU1681048630 :
https://www.quantalys.com/Recherche?search=LU1681048630

La page me donne cette information. LU1681048630 a comme code produit 561617

<td class="text-left sorting_1">
<a href="/Produit/561617" target="_blank">Amundi IS S&amp;P Gbl Luxury UCITS ETF EUR C</a>
</td>

Mais malheureusement je me retrouve bloqué à cause du RGPD. Sous Firefox, lorsque l'on ouvre la première fois (Firefox en mode privé par exemple), un popup RGPD apparait avec 2 boutons possibles : "Personnaliser" et "Tout accepter".

Quand on regarde de plus près, le bouton "Tout accepter" déclenche une fonction Javascript

function() {
  tarteaucitron.userInterface.respondAll(!0)
}

Je ne sais pas si c'est possible d'appeler facilement du code JS en python et lancer la fonction pour simuler le clique. Je pense que cela me semble compliqué.


Je pense que le plus simple est de jouer avec les cookies.
Quand on regarde dans Firefox, lorsque l'on accepte les conditions, j'ai un cookie avec comme nom tarteaucitron (et cela ressemble au tag que j'ai vu dans le formulaire du rgpd)
https://i.imgur.com/1ZDG3YX.png
La valeur du cookie est : https://i.imgur.com/1ZDG3YX.png
avec comme valeur suivante :

tarteaucitron:"!gtag=true!twitterwidgetsapi=true!twittertimeline=true!spotify=true!youtube=true!youtubeapi=true"

En plus du cookie tarteaucitron, il en existe d'autres mais ont l'air d'être facultatif. Après avoir validé le RGDP via Firefox via l'interface, j'ai supprimé les autres cookies puis rafraîchie la page qui s'affiche sans le popup RGPD

J'ai essayé le code suivant :

#from requests_html import HTMLSession
#session = HTMLSession()
import requests
url = "https://www.quantalys.com/Recherche?search=LU1681048630"

cookies_jar = requests.cookies.RequestsCookieJar()
cookies_jar.set('tarteaucitron', "!gtag=true!twitterwidgetsapi=true!twittertimeline=true!spotify=true!youtube=true!youtubeapi=true", domain="www.quantalys.com", path='/')
response = requests.get(url, cookies=cookies_jar)
print(response.text)

Mais sans succès, la page retournait ne me renvoi pas la balise a href : a href="/Produit/561617". Auriez vous des idées comment accepter les RGPD ?

Hors ligne

#2 Le 16/06/2021, à 18:07

Vobul

Re : [Python][Request] Comment parser une page HTML avec le RGPD ?

Avant d'aller plus loin, reprenons le problème de base :

> Je souhaiterais récupérer le numéro produit d'un titre financier à partir de son code financier sur le site Quantalys

Est-ce que c'est obligé de passer par Quantalys. Quelle est la finalité ? Parce que je suis sûr qu'il y a des sites qui proposent une API REST pour ce genre de choses, bien plus simple que parser du html avec le javascript activé, les cookies et tout le tralala.


Vobul

Utilisez le retour utilisable de commandes !!!
J'aime la langue française, mais je parle franglais, deal with it.

Hors ligne

#3 Le 16/06/2021, à 19:43

soshy

Re : [Python][Request] Comment parser une page HTML avec le RGPD ?

Bien tenté, mais c'est perdu tongue
C'est pas le RGPD ton problème smile

Ton problème, c'est le web moderne, qui envoi un bout de page, puis le javascript fait des requêtes supplémentaires pour récupérer plus de données et les ajouter à la page initialement chargée. Au lieu de regarder l'onglet storage, vas sur network. Là, tu recharges la page et tu filtres les résultats en selectionnant uniquement les requêtes de type XHR.
Dans le peu de requêtes restantes, il y en a une Data , et c'est elle qui détient l'information qui t'intéresse.

"data":[{"ID_Produit":561617,

Hors ligne

#4 Le 17/06/2021, à 14:20

jplemoine

Re : [Python][Request] Comment parser une page HTML avec le RGPD ?

Surtout que je ne vois pas ce que le RGPD vient faire là-dedans...
Sauf erreur de ma part : une correspondance ID - libellé d'un produit n'est pas une donnée personnelle sauf s'il y a des données personnelles dans le libellé mais dans ce cas-là, une automatisation est interdite sauf accord explicite de l'intéressé et je crois me souvenir que sans cet accord, tu risques gros (plusieurs milliers d'euros et plusieurs années de prison).


Membre de l'ALDIL (Association Lyonnaise pour le Développement de l'Informatique Libre)
- En pro, après 20 ans de développement, administrateur Linux / Unix depuis Avril 2019.
- En privé, sous Ubuntu-Xubuntu depuis 2009.

Hors ligne

#5 Le 17/06/2021, à 14:43

alex2423

Re : [Python][Request] Comment parser une page HTML avec le RGPD ?

Salut Vobul,

Vobul a écrit :

Est-ce que c'est obligé de passer par Quantalys. Quelle est la finalité ? Parce que je suis sûr qu'il y a des sites qui proposent une API REST pour ce genre de choses, bien plus simple que parser du html avec le javascript activé, les cookies et tout le tralala.

La finalité finale est de récupérer les frais courant du titre.
Je souhaitais à partir du code ISIN récupérer le numéro produits (qui doit être un code interne) puis ensuite aller sur la page du produit.
Par exemple https://www.quantalys.com/Fonds/561617
Et ensuite récupérer les frais courants qui s'élèvent ici à 0.25% (dans le bloc Caractéristiques générales).

Pour parser du HTML, je trouve cela extrêmement simple avec BeautifullSoup mais en effet, tu as raison, il faut garder en tête que certaines données peuvent être chargées dans un second temps avec du javascript, ce qui posait problème pour parser.

Ce n'est pas obligé de passer par Quantalys mais cette information est loin d'être évidente à récupérer. Yahoo Finance ne le fournit pas par exemple. Je n'ai pas réussi à trouver autre part.



soshy a écrit :

Bien tenté, mais c'est perdu tongue
C'est pas le RGPD ton problème smile

Ton problème, c'est le web moderne, qui envoi un bout de page, puis le javascript fait des requêtes supplémentaires pour récupérer plus de données et les ajouter à la page initialement chargée. Au lieu de regarder l'onglet storage, vas sur network. Là, tu recharges la page et tu filtres les résultats en selectionnant uniquement les requêtes de type XHR.
Dans le peu de requêtes restantes, il y en a une Data , et c'est elle qui détient l'information qui t'intéresse.

"data":[{"ID_Produit":561617,

Merci bien pour le conseil soshy.

Exact, il y a un superbe requête qui permettrait de récupérer les informations au format JSon avec ID_Produit":561617. Sous Firefox, il est possible de modifier le header avant de ré-envoyer la requête, j'ai viré les cookies dans le header de la requête, et en effet, hourra, le résultat est tout de même retourné. smile

La requête est du "post"  avec pas moins de 186 paramètres !!! J'ai repris exactement les mêmes paramètres que dans Firefox. J'ai les paramètres en mode brut, puis un bête copié collé pour faire un premier test en Python mais sans succès. Le HTML retourné n'est pas le bon. 

import requests
session = requests.Session()

data = "draw=2&columns%5B0%5D%5Bname%5D=ID_Produit&columns%5B1%5D%5Bname%5D=cTypeFinancialItem&columns%5B2%5D%5Bname%5D=cClasseFinancialItem&columns%5B3%5D%5Bname%5D=sTypeFinancialObject&columns%5B4%5D%5Bname%5D=checkbox&columns%5B5%5D%5Bname%5D=sNom&columns%5B6%5D%5Bname%5D=sURL&columns%5B7%5D%5Bname%5D=sNomManager&columns%5B8%5D%5Bname%5D=sNomTypeFinancialObject&columns%5B9%5D%5Bname%5D=sGroupeCat_Specific_Dynamic&columns%5B10%5D%5Bname%5D=sGroupeCat_rng1&columns%5B11%5D%5Bname%5D=sCodeISIN&columns%5B12%5D%5Bname%5D=nVL&columns%5B13%5D%5Bname%5D=sCurrency&columns%5B14%5D%5Bname%5D=nStarRating&columns%5B15%5D%5Bname%5D=nScore&columns%5B16%5D%5Bname%5D=nRetYTD&columns%5B17%5D%5Bname%5D=nRet1a&columns%5B18%5D%5Bname%5D=nRet3a&columns%5B19%5D%5Bname%5D=nRet5a&columns%5B20%5D%5Bname%5D=nRet1c&columns%5B21%5D%5Bname%5D=nRet3c&columns%5B22%5D%5Bname%5D=nRet1j&columns%5B23%5D%5Bname%5D=nRet1m&columns%5B24%5D%5Bname%5D=nRet3m&columns%5B25%5D%5Bname%5D=nRet6m&columns%5B26%5D%5Bname%5D=nRet5c&columns%5B27%5D%5Bname%5D=nRet8c&columns%5B28%5D%5Bname%5D=nVolat1a&columns%5B29%5D%5Bname%5D=nVolat3a&columns%5B30%5D%5Bname%5D=nVolat5a&columns%5B31%5D%5Bname%5D=nSharpe1a&columns%5B32%5D%5Bname%5D=nSharpe3a&columns%5B33%5D%5Bname%5D=nSharpe5a&columns%5B34%5D%5Bname%5D=nPerteMax1a&columns%5B35%5D%5Bname%5D=nPerteMax3a&columns%5B36%5D%5Bname%5D=nPerteMax5a&columns%5B37%5D%5Bname%5D=nSortino1a&columns%5B38%5D%5Bname%5D=nSortino3a&columns%5B39%5D%5Bname%5D=nSortino5a&columns%5B40%5D%5Bname%5D=nIr1A&columns%5B41%5D%5Bname%5D=nIr3A&columns%5B42%5D%5Bname%5D=nIr5A&columns%5B43%5D%5Bname%5D=nMinInvest&columns%5B44%5D%5Bname%5D=nFraisGestion&columns%5B45%5D%5Bname%5D=nFraisEntree&columns%5B46%5D%5Bname%5D=nFraisSortie&columns%5B47%5D%5Bname%5D=dtRet&columns%5B48%5D%5Bname%5D=dtRetMonth&columns%5B49%5D%5Bname%5D=bFerme&columns%5B50%5D%5Bname%5D=nIntensiteESG&columns%5B51%5D%5Bname%5D=nActifEur&columns%5B52%5D%5Bname%5D=nActifDiffEUR1m&columns%5B53%5D%5Bname%5D=nActifDiffEUR3m&columns%5B54%5D%5Bname%5D=nActifDiffEUR6m&columns%5B55%5D%5Bname%5D=nActifDiffEUR1A&columns%5B56%5D%5Bname%5D=nActifCompartimentEUR&columns%5B57%5D%5Bname%5D=nActifCompartimentDiffEUR1m&columns%5B58%5D%5Bname%5D=nActifCompartimentDiffEUR3m&columns%5B59%5D%5Bname%5D=nActifCompartimentDiffEUR6m&columns%5B60%5D%5Bname%5D=nActifCompartimentDiffEUR1A&columns%5B61%5D%5Bname%5D=nCollecteCompartiment1m&columns%5B62%5D%5Bname%5D=nCollecteCompartiment3m&columns%5B63%5D%5Bname%5D=nCollecteCompartiment6m&columns%5B64%5D%5Bname%5D=nCollecteCompartimentYTD&columns%5B65%5D%5Bname%5D=nCollecteCompartiment1A&columns%5B66%5D%5Bname%5D=nCollecteCompartiment3A&columns%5B67%5D%5Bname%5D=nCollecteRet1m&columns%5B68%5D%5Bname%5D=nCollecteRet3m&columns%5B69%5D%5Bname%5D=nCollecteRet6m&columns%5B70%5D%5Bname%5D=nCollecteRetYTD&columns%5B71%5D%5Bname%5D=nCollecteRet1A&columns%5B72%5D%5Bname%5D=nCollecteRet3A&columns%5B73%5D%5Bname%5D=nCollecteCompartimentRet1m&columns%5B74%5D%5Bname%5D=nCollecteCompartimentRet3m&columns%5B75%5D%5Bname%5D=nCollecteCompartimentRet6m&columns%5B76%5D%5Bname%5D=nCollecteCompartimentRetYTD&columns%5B77%5D%5Bname%5D=nCollecteCompartimentRet1A&columns%5B78%5D%5Bname%5D=nCollecteCompartimentRet3A&columns%5B79%5D%5Bname%5D=isESG&columns%5B80%5D%5Bname%5D=sArticleSFDR&columns%5B81%5D%5Bname%5D=nIntensiteISR&columns%5B82%5D%5Bname%5D=nESG_Environnement&columns%5B83%5D%5Bname%5D=nESG_Social&columns%5B84%5D%5Bname%5D=nESG_Gouvernance&columns%5B85%5D%5Bname%5D=nLabels&columns%5B86%5D%5Bname%5D=sProspectusUrl&columns%5B87%5D%5Bname%5D=sUrlMainDocument&columns%5B88%5D%5Bname%5D=isMainDocumentAccessible&order%5B0%5D%5Bcolumn%5D=5&order%5B0%5D%5Bdir%5D=asc&start=0&length=10&search%5Bvalue%5D=&search%5Bregex%5D=false&nbMaxCompare=5&Values.sNomOrISIN=LU1681048630&chkTypeProduits=1&Values.bETF=true&Values.isTypeProduitV2=true&Values.sDevise=&Values.nAge=&Values.sDomicile=&Values.nTypeFonds=&Values.nTypeInvestisseur=&Values.nDistribution=&Values.nAMF=&Values.bExcludeUncommercialized=true&Values.perfAnnu.dateIndex=0&Values.perfAnnu.signe=ge&Values.perfAnnu.value=&Values.perfCumulee.sDate=0&Values.perfCumulee.signe=ge&Values.perfCumulee.value=&Values.superfAnnu.dateIndex=0&Values.superfAnnu.signe=le&Values.superfAnnu.value=&Values.sharpe.dateIndex=0&Values.sharpe.signe=ge&Values.sharpe.value=&Values.volat.dateIndex=0&Values.volat.signe=le&Values.volat.value=&Values.perteMax.dateIndex=0&Values.perteMax.signe=le&Values.perteMax.value=&Values.beta.dateIndex=0&Values.beta.signe=le&Values.beta.value=&Values.ecartSuivi.dateIndex=0&Values.ecartSuivi.signe=le&Values.ecartSuivi.value=&Values.IR.dateIndex=0&Values.IR.signe=le&Values.IR.value=&Values.sortino.dateIndex=0&Values.sortino.signe=le&Values.sortino.value=&Values.ratioOmega.dateIndex=0&Values.ratioOmega.signe=le&Values.ratioOmega.value=&Values.betaHaussier.dateIndex=0&Values.betaHaussier.signe=le&Values.betaHaussier.value=&Values.betaBaissier.dateIndex=0&Values.betaBaissier.signe=le&Values.betaBaissier.value=&Values.upCaptureRatio.dateIndex=0&Values.upCaptureRatio.signe=le&Values.upCaptureRatio.value=&Values.downCaptureRatio.dateIndex=0&Values.downCaptureRatio.signe=le&Values.downCaptureRatio.value=&Values.DSR.dateIndex=0&Values.DSR.signe=le&Values.DSR.value=&Values.var95.dateIndex=0&Values.var95.signe=le&Values.var95.value=&Values.var99.dateIndex=0&Values.var99.signe=le&Values.var99.value=&Values.skewness.dateIndex=0&Values.skewness.signe=le&Values.skewness.value=&Values.kurtosis.dateIndex=0&Values.kurtosis.signe=le&Values.kurtosis.value=&Values.fraisSouscription.Signe=le&Values.fraisSouscription.Value=&Values.fraisRachat.Signe=le&Values.fraisRachat.Value=&Values.fraisGestion.Signe=le&Values.fraisGestion.Value=&Values.fraisCourants.Signe=le&Values.fraisCourants.Value=&Values.ESG.isEnvironnement=&Values.ESG.isSocial=&Values.ESG.isGouvernance=&Values.isIntersectionContrats=false&Values.lstIdProduits%5B%5D=1&lstIdProduits%5B%5D=1&sNomOrISIN=LU1681048630&Values.isForProposition=false"

url = "https://www.quantalys.com/Recherche?search=LU1681048630"
headers = {"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"}

response = session.post(url, data=data, headers=headers)
print(response.text)

J'ai essayé en passant les paramètres au format dictionnaire, mais pas mieux :

data ={
"columns[54][name]":"nActifDiffEUR6m",
"columns[55][name]":"nActifDiffEUR1A",
"columns[56][name]":"nActifCompartimentEUR",
"columns[57][name]":"nActifCompartimentDiffEUR1m",
"columns[58][name]":"nActifCompartimentDiffEUR3m",
"columns[59][name]":"nActifCompartimentDiffEUR6m",
"columns[60][name]":"nActifCompartimentDiffEUR1A",
"columns[61][name]":"nCollecteCompartiment1m",
"columns[62][name]":"nCollecteCompartiment3m",
"columns[63][name]":"nCollecteCompartiment6m",
"columns[64][name]":"nCollecteCompartimentYTD",
"columns[65][name]":"nCollecteCompartiment1A",
"columns[66][name]":"nCollecteCompartiment3A",
"columns[67][name]":"nCollecteRet1m",
"columns[68][name]":"nCollecteRet3m",
"columns[69][name]":"nCollecteRet6m",
"columns[70][name]":"nCollecteRetYTD",
"columns[71][name]":"nCollecteRet1A",
"columns[72][name]":"nCollecteRet3A",
"columns[73][name]":"nCollecteCompartimentRet1m",
"columns[74][name]":"nCollecteCompartimentRet3m",
"columns[75][name]":"nCollecteCompartimentRet6m",
"columns[76][name]":"nCollecteCompartimentRetYTD",
"columns[77][name]":"nCollecteCompartimentRet1A",
"columns[78][name]":"nCollecteCompartimentRet3A",
"columns[79][name]":"isESG",
"columns[80][name]":"sArticleSFDR",
"columns[81][name]":"nIntensiteISR",
"columns[82][name]":"nESG_Environnement",
"columns[83][name]":"nESG_Social",
"columns[84][name]":"nESG_Gouvernance",
"columns[85][name]":"nLabels",
"columns[86][name]":"sProspectusUrl",
"columns[87][name]":"sUrlMainDocument",
"columns[88][name]":"isMainDocumentAccessible",
"order[0][column]":"5",
"order[0][dir]":"asc",
"start":"0",
"length":"10",
"search[value]":"",
"search[regex]":"false",
"nbMaxCompare":"5",
"Values.sNomOrISIN":"LU1681048630",
"chkTypeProduits":"1",
"Values.bETF":"true",
"Values.isTypeProduitV2":"true",
"Values.sDevise":"",
"Values.nAge":"",
"Values.sDomicile":"",
"Values.nTypeFonds":"",
"Values.nTypeInvestisseur":"",
"Values.nDistribution":"",
"Values.nAMF":"",
"Values.bExcludeUncommercialized":"true",
"Values.perfAnnu.dateIndex":"0",
"Values.perfAnnu.signe":"ge",
"Values.perfAnnu.value":"",
"Values.perfCumulee.sDate":"0",
"Values.perfCumulee.signe":"ge",
"Values.perfCumulee.value":"",
"Values.superfAnnu.dateIndex":"0",
"Values.superfAnnu.signe":"le",
"Values.superfAnnu.value":"",
"Values.sharpe.dateIndex":"0",
"Values.sharpe.signe":"ge",
"Values.sharpe.value":"",
"Values.volat.dateIndex":"0",
"Values.volat.signe":"le",
"Values.volat.value":"",
"Values.perteMax.dateIndex":"0",
"Values.perteMax.signe":"le",
"Values.perteMax.value":"",
"Values.beta.dateIndex":"0",
"Values.beta.signe":"le",
"Values.beta.value":"",
"Values.ecartSuivi.dateIndex":"0",
"Values.ecartSuivi.signe":"le",
"Values.ecartSuivi.value":"",
"Values.IR.dateIndex":"0",
"Values.IR.signe":"le",
"Values.IR.value":"",
"Values.sortino.dateIndex":"0",
"Values.sortino.signe":"le",
"Values.sortino.value":"",
"Values.ratioOmega.dateIndex":"0",
"Values.ratioOmega.signe":"le",
"Values.ratioOmega.value":"",
"Values.betaHaussier.dateIndex":"0",
"Values.betaHaussier.signe":"le",
"Values.betaHaussier.value":"",
"Values.betaBaissier.dateIndex":"0",
"Values.betaBaissier.signe":"le",
"Values.betaBaissier.value":"",
"Values.upCaptureRatio.dateIndex":"0",
"Values.upCaptureRatio.signe":"le",
"Values.upCaptureRatio.value":"",
"Values.downCaptureRatio.dateIndex":"0",
"Values.downCaptureRatio.signe":"le",
"Values.downCaptureRatio.value":"",
"Values.DSR.dateIndex":"0",
"Values.DSR.signe":"le",
"Values.DSR.value":"",
"Values.var95.dateIndex":"0",
"Values.var95.signe":"le",
"Values.var95.value":"",
"Values.var99.dateIndex":"0",
"Values.var99.signe":"le",
"Values.var99.value":"",
"Values.skewness.dateIndex":"0",
"Values.skewness.signe":"le",
"Values.skewness.value":"",
"Values.kurtosis.dateIndex":"0",
"Values.kurtosis.signe":"le",
"Values.kurtosis.value":"",
"Values.fraisSouscription.Signe":"le",
"Values.fraisSouscription.Value":"",
"Values.fraisRachat.Signe":"le",
"Values.fraisRachat.Value":"",
"Values.fraisGestion.Signe":"le",
"Values.fraisGestion.Value":"",
"Values.fraisCourants.Signe":"le",
"Values.fraisCourants.Value":"",
"Values.ESG.isEnvironnement":"",
"Values.ESG.isSocial":"",
"Values.ESG.isGouvernance":"",
"Values.isIntersectionContrats":"false",
"Values.lstIdProduits[]":"1",
"lstIdProduits[]":"1",
"sNomOrISIN":"LU1681048630",
"Values.isForProposition":"false",
"draw":"2",
"columns[0][name]":"ID_Produit",
"columns[1][name]":"cTypeFinancialItem",
"columns[2][name]":"cClasseFinancialItem",
"columns[3][name]":"sTypeFinancialObject",
"columns[4][name]":"checkbox",
"columns[5][name]":"sNom",
"columns[6][name]":"sURL",
"columns[7][name]":"sNomManager",
"columns[8][name]":"sNomTypeFinancialObject",
"columns[9][name]":"sGroupeCat_Specific_Dynamic",
"columns[10][name]":"sGroupeCat_rng1",
"columns[11][name]":"sCodeISIN",
"columns[12][name]":"nVL",
"columns[13][name]":"sCurrency",
"columns[14][name]":"nStarRating",
"columns[15][name]":"nScore",
"columns[16][name]":"nRetYTD",
"columns[17][name]":"nRet1a",
"columns[18][name]":"nRet3a",
"columns[19][name]":"nRet5a",
"columns[20][name]":"nRet1c",
"columns[21][name]":"nRet3c",
"columns[22][name]":"nRet1j",
"columns[23][name]":"nRet1m",
"columns[24][name]":"nRet3m",
"columns[25][name]":"nRet6m",
"columns[26][name]":"nRet5c",
"columns[27][name]":"nRet8c",
"columns[28][name]":"nVolat1a",
"columns[29][name]":"nVolat3a",
"columns[30][name]":"nVolat5a",
"columns[31][name]":"nSharpe1a",
"columns[32][name]":"nSharpe3a",
"columns[33][name]":"nSharpe5a",
"columns[34][name]":"nPerteMax1a",
"columns[35][name]":"nPerteMax3a",
"columns[36][name]":"nPerteMax5a",
"columns[37][name]":"nSortino1a",
"columns[38][name]":"nSortino3a",
"columns[39][name]":"nSortino5a",
"columns[40][name]":"nIr1A",
"columns[41][name]":"nIr3A",
"columns[42][name]":"nIr5A",
"columns[43][name]":"nMinInvest",
"columns[44][name]":"nFraisGestion",
"columns[45][name]":"nFraisEntree",
"columns[46][name]":"nFraisSortie",
"columns[47][name]":"dtRet",
"columns[48][name]":"dtRetMonth",
"columns[49][name]":"bFerme",
"columns[50][name]":"nIntensiteESG",
"columns[51][name]":"nActifEur",
"columns[52][name]":"nActifDiffEUR1m",
"columns[53][name]":"nActifDiffEUR3m"
}
response = session.post(url, data=data, headers=headers, )
print(response.text)

Hors ligne

#6 Le 17/06/2021, à 15:29

Vobul

Re : [Python][Request] Comment parser une page HTML avec le RGPD ?

C'est le request header Content-Type qui est important. Si tu l'enlèves -> erreur 500 !


Vobul

Utilisez le retour utilisable de commandes !!!
J'aime la langue française, mais je parle franglais, deal with it.

Hors ligne

#7 Le 24/06/2021, à 08:10

alex2423

Re : [Python][Request] Comment parser une page HTML avec le RGPD ?

Bon je suis content, j'ai réussi à trouver la requête. Malgré l'ajout du Content-Type, cela ne voulait toujours pas fonctionner.

Sous Firefox, il est possible de récupérer la commande CURL complète avec tous les paramètres. Je l'ai lancé dans un terminal et cela fonctionnait bien.

Et ensuite j'ai trouvé un site qui permet de convertir l'équivalent avec Request en Python
https://curl.trillworks.com/#json

import requests
headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0',
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
}

data = {
  'draw': '2',
  'columns[0][name]': 'ID_Produit',
  'columns[1][name]': 'cTypeFinancialItem',
  'columns[2][name]': 'cClasseFinancialItem',
  'columns[3][name]': 'sTypeFinancialObject',
  'columns[4][name]': 'checkbox',
  'columns[5][name]': 'sNom',
  'columns[6][name]': 'sURL',
  'columns[7][name]': 'sNomManager',
  'columns[8][name]': 'sNomTypeFinancialObject',
  'columns[9][name]': 'sGroupeCat_Specific_Dynamic',
  'columns[10][name]': 'sGroupeCat_rng1',
  'columns[11][name]': 'sCodeISIN',
  'columns[12][name]': 'nVL',
  'columns[13][name]': 'sCurrency',
  'columns[14][name]': 'nStarRating',
  'columns[15][name]': 'nScore',
  'columns[16][name]': 'nRetYTD',
  'columns[17][name]': 'nRet1a',
  'columns[18][name]': 'nRet3a',
  'columns[19][name]': 'nRet5a',
  'columns[20][name]': 'nRet1c',
  'columns[21][name]': 'nRet3c',
  'columns[22][name]': 'nRet1j',
  'columns[23][name]': 'nRet1m',
  'columns[24][name]': 'nRet3m',
  'columns[25][name]': 'nRet6m',
  'columns[26][name]': 'nRet5c',
  'columns[27][name]': 'nRet8c',
  'columns[28][name]': 'nVolat1a',
  'columns[29][name]': 'nVolat3a',
  'columns[30][name]': 'nVolat5a',
  'columns[31][name]': 'nSharpe1a',
  'columns[32][name]': 'nSharpe3a',
  'columns[33][name]': 'nSharpe5a',
  'columns[34][name]': 'nPerteMax1a',
  'columns[35][name]': 'nPerteMax3a',
  'columns[36][name]': 'nPerteMax5a',
  'columns[37][name]': 'nSortino1a',
  'columns[38][name]': 'nSortino3a',
  'columns[39][name]': 'nSortino5a',
  'columns[40][name]': 'nIr1A',
  'columns[41][name]': 'nIr3A',
  'columns[42][name]': 'nIr5A',
  'columns[43][name]': 'nMinInvest',
  'columns[44][name]': 'nFraisGestion',
  'columns[45][name]': 'nFraisEntree',
  'columns[46][name]': 'nFraisSortie',
  'columns[47][name]': 'dtRet',
  'columns[48][name]': 'dtRetMonth',
  'columns[49][name]': 'bFerme',
  'columns[50][name]': 'nIntensiteESG',
  'columns[51][name]': 'nActifEur',
  'columns[52][name]': 'nActifDiffEUR1m',
  'columns[53][name]': 'nActifDiffEUR3m',
  'columns[54][name]': 'nActifDiffEUR6m',
  'columns[55][name]': 'nActifDiffEUR1A',
  'columns[56][name]': 'nActifCompartimentEUR',
  'columns[57][name]': 'nActifCompartimentDiffEUR1m',
  'columns[58][name]': 'nActifCompartimentDiffEUR3m',
  'columns[59][name]': 'nActifCompartimentDiffEUR6m',
  'columns[60][name]': 'nActifCompartimentDiffEUR1A',
  'columns[61][name]': 'nCollecteCompartiment1m',
  'columns[62][name]': 'nCollecteCompartiment3m',
  'columns[63][name]': 'nCollecteCompartiment6m',
  'columns[64][name]': 'nCollecteCompartimentYTD',
  'columns[65][name]': 'nCollecteCompartiment1A',
  'columns[66][name]': 'nCollecteCompartiment3A',
  'columns[67][name]': 'nCollecteRet1m',
  'columns[68][name]': 'nCollecteRet3m',
  'columns[69][name]': 'nCollecteRet6m',
  'columns[70][name]': 'nCollecteRetYTD',
  'columns[71][name]': 'nCollecteRet1A',
  'columns[72][name]': 'nCollecteRet3A',
  'columns[73][name]': 'nCollecteCompartimentRet1m',
  'columns[74][name]': 'nCollecteCompartimentRet3m',
  'columns[75][name]': 'nCollecteCompartimentRet6m',
  'columns[76][name]': 'nCollecteCompartimentRetYTD',
  'columns[77][name]': 'nCollecteCompartimentRet1A',
  'columns[78][name]': 'nCollecteCompartimentRet3A',
  'columns[79][name]': 'isESG',
  'columns[80][name]': 'sArticleSFDR',
  'columns[81][name]': 'nIntensiteISR',
  'columns[82][name]': 'nESG_Environnement',
  'columns[83][name]': 'nESG_Social',
  'columns[84][name]': 'nESG_Gouvernance',
  'columns[85][name]': 'nNbLabels',
  'columns[86][name]': 'sProspectusUrl',
  'columns[87][name]': 'sUrlMainDocument',
  'columns[88][name]': 'isMainDocumentAccessible',
  'order[0][column]': '5',
  'order[0][dir]': 'asc',
  'start': '0',
  'length': '10',
  'search[value]': '',
  'search[regex]': 'false',
  'nbMaxCompare': '5',
  'Values.sNomOrISIN': 'LU1681048630',
  'chkTypeProduits': '1',
  'Values.bETF': 'true',
  'Values.isTypeProduitV2': 'true',
  'Values.sDevise': '',
  'Values.nAge': '',
  'Values.sDomicile': '',
  'Values.nTypeFonds': '',
  'Values.nTypeInvestisseur': '',
  'Values.nDistribution': '',
  'Values.nAMF': '',
  'Values.bExcludeUncommercialized': 'true',
  'Values.perfAnnu.dateIndex': '0',
  'Values.perfAnnu.signe': 'ge',
  'Values.perfAnnu.value': '',
  'Values.perfCumulee.sDate': '0',
  'Values.perfCumulee.signe': 'ge',
  'Values.perfCumulee.value': '',
  'Values.superfAnnu.dateIndex': '0',
  'Values.superfAnnu.signe': 'le',
  'Values.superfAnnu.value': '',
  'Values.sharpe.dateIndex': '0',
  'Values.sharpe.signe': 'ge',
  'Values.sharpe.value': '',
  'Values.volat.dateIndex': '0',
  'Values.volat.signe': 'le',
  'Values.volat.value': '',
  'Values.perteMax.dateIndex': '0',
  'Values.perteMax.signe': 'le',
  'Values.perteMax.value': '',
  'Values.beta.dateIndex': '0',
  'Values.beta.signe': 'le',
  'Values.beta.value': '',
  'Values.ecartSuivi.dateIndex': '0',
  'Values.ecartSuivi.signe': 'le',
  'Values.ecartSuivi.value': '',
  'Values.IR.dateIndex': '0',
  'Values.IR.signe': 'le',
  'Values.IR.value': '',
  'Values.sortino.dateIndex': '0',
  'Values.sortino.signe': 'le',
  'Values.sortino.value': '',
  'Values.ratioOmega.dateIndex': '0',
  'Values.ratioOmega.signe': 'le',
  'Values.ratioOmega.value': '',
  'Values.betaHaussier.dateIndex': '0',
  'Values.betaHaussier.signe': 'le',
  'Values.betaHaussier.value': '',
  'Values.betaBaissier.dateIndex': '0',
  'Values.betaBaissier.signe': 'le',
  'Values.betaBaissier.value': '',
  'Values.upCaptureRatio.dateIndex': '0',
  'Values.upCaptureRatio.signe': 'le',
  'Values.upCaptureRatio.value': '',
  'Values.downCaptureRatio.dateIndex': '0',
  'Values.downCaptureRatio.signe': 'le',
  'Values.downCaptureRatio.value': '',
  'Values.DSR.dateIndex': '0',
  'Values.DSR.signe': 'le',
  'Values.DSR.value': '',
  'Values.var95.dateIndex': '0',
  'Values.var95.signe': 'le',
  'Values.var95.value': '',
  'Values.var99.dateIndex': '0',
  'Values.var99.signe': 'le',
  'Values.var99.value': '',
  'Values.skewness.dateIndex': '0',
  'Values.skewness.signe': 'le',
  'Values.skewness.value': '',
  'Values.kurtosis.dateIndex': '0',
  'Values.kurtosis.signe': 'le',
  'Values.kurtosis.value': '',
  'Values.fraisSouscription.Signe': 'le',
  'Values.fraisSouscription.Value': '',
  'Values.fraisRachat.Signe': 'le',
  'Values.fraisRachat.Value': '',
  'Values.fraisGestion.Signe': 'le',
  'Values.fraisGestion.Value': '',
  'Values.fraisCourants.Signe': 'le',
  'Values.fraisCourants.Value': '',
  'Values.ESG.isEnvironnement': '',
  'Values.ESG.isSocial': '',
  'Values.ESG.isGouvernance': '',
  'Values.isIntersectionContrats': 'false',
  'Values.lstIdProduits[]': '1',
  'lstIdProduits[]': '1',
  'sNomOrISIN': 'LU1681048630',
  'Values.isForProposition': 'false'
}

response = requests.post('https://www.quantalys.com/Recherche/Data', headers=headers, data=data)

print(response.text)

Et cela fonctionne cette fois-ci smile

Hors ligne