La première application Web créée par des débutants en Python

Il s'agit d'un mémorandum lorsqu'un débutant n'ayant jamais touché à Python a créé une application web très simple. C'est le premier message de Qiita. Je suis toujours redevable.

** ■ Présentation de l'application ** ・ Afficher une page Web qui accepte les entrées des utilisateurs -Demande de recherche de l'API Book (API Google Livres) basée sur le titre du livre saisi ・ Afficher la vignette du livre à partir de la réponse

Je décrirai le processus de création, l'endroit auquel j'étais accro et la solution.

-environnement- Mac OS

1. Installation de Python

Par défaut, Mac a installé 2.x Python. Vérifiez la version Python installée avec la commande suivante.

Terminal


$ python --version
Python 2.7.16

La série Python 2.x n'est plus prise en charge le 1er janvier 2020. Il y a beaucoup d'incohérences dues à la différence de version par rapport à la série 3.x + Il semble que les élèves du primaire riront à ce moment-là en utilisant la série 2.x, donc ... Tout d'abord, mettez à jour vers la série 3.x.

↓ Téléchargez le package de la série 3.x sur le site officiel https://www.python.org/downloads/

** Q1. Points addictifs ** Même si je l'ai installé, la version reste 2.x Si vous cochez python3 --version, il s'agit de la série 3.x

Terminal


$ python --version
Python 2.7.16
$ python3 --version
Python 3.7.7

** A1. Solution **

  1. Installez pyenv avec la commande brew (je ne sais pas comment le lire, je l'ai lu dans mon cœur)

Terminal


$ brew install pyenv
  1. Ajoutez les 4 lignes suivantes à ~ / .bash_profile en utilisant l'éditeur vi etc. export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)" export PATH="$HOME/.pyenv/shims:$PATH"

Terminal


$ vi ~/.bash_profile
# ~/.bash_Editer le profil
$ source ~/.bash_profile
  1. Utilisez pyenv pour que tout le Mac reconnaisse la série python 3.x.

Terminal


$ pyenv global 3.7.0
$ pyenv rehash

Vous pouvez maintenant utiliser la série 3.x.

Terminal


$ python --version
Python 3.7.7

2. Structure des dossiers

Placez les dossiers index.html, server.py et cgi-bin directement sous le dossier racine du projet. Placez index.py dans le dossier cgi-bin.

project/
  ┝ ─ index.html
  ┝ ─ server.py
  └ ─ cgi-bin/
         └ ─ index.py

3. Créez index.html

Cette fois, je vais créer un html qui accepte simplement l'entrée de chaînes de caractères sans tenir compte de la mise en page.

index.html


<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <form method="POST" action="cgi-bin/index.py">
      <label>Titre de l'image du livre d'acquisition:</label>
      <br>
      <input type="text" name="text">
      <button type="submit">Envoyer</button>
    </form>
  </body>
</html>

Pour l'expliquer, Les données saisies dans la zone entourée de la balise \

sont \ est envoyé à cgi-bin / index.py par la méthode POST. C'est comme ça.

Une page comme celle ci-dessous sera créée. スクリーンショット 2020-04-03 21.20.59.png

Les données saisies dans la zone de texte seront envoyées à index.py lorsque vous appuyez sur le bouton [Envoyer].

4. Créez server.py

Vous en aurez besoin pour configurer un serveur pour la vérification localement.

server.py


import http.server
http.server.test(HandlerClass=http.server.CGIHTTPRequestHandler)

Lorsque vous démarrez le fichier Python créé dans Terminal, le serveur local démarre. Avec le serveur local en place http://0.0.0.0:8000/ Lorsque vous y accédez, vous devriez voir l'index.html que vous venez de voir.

Terminal


$ python server.py
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
  • Au fait, c'est la commande + C pour arrêter le serveur local.

5. Créez index.py

Nous utiliserons les données envoyées depuis index.html pour envoyer une demande pour l'API Google Book Search.

index.py


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import cgi #Importer le module CGI
import cgitb
import sys
import requests
import json

#Modèle d'API de recherche de livres
api = "https://www.googleapis.com/books/v1/volumes?q={title}&maxResults=10&startIndex=0"

#Puisqu'il est utilisé pour le débogage, il n'est pas décrit dans l'environnement de production.
cgitb.enable()

#Obtenez les données du formulaire saisies par l'utilisateur
form = cgi.FieldStorage()

#En-tête pour écrire du HTML
print("Content-Type: text/html; charset=UTF-8") 
print("")

#Si aucune donnée de formulaire n'a été saisie
if "text" not in form:
    print("<h1>Error!</h1>")
    print("<br>")
    print("Entrez le texte!")
    print("<a href='/'><button type='submit'>Revenir</button></a>")
    sys.exit() # index.Fin de py

text = form.getvalue("text") #Obtenez la valeur des données textuelles
url = api.format(title=text) #Recherche de livre mot de recherche API{title}Appliquer le texte d'entrée à
response = requests.get(url) #Lancer une demande
data = json.loads(response.text) #Convertir la réponse au format json

#Refléter la réponse en html

print(data['items'][0]['volumeInfo']['title'])
print("<br>")
print("<img src=" + data['items'][0]['volumeInfo']['imageLinks']['thumbnail'] + ">")
print("<br>")
print("<a href='/'><button type='submit'>Revenir</button></a>")

J'ai beaucoup ajouté dans les commentaires, mais je vais l'expliquer. ↓ Il s'agit de l'URL de l'API Google Livres. https://www.googleapis.com/books/v1/volumes?q=いちご100&maxResults=10&startIndex=0 Entrez le nom du livre que vous souhaitez rechercher après ** q = ** et il renverra la réponse appropriée.

Vous pouvez facilement le vérifier en utilisant curl.

Terminal


$ curl https://www.googleapis.com/books/v1/volumes?q=Fraise 100&maxResults=10&startIndex=0

"kind": "books#volumes",
 "totalItems": 2836,
 "items": [
  {
   "kind": "books#volume",
   "id": "vWSUDwAAQBAJ",
   "etag": "b/w9qaxsyy4",
   "selfLink": "https://www.googleapis.com/books/v1/volumes/vWSUDwAAQBAJ",
   "volumeInfo": {
    "title": "Version 100% monochrome d'Ichigo [gratuit pour une durée limitée] 2",
    "authors": [
     "Mizuki Kawashita"
    ],
    "publisher": "Shueisha",
    "publishedDate": "2002-10-04",
    "description": "[Spring Man!!Gratuit pour un temps limité!!/ Un labyrinthe d'amour dans lequel Junpei Manaka s'est soudainement perdu! Super comédie d'amour de jeunesse dirigée par un pantalon de fraise! ] * Ceci est une version d'essai gratuite pour une durée limitée jusqu'au 8 mai 2019. Il ne sera plus disponible après le 9 mai 2019. Nishino et Tojo, la sensation du milieu se balançant entre eux. Qu'est-ce que tu aimes vraiment chez Nishino? Ou est-ce Tojo? Le jour de l'examen, quand j'ai été accueilli sans me mettre à étudier du tout, à l'entrée du labyrinthe aux motifs de fraises, une belle fille fantôme était devant moi ...!!Que faire au milieu!?",
    "industryIdentifiers": [
     {
      "type": "OTHER",
      "identifier": "PKEY:088733268733043155P5"
     }
    ],
    "readingModes": {
     "text": true,
     "image": false
    },
    "pageCount": 188,
    "printType": "BOOK",
    "categories": [
     "Comics & Graphic Novels"
    ],
    "maturityRating": "NOT_MATURE",
    "allowAnonLogging": false,
    "contentVersion": "1.2.2.0.preview.2",
    "panelizationSummary": {
     "containsEpubBubbles": true,
     "containsImageBubbles": true,
     "epubBubbleVersion": "99b0fa95624a43e9_A",
     "imageBubbleVersion": "99b0fa95624a43e9_A"
    },
    "imageLinks": {
     "smallThumbnail": "http://books.google.com/books/content?id=vWSUDwAAQBAJ&printsec=frontcover&img=1&zoom=5&source=gbs_api",
     "thumbnail": "http://books.google.com/books/content?id=vWSUDwAAQBAJ&printsec=frontcover&img=1&zoom=1&source=gbs_api"
    },
    "language": "ja",
    "previewLink": "http://books.google.co.jp/books?id=vWSUDwAAQBAJ&dq=%E3%81%84%E3%81%A1%E3%81%94100&hl=&cd=1&source=gbs_api",
    "infoLink": "http://books.google.co.jp/books?id=vWSUDwAAQBAJ&dq=%E3%81%84%E3%81%A1%E3%81%94100&hl=&source=gbs_api",
    "canonicalVolumeLink": "https://books.google.com/books/about/%E3%81%84%E3%81%A1%E3%81%94100_%E3%83%A2%E3%83%8E%E3%82%AF%E3%83%AD%E7%89%88_%E6%9C%9F%E9%96%93%E9%99%90.html?hl=&id=vWSUDwAAQBAJ"
   },
   "saleInfo": {
    "country": "JP",
    "saleability": "NOT_FOR_SALE",
    "isEbook": false
   },
   "accessInfo": {
    "country": "JP",
    "viewability": "NO_PAGES",
    "embeddable": false,
    "publicDomain": false,
    "textToSpeechPermission": "ALLOWED",
    "epub": {
     "isAvailable": true
    },
    "pdf": {
     "isAvailable": true
    },
Abréviation------------------------------------------------------

La réponse longue telle que décrite ci-dessus est stockée en réponse, Dans les données, la réponse est convertie en type JSON et stockée.

Cette fois, je souhaite utiliser [titre] et [miniature]. data['items'][0]['volumeInfo']['title'] data['items'][0]['volumeInfo']['imageLinks']['thumbnail'] Pour accéder et récupérer les données requises.

En modifiant la valeur de [0] en [1] [2] Vous pouvez modifier la cible des résultats de recherche à récupérer.

スクリーンショット 2020-04-03 21.42.24.png

↓↓↓

スクリーンショット 2020-04-03 21.43.06.png

Achèvement ○ △ □

** Q2. Points addictifs ** Lorsque vous appuyez sur le bouton d'envoi, FileNotFoundError: [Errno 2] No such file or directory: '/Users/hoge/project/cgi-bin/index.py' L'erreur s'affiche et les résultats de la recherche ne s'affichent pas

** A2. Solution ** /Users/hoge/project/cgi-bin/index.py existait. La première ligne de index.py était incorrecte × #!usr/bin/env python3 ○ #!/usr/bin/env python3

** Les requêtes Q3.ne peuvent pas être importées ** import requests Une erreur se produit à l'emplacement de

** A3. Solution ** Cet article a été très utile. https://qiita.com/Kent_recuca/items/349586e9c034535f2991

Dans Python sys.path Résolu en ajoutant le chemin où les demandes sont installées

Résumé

J'avais l'habitude de créer une application Web à l'aide de Spring Boot, Par rapport à cela, je pense que la structure des dossiers et la construction de l'environnement sont plus faciles et peuvent être déplacées immédiatement.

Je savais qu'il était utilisé dans le domaine de l'apprentissage automatique, mais j'ai été surpris qu'il soit également utilisé dans l'environnement Web. Depuis que je suis nouveau sur Python Pourquoi l'erreur se produit après le #, qui devrait être un commentaire Pourquoi index.html s'affiche-t-il lorsque je démarre le serveur local? Il y a encore beaucoup de mystères, mais j'aimerais étudier et approfondir ma compréhension.

Recommended Posts