|
| 1 | +Title: Présentation de la librairie requests |
| 2 | +Date: 2019-01-31 16:00 |
| 3 | +Modified: 2019-01-31 16:00 |
| 4 | +Category: Tutoriels |
| 5 | +Tags: requests |
| 6 | +Slug: presentation-requests |
| 7 | +Author: Cédric Migazzi |
| 8 | + |
| 9 | +# Présentation de la librairie requests. |
| 10 | + |
| 11 | +### Présentation |
| 12 | + |
| 13 | +`requests` est une librairie Python qui permet de gérer facilement les requêtes HTTP. Elle utilise la librairie standard `urllib3` et en simplifie l'utilisation pour la rendre plus "humaine" ([*HTTP for humans*](http://docs.python-requests.org/en/master/)). |
| 14 | + |
| 15 | +Pour cet article, nous allons voir un usage basique de dialogue avec l'API d'[OpenFoodFacts](https://fr.openfoodfacts.org/). |
| 16 | + |
| 17 | +>*"OpenFoodFacts est une base de données sur les produits alimentaires faite par tout le monde, pour tout le monde"* |
| 18 | +> |
| 19 | +Le site dispose d’une API dont la documentation se trouve [ici](https://en.wiki.openfoodfacts.org/API). Il est ainsi possible de faire toutes sortes de recherches, de récupérer les données avec `requests` et de les exploiter avec Python. |
| 20 | + |
| 21 | +### Installation |
| 22 | +`pipenv install requests` |
| 23 | + |
| 24 | +### Une simple requête |
| 25 | + |
| 26 | +Pour réaliser une requête: |
| 27 | + |
| 28 | +avec `urllib3`... |
| 29 | +``` |
| 30 | +import urllib3 |
| 31 | +
|
| 32 | +http = PoolManager() |
| 33 | +res = http.request("GET", "https://fr.openfoodfacts.org/") |
| 34 | +``` |
| 35 | +... et pour obtenir le même résultat avec `requests`: |
| 36 | +``` |
| 37 | +import requests |
| 38 | +
|
| 39 | +res = requests.get("https://fr.openfoodfacts.org/ ") |
| 40 | +``` |
| 41 | +C'est effectivement beaucoup plus simple, mais que se passe-t-il ? |
| 42 | + |
| 43 | +Dans les 2 cas, `res` contient la réponse du serveur HTTP. |
| 44 | + |
| 45 | +Avec `requests`, l’import de `http` et l’instanciation de `PoolManager()` est transparent pour l’utilisateur, ce qui économise du code. Les méthodes HTTP sont des méthodes de `requests` au lieu d'être des paramètres dans `urllib3`. |
| 46 | + |
| 47 | +On peut aussi faire de même avec les autres méthodes HTTP : |
| 48 | +``` |
| 49 | +res = request.post("https://mon-url.de/post", data={key:value}) |
| 50 | +res = request.put("https://mon-url.de/put", data={key:value}) |
| 51 | +res = request.delete("https://mon-url.de/delete") |
| 52 | +res = request.head("https://mon-url.de/get") |
| 53 | +res = request.head("https://mon-url.de/get") |
| 54 | +``` |
| 55 | + |
| 56 | +**Et qu'est-ce qu'on en fait ?** |
| 57 | + |
| 58 | +`requests` renvoie un objet `Response` qui possède les attributs suivants: |
| 59 | +``` |
| 60 | +# le code HTTP de la réponse |
| 61 | +>>> res.status_code |
| 62 | +200 |
| 63 | +
|
| 64 | +# l'url |
| 65 | +>>> res.url |
| 66 | +'https://fr.openfoodfacts.org/' |
| 67 | +
|
| 68 | +# les headers HTTP. |
| 69 | +>>> res.headers # dictionnaire |
| 70 | +
|
| 71 | +#l'encodage |
| 72 | +>>> res.encoding |
| 73 | +'UTF-8' |
| 74 | +``` |
| 75 | +Et quelques méthodes de base: |
| 76 | + |
| 77 | +``` |
| 78 | +# le code html |
| 79 | +>>> res.text # chaine de charactère |
| 80 | +
|
| 81 | +# Si la réponse est au format json, on peut la convertir en dictionnaire |
| 82 | +>>> res.json() |
| 83 | +``` |
| 84 | + |
| 85 | +### Un premier exemple: |
| 86 | + |
| 87 | +Petit exemple avec du Nutella que l’on peut retrouver grâce à son code barre : 3017620425400. |
| 88 | +``` |
| 89 | +>>>res = requests.get("https://world.openfoodfacts.org/api/v0/product/3017620425400.json") |
| 90 | +``` |
| 91 | +Comme la réponse est au format json, on peut le transformer en dictionnaire: |
| 92 | +``` |
| 93 | +>>>results = res.json() |
| 94 | +
|
| 95 | +# voir toutes les clés |
| 96 | +>>>results.keys() |
| 97 | +dict_keys(['code', 'status_verbose', 'product', 'status']) |
| 98 | +
|
| 99 | +# faire un dictionnaire du produit |
| 100 | +>>> product = results["product"] |
| 101 | +
|
| 102 | +# voir le nombre d'attributs du produit |
| 103 | +>>> len(prodcut) |
| 104 | +191 |
| 105 | +
|
| 106 | +# et par exemple, voir les catégories qui lui sont associé |
| 107 | +>>>product["categories"] |
| 108 | +'Petit-déjeuners, Produits à tartiner, Produits à tartiner sucrés, Pâtes à tartiner, Pâtes à tartiner au chocolat, Pâtes à tartiner aux noisettes et au cacao, Pâtes à tartiner aux noisettes' |
| 109 | +``` |
| 110 | + |
| 111 | +### Ajouter des paramètres |
| 112 | + |
| 113 | +Pour des requêtes plus claires, il est possible de passer une liste d'objets clé/valeur en paramètre de la requête. |
| 114 | + |
| 115 | +Avec l'API d'OpenFoodFacts, il est possible de le mettre en pratique grâce à son url de recherche: |
| 116 | + |
| 117 | +*Vous trouverez toutes les options de recherche sur la [doc officielle](https://en.wiki.openfoodfacts.org/API/Read/Search#Parameters)* |
| 118 | + |
| 119 | +``` |
| 120 | +>>>payload = {"search_terms": "Lindt, "json":1} |
| 121 | +>>>res = requests.get("https://fr.openfoodfacts.org/cgi/search.pl?", params=payload) |
| 122 | +
|
| 123 | +# Pour voir l'url correspondante |
| 124 | +>>>res.url |
| 125 | +'https://fr.openfoodfacts.org/cgi/search.pl?search_terms=Lindt&json=1' |
| 126 | +
|
| 127 | +# pour voir le nombre de résultats |
| 128 | +>>> results = res.json() |
| 129 | +>>> results["count"] |
| 130 | +802 |
| 131 | +``` |
| 132 | +Si on veut retrouver les 50 produits les plus populaires de la marque Lindt, on pourra faire: |
| 133 | +``` |
| 134 | +>>>payload = {"search_terms": "Lindt", |
| 135 | +... "search_tag": "brands", |
| 136 | +... "sort_by": "unique_scans_n", |
| 137 | +... "page_size": 50, |
| 138 | +... "json": 1} |
| 139 | +>>>res = requests.get("https://fr.openfoodfacts.org/cgi/search.pl?", params=payload) |
| 140 | +
|
| 141 | +# l'url correspondante |
| 142 | +>>>res.url |
| 143 | +'https://fr.openfoodfacts.org/cgi/search.pl?search_terms=Lindt&search_tag=brands&sort_by=unique_scans_n&page_size=50&json=1' |
| 144 | +
|
| 145 | +# on peut ensuite récupérer les produits |
| 146 | +>>>results = res.json() |
| 147 | +>>>products = results["products"] |
| 148 | + |
| 149 | +# Et afficher leurs noms |
| 150 | +>>>for product in products: |
| 151 | + print(product["product_name"]) |
| 152 | +``` |
| 153 | +### Pour aller plus loin |
| 154 | + |
| 155 | +Nous avons vu un usage basique de `requests`, mais il est aussi possible de: |
| 156 | + |
| 157 | +- vérifier si la réponse HTTP est valide: |
| 158 | +``` |
| 159 | +>>> res = requests.get('https://fr.openfoodfacts.org') |
| 160 | +>>> res.status_code == requests.codes.ok |
| 161 | +True |
| 162 | +``` |
| 163 | +- voir et gérer les redirections (HTTP vers HTTPS) avec l'attribut `history`: |
| 164 | + |
| 165 | +``` |
| 166 | +res = requests.get("http://fr.openfoodfacts.org/") |
| 167 | +>>> res.status_code |
| 168 | +200 |
| 169 | +>>> res.history |
| 170 | +[<Response [301]>] |
| 171 | +
|
| 172 | +# Poosibilité de désactiver les redirections |
| 173 | +res = requests.get("http://fr.openfoodfacts.org/", allow_redirects=False) |
| 174 | +>>> res.status_code |
| 175 | +301 |
| 176 | +>>> res.history |
| 177 | +[] |
| 178 | +``` |
| 179 | + |
| 180 | +- personnaliser les headers d'une requête en passant un dictionnaire: |
| 181 | +``` |
| 182 | +url = "http://fr.openfoodfacts.org/" |
| 183 | +headers = {"user-agent": "python-app/0.0.1"} |
| 184 | +>>>res = requests.get(url, headers=headers) |
| 185 | +``` |
| 186 | +- retrouver facilement la valeur d'un header: |
| 187 | +``` |
| 188 | +>>>res.headers["content-type"] |
| 189 | +'text/html; charset=UTF-8' |
| 190 | +``` |
| 191 | + |
| 192 | +- Et pleins d'autres choses avec les cookies, les certificats SSL ou encore les requêtes préparées que vous retrouveregit checkz sur la [doc officielle](http://docs.python-requests.org/en/master/user/advanced/) |
| 193 | + |
| 194 | +### Conclusion |
| 195 | +`requests` est une librairie simple d'utilisation et très complète. Que ce soit pour un usage basique (comme on vient de voir) ou plus avancé, c'est la librairie conseillée pour effectuer des requêtes HTTP. |
| 196 | + |
0 commit comments