Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Python et Raspberry Pi
  3. À l'assaut du Web avec le Raspberry Pi
Extrait - Python et Raspberry Pi Apprenez à développer sur votre nano-ordinateur (3e édition)
Extraits du livre
Python et Raspberry Pi Apprenez à développer sur votre nano-ordinateur (3e édition)
1 avis
Revenir à la page d'achat du livre

À l'assaut du Web avec le Raspberry Pi

Webscraping facile avec les modules requests et html

Python est un langage de choix pour la programmation réseau, ainsi que la programmation web, notamment grâce à, encore fois, son très large panel de bibliothèques disponibles. Le webscrapping est une technique permettant de récupérer une page d’un site web et d’en analyser son contenu. Deux modules tirent leurs épingles du jeu : requests et html. Ces deux modules servent essentiellement à manipuler des pages web, c’est-à-dire les récupérer depuis un serveur et en extraire des informations pertinentes.

Avec le module requests, la récupération du contenu d’une page et l’interrogation d’un serveur s’effectuent en à peine trois lignes. Bien évidemment, le Raspberry Pi doit être connecté à Internet avant de commencer à utiliser le module et interroger des sites. L’URL (Uniform Resource Locator) de la page interrogée est l’article de la France (en français) du site Wikipedia.org :

>>> import requests 
>>> reponse = requests.get("https://fr.wikipedia.org/wiki/France") 
>>> page = reponse.text 

La page peut être affichée telle quelle mais résulte généralement en un énorme flux de texte. Elle peut aussi être sauvegardée dans un fichier .html pour être lue plus tard :

>>> open("france.html", "w", encoding="UTF-8").write(page) 

Cette logique peut être résumée dans un script (Chapitre_6/webscrapping_1.py) :

1 #!/usr/bin/env python3 
2 import requests 
3 url = "https://fr.wikipedia.org/wiki/France" 
4 
5 
6 def main(): 
7     with requests.Session() as session: 
8         reponse = session.get(url) 
9         page = reponse.text 
10         with open("france.html", "w", encoding="UTF-8") as f: 
11             print(f"Sauvegarde la page {url} dans le fichier france.html.") 
12            ...

Développer un serveur HTTP avec le module http.server

Python rend possible l’écriture de son propre serveur HTTP grâce aux classes fournies avec la distribution de base. Dans Python 3, ces classes se trouvent dans le module http et, en quelques lignes, transforment le Raspberry Pi en un serveur web pouvant héberger du contenu. Démonstration avec le code suivant (Chapitre_6/serveurhttp_1.py) :

1 #!/usr/bin/env python3 
2 from http.server import BaseHTTPRequestHandler 
3 from http.server import HTTPServer 
4 
5 
6 ip = "127.0.0.1" 
7 port = 8080 
8 
9 
10 class HTTPi(BaseHTTPRequestHandler): 
11     def do_GET(self): 
12         self.send_response(200) 
13         self.send_header("Content-type", "text-html; charset=UTF-8") 
14         self.end_headers() 
15         content = """ 
16 <html> 
17 <head> 
18 <title>Hello Pi !</title> 
19 </head> 
20 <body> 
21   <h1>Hello Pi !</h1> 
22 </body> 
23 </html>""" 
24         body = content.encode("UTF-8") 
25         self.wfile.write(body) 
26 
27 
28 def main(): 
29     try: 
30         serveur = HTTPServer((ip, port), HTTPi) 
31         print(f"Démarrage du serveur HTTPi: http://{ip}:{port}") 
32         serveur.serve_forever() 
33     except KeyboardInterrupt: 
34         serveur.socket.close() 
35 
36 
37 if __name__ == "__main__": 
38     main() 

BaseHTTPRequestHandler et HTTPServer sont deux classes qui effectuent la majorité du travail de rendu de la page. Pour rappel, les requêtes HTTP les plus courantes définies par la RFC 7231 sont les suivantes :

  • GET

  • POST

  • PUT

  • HEAD

Pour rappel, la RFC 7231 définit les bases du protocole HTTP/1.1 et explique en profondeur les nombreux détails nécessaires au bon fonctionnement du protocole.

Pour servir du contenu depuis...

Exécuter des scripts avec le module cgi

CGI, signifiant Common Gateway Interface et décrit dans la RFC 3875, est une interface destinée aux serveurs HTTP. Cette interface rajoute une fonctionnalité supplémentaire : l’interprétation de scripts, en l’occurrence de scripts Python dans le cas d’un serveur HTTP Python. À l’inverse d’un serveur traditionnel se contentant simplement de lire une page web et de renvoyer le contenu au client ayant demandé la page, avec CGI le serveur HTTP exécute un script qui, une fois exécuté, renvoie le résultat au client. L’interface CGI exploite aussi l’échange entre le client et le serveur à travers la méthode HTTP POST, communément mise en œuvre par le biais d’un formulaire. L’interface CGI n’est pas spécifique au langage Python et existe dans de nombreux autres langages de programmation.

Dans la pratique, ajouter une interface CGI à un serveur HTTP Python requiert de programmer un gestionnaire HTTP conforme au protocole CGI. Une fois n’est pas coutume, la bibliothèque standard contient un gestionnaire déjà prêt à l’emploi : CGIHTTPRequestHandler. Le code de ce serveur HTTP/CGI est sensiblement le même que celui d’un serveur HTTP classique (Chapitre_6/serveurcgi_1.py) :

1 #!/usr/bin/env python3 
2 from http.server import CGIHTTPRequestHandler 
3 from http.server import HTTPServer 
4 import sys 
5 import os 
6 
7 
8 ip = "127.0.0.1" 
9 port = 8080 
10 repertoire = "/home/pi/www" 
11 
12 
13 def main(): 
14     try: 
15         os.chdir(repertoire) 
16         serveur = HTTPServer((ip, port), CGIHTTPRequestHandler) 
17         print(f"Démarrage du serveur CGI: http://{ip}:{port}") 
18         serveur.serve_forever() 
19     except FileNotFoundError as e: 
20         sys.stderr.write( 
21             f"ERREUR ! Le répertoire \"{repertoire}\" n'existe pas !\n") 
22         raise e ...

Envoyer des e-mails avec le module smtplib

La distribution d’e-mails, aussi appelés courriels, est un aspect important de la programmation web et réseau. Pour mieux comprendre comment un e-mail doit être formé et envoyé, deux RFC sont essentielles pour ce chapitre :

  • la RFC 822 - Internet Message Format qui définit la structure et les en-têtes d’un e-mail.

  • la RFC 5321 - Simple Mail Transfer Protocol définissant le protocole SMTP, le plus utilisé pour l’échange et l’envoi d’e-mails sur Internet.

L’essentiel à comprendre de ces deux RFC se résume à la structure d’un message e-mail, élément clé pour pouvoir envoyer des messages valides à son interlocuteur. De la même manière qu’une réponse HTTP, un message mail est composé de plusieurs en-têtes. Les quatre plus connus sont les suivants :

  • From : désignant l’expéditeur.

  • To : désignant le destinataire.

  • Date : indiquant la date d’envoi du message.

  • Subject : indiquant le sujet du message envoyé.

Il existe d’autres en-têtes qui sont parfois (souvent) utilisés, tels que Cc : pour mettre en copie un destinataire et Bcc : pour mettre en copie cachée un destinataire. Ainsi, avec ces informations, l’envoi d’un courriel consiste à assembler ces en-têtes...

Écrire une API légère avec Flask

Au sein de la communauté web Python, un framework émerge et fait beaucoup parler de lui depuis un petit moment déjà. Simple, modulaire et relativement facile à prendre en main, Flask accélère grandement le développement d’interfaces de programmation applicative orientée web, aussi appelées API en anglais (Application Programming Interface). La force de Flask réside essentiellement dans son extrême modularité et sa facilité d’utilisation déconcertante. 

Flask ne fait pas partie de la bibliothèque standard Python. Comme d’habitude, passez par l’outil pip3 pour l’installer :

pi@raspberrypi:~ $ sudo pip3 install flask 

Commençons par le traditionnel programme « Hello world », version Flask (Chapitre_6/flask_1.py) :

1 #!/usr/bin/env python3  
2 from flask import Flask  
3  
4  
5 app = Flask(__name_₎  
6  
7  
8 @app.route("/")  
9 def hello():  
10     return "Hello World!"  
11  
12  
13 if __name__ == "__main__":  
14     app.run() 

Que se passe-t-il exactement dans ce code ? Reprenons ligne par ligne.

1 #!/usr/bin/env python3  
2 from flask import Flask  
3  
4  
5 app = Flask(__name__) 

L’import de la classe Flask est primordial, il permet d’instancier notre application un peu plus bas dans le code. Notez que le nom de l’application correspond au nom du contexte, qui n’est autre que __main__ ici.

8 @app.route("/")  
9 def hello():  
10     return "Hello World !" 

Un décorateur déclare une route au sein de notre application. Lorsque cette route est appelée, le résultat de la fonction hello() est calculé par le serveur et le rendu est affiché au client.

13 if __name__ == "__main__":  
14     app.run() 

L’application démarre à partir de cette ligne. Lorsque l’application est lancée à partir de la console, voici le résultat :

pi@raspberrypi:~/python-raspberrypi-3e-edition/Chapitre_6 $ python3 flask_1.py 
* Serving Flask app "flask_1" (lazy loading) ...

Conclusion

Ce chapitre présente en détail certaines techniques incontournables de la programmation web, une connaissance clé pour faire communiquer le Raspberry Pi avec d’autres périphériques en réseau. En expliquant certains modules de base, tels que le module http, comme d’autres modules plus évolués, par exemple Flask, ce chapitre couvre les techniques standards comme les plus avancées.