Pour la première fois, j'ai utilisé Flask et Heroku of Python pour créer une API qui renvoie des informations récupérées avec json, je voudrais donc résumer la méthode utilisée à ce moment-là.
Ceux utilisés par heroku jusqu'à Hello World et la construction de l'environnement de Python sont la première partie. Re: Heroku life - Environment start with Flask from zero and the Hello World ~ À Ce sera la deuxième partie jusqu'à ce que le programme à créer cette fois soit déployé sur Heroku Re: Life in Heroku à partir de zéro avec Flask ~ PhantomJS à Heroku ~ Puisqu'il est écrit, veuillez également consulter
Cette fois, j'écrirai comment gratter en utilisant Selenium et PhantomJS avec SlideShare comme sujet.
*** Comme il est devenu long lorsque je l'ai rassemblé dans un article, le flux de déploiement vers Heroku est divisé en une deuxième partie. *** ***
[HerokuURL] / api / [Mot de recherche] / [Nombre de pages] Exemple: ~ herokuapp.com/api/python/2 Lorsque vous accédez
PhantomJS fonctionne sur Heroku et ouvre la page de recherche Slideshare
Entrez le [Mot de recherche] de l'URL dans le champ de recherche de la page de recherche à rechercher.
Modifiez le paramètre de langue des résultats de recherche en japonais
Extraire les informations des diapositives dans les pages Web en grattant
Cliquez sur Suivant sur le pager sous le nombre de pages de l'URL et répétez le scraping.
Après avoir gratté, mettez-le au format json et lancez-le!
Je voudrais créer une API qui fait cela.
Re: Heroku life - Environment start with Flask from zero and the Hello World ~ Installé au moment où vous faites Hello World Veuillez inclure *** Flask *** et *** Gunicorn *** Veuillez préparer votre environnement préféré tel que pyenv-virtualenv.
PhantomJS Placez PhantomJS localement pour vérifier l'opération localement avant de l'exécuter sur Heroku. Je pense qu'il est normal de reconnaître que le navigateur n'a pas d'interface graphique pouvant être utilisée à partir du code. Référence: Essayez différentes choses avec PhantomJS
$ brew install phantomjs
Selenium Il semble que ce soit un outil de test d'interface utilisateur multi-navigateurs et multi-plateformes. Avec le grattage normal, vous ne pouvez faire que ce qui est affiché à l'URL spécifiée, mais en utilisant le sélénium, vous pouvez appuyer sur le bouton pour aller à la page suivante ou entrer des caractères et appuyer sur le bouton de recherche. sensationnel
C'est Ruby, mais c'est un article utile: Test d'automatisation de l'interface utilisateur Web - Essayez avec Selenium
$ pip install selenium
beautifulsoup Il est utilisé lors du traitement des données de page Web acquises. Référence: Scraping with Python and Beautiful Soup
$ pip install beautifulsoup4
lxml Utilisé en combinaison avec une belle soupe.
$ pip install lxml
Même si vous créez une API qui renvoie normalement Json, il est gênant d'utiliser une API qui n'a pas été traitée dans Chrome en raison de restrictions interdomaines, je prendrai donc des mesures. Je vais mettre un lien dans l'explication du code.
$ pip install -U flask-cors
https://github.com/ymgn/SlideShare-API
api.py
# -*- coding: utf-8 -*-
import json
#Grattage requis à partir d'ici
from bs4 import BeautifulSoup
#De là, vous devez utiliser le navigateur avec du sélénium
from selenium import webdriver
from selenium.webdriver.common.keys import Keys #Utilisé lors de la saisie de caractères
#Quantité de flacon requise à partir d'ici
import os
from flask import Flask
#À partir de là pour la contrainte inter-domaines lors de l'utilisation de cors en définissant ajax avec flask
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app)
@app.route('/')
def index():
return "Comment utiliser: /api/Mot à rechercher/Nombre de pages acquises"
@app.route('/api/<string:word>/<int:page>') #Rechercher un mot/Recevoir le nombre de pages du chemin vers la variable
def slide(word,page):
driver = webdriver.PhantomJS() #Utilisez PhantomJS
driver.set_window_size(1124, 850) #Spécifiez la taille de PhantomJS
driver.implicitly_wait(20) #Si l'élément spécifié n'existe pas, le pilote attendra automatiquement jusqu'à 20 secondes jusqu'à ce qu'il sorte.
URL = "http://www.slideshare.net/search/"
driver.get(URL) #Accéder à l'URL de partage de diapositives
data_list = [] #Un tableau qui collecte des données pour toutes les pages
search = driver.find_element_by_id("nav-search-query") #Obtenir un élément de champ de recherche
search.send_keys(word) #Entrez un mot de recherche
search.submit() #Soumettre la recherche
lang = driver.find_element_by_xpath("//select[@id='slideshows_lang']/option[@value='ja']") #Extraire la partie japonaise de la liste de sélection des langues
lang.click() #Sélectionnez le japonais comme sélection de langue
for i in range(0,page):
print(str(i+1) + u"Page de la page")
data = driver.page_source.encode('utf-8') #Utf les informations dans la page-Préparez-vous en 8
soup = BeautifulSoup(data,"lxml") #Faites-le au format lxml pour un traitement facile
slide_list = soup.find_all("div",class_="thumbnail-content") #Extrait par diapositive
for slide in slide_list:
slide_in = {} #Organiser les informations sur les diapositives au format dictionnaire
#Obtenez le nom de l'affiche de la diapositive
name = slide.find("div",class_="author").text
slide_in["name"] = name.strip() # strip()Élimine les blancs et les sauts de ligne aux deux extrémités
#Obtenez le titre de la diapositive
title = slide.find("a",class_="title title-link antialiased j-slideshow-title").get("title") #Balise spécifiée&Émettre un titre dans la classe
slide_in["title"] = title
#Obtenez le lien de la diapositive
link = slide.find("a",class_="title title-link antialiased j-slideshow-title").get("href") #Balise spécifiée&Émettre href en classe
slide_in["link"] = "http://www.slideshare.net" + link
#Obtenir le lien de la miniature de la diapositive
imagetag = slide.find("a",class_="link-bg-img").get("style") #Balise spécifiée&Mettez le style dans la classe
image = imagetag[imagetag.find("url(")+4:imagetag.find(");")] #Retirez les pièces inutiles
slide_in["image"] = image
#Obtenez des diapositives et des likes, qui sont le nombre de pages de diapositives
info = slide.find("div",class_="small-info").string #Obtenez les chaînes de diapositives et de likes
slides = info[7:info.find("slides")] #Extraire la partie diapositives
slide_in["slides"] = slides.strip() # strip()Élimine les blancs et les sauts de ligne aux deux extrémités
if "likes" in info:
likes = info[info.find(", ")+2:info.find("likes")] #Extraire la partie likes
else:
likes = "0"
slide_in["likes"] = likes.strip() # strip()Élimine les blancs et les sauts de ligne aux deux extrémités
data_list.append(slide_in) # data_Résumer le contenu d'une page dans la liste
driver.execute_script('window.scrollTo(0, 3000)') #Descendre avec téléavertisseur
next = driver.find_element_by_xpath("//li[@class='arrow']/a[@rel='next']") #Extraire l'élément NEXT du pager
next.click() #Cliquez sur le bouton Suivant
driver.close() #Terminer le fonctionnement du navigateur
jsonstring = json.dumps(data_list,ensure_ascii=False,indent=2) #Sortie du tableau créé au format json
return jsonstring
#Déterminez si vous frappez avec bash ou insérez avec l'importation
if __name__ == '__main__':
app.run()
J'ai également écrit des commentaires dans le code, mais je voudrais expliquer les parties importantes du haut. L'importation est telle qu'elle est écrite, donc omise CORS Les programmes qui utilisent des API ne fonctionnent pas sur Chrome, etc.! Je pense que vous avez l'expérience. Puisque nous créons une API avec beaucoup d'efforts, prenons des mesures.
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app)
Il semble que si vous écrivez, cela prendra des mesures. Benri Référence: https://flask-cors.readthedocs.io/en/latest/
Si vous écrivez
@app.route('/api/<string:word>/<int:page>') #Rechercher un mot/Recevoir le nombre de pages du chemin vers la variable
def slide(word,page):
Référence: Let's master Flask
driver.set_window_size(1124, 850)
Si vous ne décidez pas de la taille du navigateur, vous ne pourrez pas prendre des éléments ou bien faire défiler. La raison est inconnue car la valeur numérique de la taille est telle qu'elle a été écrite lorsque je l'ai vérifiée.
driver.implicitly_wait(20)
En écrivant comme ceci, lorsque vous spécifiez l'ID et la classe de driver.find ~~ '' et que vous récupérez et utilisez l'élément, attendez jusqu'à 10 secondes et exécutez immédiatement lorsque la lecture est terminée. Ce sera dans un état pratique à faire. C'est très pratique lorsque vous utilisez du sélénium car vous n'avez pas à attendre explicitement le temps d'attente attendu tel que
time.sleep (3) ''.
Référence: Il est écrit dans la section Attentes implicites de ce site
search = driver.find_element_by_id("nav-search-query") #Obtenir un élément de champ de recherche
search.send_keys(word) #Entrez un mot de recherche
search.submit() #Soumettre la recherche
Après avoir récupéré l'élément d'entrée, etc. par id depuis le navigateur, vous pouvez entrer la valeur avec `send_keys (" hoge ")`
etc.
Si l'élément est dans un formulaire, vous pouvez le soumettre en ajoutant `` .submit () ''.
lang = driver.find_element_by_xpath("//select[@id='slideshows_lang']/option[@value='ja']") #Extraire la partie japonaise de la liste de sélection des langues
lang.click() #Sélectionnez le japonais comme sélection de langue
Cette fois, la méthode de spécification d'élément est spécifiée par XPATH au lieu de id ou de classe. La raison en est que lors de la sélection d'un élément enfant qui a plusieurs identifiants ou que seul le parent a un identifiant, il est nécessaire de le spécifier dans une partie autre que id et classe.
Au fait, si vous ne passez pas au japonais comme celui-ci, même si vous obtenez le japonais localement, le côté Heroku obtiendra les diapositives de toutes les langues.
Lorsqu'il y a plusieurs identifiants
lang = driver.find_elements_by_id("slideshows_lang")
lang[1].find_elements_by_tag_name("option")
#Lors de l'extraction de plusieurs, ce sera d'élément en éléments
Si seulement le parent a un identifiant
lang = driver.find_element_by_id("slideshows_lang")
lang.find_element_by_tag_name("option")
Veuillez vous référer à la référence pour savoir comment écrire XPATH et d'autres méthodes d'extraction. Référence: Locating Elements
data = driver.page_source.encode('utf-8') #Utf les informations dans la page-Préparez-vous en 8
soup = BeautifulSoup(data,"lxml") #Faites-le au format lxml pour un traitement facile
Après avoir encodé les données de page du site Web obtenues par webdriver avec utf-8, utilisez lxml qui est compatible avec Beautiful Soup pour le rendre facile à gratter. Je l'ai mis car il doit être chargé à chaque fois que la page change.
driver.execute_script('window.scrollTo(0, 3000)') #Descendre avec téléavertisseur
Vous pouvez maintenant faire défiler PhantomJS vers le bas de 3000 pixels avec JavaScript. Si PhantomJS n'a pas d'interface graphique, le défilement n'a pas de sens, non? Vous pourriez penser, mais si vous ne faites pas défiler, vous obtiendrez une erreur. Je voulais aller en bas car je l'ai réglé sur 3000, donc je l'ai réglé sur 3000 pour le moment.
next = driver.find_element_by_xpath("//li[@class='arrow']/a[@rel='next']") #Extraire l'élément NEXT du pager
next.click() #Cliquez sur le bouton Suivant
Quand j'ai essayé d'appuyer sur Suivant sur la partie pager de Slideshare, Précédent et Suivant avaient
class = "arrow"
, et la balise a ne contenait ni id ni classe. .. Depuis que j'ai écrit
rel = "next"
dans la balise a de l'élément enfant, cette partie est définie sur XPATH qui peut être spécifiée, y compris le parent et rel.
jsonstring = json.dumps(data_list,ensure_ascii=False,indent=2) #Sortie du dictionnaire créé au format json
return jsonstring
json.dumps(Tableau,Données du dictionnaire,Faux si le japonais est inclus,Organiser par retrait)
Si vous passez un tableau ou un dictionnaire, il sera au format json. Le retrait est facultatif, et si vous définissez indent = 2
, il sera mis en retrait avec deux espaces demi-largeur pour le rendre plus facile à voir.
Référence: [Python] Handle JSON
Supposons que vous ayez tout ce dont vous avez besoin installé.
$ mkdir slide
$ cd slide
$ touch api.py Procfile
#Créer un fichier pour écrire le fichier et les paramètres du flacon
Procfile
web: gunicorn hello:app --log-file=-
api.py
Voir au dessus
$ python api.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
http://127.0.0.1:5000/api/python/2 Accédez avec ce chemin et obtenez deux pages recherchées par python sur slideshare. résultat Dans Safari, json ressemble à une liste, mais dans Chrome, vous pouvez le voir magnifiquement en insérant JSON View, etc.
Diverses bibliothèques pouvant être utilisées pour l'exploration et le scraping en Python
Le flux de déploiement vers Heroku est la deuxième partie Re: Life in Heroku à partir de zéro avec Flask ~ PhantomJS à Heroku ~ Puisqu'il est écrit, merci.
Pour le moment, opérations de base du navigateur Selenium (saisie de caractères, soumission, sélection de liste déroulante, clic d'élément, spécification XPATH) et scraping (texte, image, URL, traitement de chaîne de caractères et jsonisation) Je pense que j'ai été capable d'écrire comment le faire, alors j'espère que cela aidera quelqu'un.
Nous vous serions reconnaissants de bien vouloir signaler des améliorations ou des erreurs dans la section des commentaires. Twitter:@ymgn_ll
Recommended Posts