J'écris beaucoup de tutoriels pour Envato Tuts +. Ces tutoriels ont des rubriques qui doivent suivre certaines règles de capitalisation. Tuts + fournit aux auteurs un outil Web qui prend le texte d’un en-tête et renvoie un en-tête correctement capitalisé. Lorsque j'écris mes tutoriels, j'essaie d'entrer dans le flux, et le passage à l'outil de capitalisation interrompt mon flux. J'avais l'habitude de voler et de faire la capitalisation moi-même.
Il se trouve que j'ai souvent commis des erreurs, ce qui a occasionné un surcroît de travail pour les éditeurs de Tuts + qui ont dû les corriger. En tant que programmeur, j'ai décidé de programmer le moyen de sortir du problème. J'écris toujours mes propres titres, mais lorsque j'ai terminé, je lance un petit programme Python qui analyse mon article, détecte tous les en-têtes, puis l'exécute à l'aide de l'outil de capitalisation Tuts + et capitalise correctement tous les titres..
L'outil de capitalisation étant une application Web et non une API, j'ai dû automatiser le navigateur pour pouvoir l'invoquer et extraire les en-têtes en majuscules. Dans ce didacticiel, vous apprendrez à contrôler le navigateur dans Python via Selenium et à le mettre à exécution..
Capitaliser les titres n'est pas sorcier, mais ce n'est pas trivial non plus. Il existe plusieurs styles, avec des chevauchements et des variations. C'est plus ou moins le consensus:
Ensuite, il y a un tas d'exceptions et de situations spéciales (par exemple, les flux de titre vers la ligne suivante). Mais tout est discutable. Même si j'ai décidé d'écrire mon propre code de capitalisation, Tuts + a déjà choisi leur saveur et je dois me conformer au style choisi..
L'outil de capitalisation Tuts + est un outil interne destiné uniquement aux instructeurs de Tuts +. Je ne peux donc pas l'utiliser comme démo. Cependant, j'ai trouvé un outil similaire appelé Title Case Converter. Il s’agit d’une application Web avec une grande zone de texte dans laquelle vous pouvez taper votre en-tête (ou titre), un bouton de conversion sur lequel vous cliquez pour envoyer le formulaire, une zone de sortie qui apparaît avec un en-tête correctement mis en majuscule, et enfin un bouton de copie rubrique convertie dans le presse-papiers.
D'ACCORD. Je vais utiliser le convertisseur de cas en ligne, mais il n'y a pas d'API. Ce n'est pas un gros problème. Je peux automatiser le navigateur et simuler un utilisateur en tapant l'en-tête dans le champ de saisie, en cliquant sur le bouton de conversion, en attendant l'affichage de la sortie, en cliquant sur le bouton de copie et en collant finalement l'en-tête correctement capitalisé dans le presse-papiers..
La première étape consiste à choisir une automatisation du navigateur. J'ai choisi Selenium WebDriver, que j'ai utilisé avec succès auparavant. Le reste du plan est:
Le code source complet est disponible sur GitLab.
Selenium automatise les navigateurs depuis 2004. En 2008, il a fusionné avec le projet WebDriver, qui résout certaines des limitations du Selenium d'origine (par exemple, exécuté dans le bac à sable JavaScript)..
Le sélénium offre toujours la saveur originale du sélénium appelée sélénium RC (télécommande). Il dispose également d'un IDE pour l'écriture de suites de tests automatisées et d'un outil appelé Selenium Grid permettant d'adapter Selenium RC aux suites de tests volumineuses devant s'exécuter dans plusieurs environnements. Nous nous limiterons à un accès programmatique au navigateur via l’API WebDriver (a.k.a. Selenium 2).
L’installation de Selenium est aussi simple que pipenv sélénium
. Si vous ne connaissez pas Pipenv, consultez Revisiting Python Packaging With Pipenv. Vous avez également besoin d'un pilote Web spécifique. Il existe des pilotes Web pour différents navigateurs et extrémités. Vous pouvez trouver la liste complète sur le site web de Selenium.
J'ai choisi le pilote Web Chrome pour ce tutoriel. Voici la dernière version.
C'est un fichier zip unique contenant un seul exécutable (il existe des versions Windows, MacOS et Linux). Une fois que vous l'avez téléchargé, décompressez-le et déposez-le dans votre chemin..
Toutes nos félicitations! Vous êtes maintenant prêt à utiliser Selenium WebDriver de Python.
Le sélénium facilite le lancement d'un navigateur. Tant que vous avez le bon pilote Web sur votre chemin, il vous suffit d'importer le sélénium.webdriver
module et appelez la méthode appropriée pour lancer le navigateur de votre choix:
à partir du sélénium import webdriver driver = webdriver.Chrome ()
Une fois que vous avez un objet pilote, vous pouvez appeler le obtenir()
méthode pour accéder à n’importe quelle page Web. Voici comment accéder au convertisseur de cas de titre:
driver.get ('https://titlecaseconverter.com')
Nous avons besoin d'un moyen de localiser les éléments sur la page avec laquelle vous souhaitez interagir. Le moyen le plus simple consiste à inspecter la page Web dans le navigateur et à rechercher les identifiants des éléments cibles. Dans la capture d'écran suivante, vous pouvez voir que le champ de saisie a l'id "titre":
Le bouton de conversion n'a pas d'identifiant, mais ce n'est pas un problème, comme vous le verrez bientôt. Voici le code pour localiser le formulaire et les champs de texte par identifiant:
champ_entrée = driver.find_element_by_id ('title')
Si un élément avec lequel vous souhaitez interagir n'a pas d'identifiant, vous pouvez le trouver à l'aide de diverses autres méthodes telles que le nom, le nom de la classe ou le sélecteur CSS. Voir toutes les options de ce guide Sélénium.
Par exemple, pour localiser le bouton de conversion, j'ai utilisé son nom de classe:
convertButton = \ driver.find_element_by_class_name ('convertButton')
Pour renseigner le champ de saisie, nous pouvons utiliser le send_keys ()
méthode de notre élément de champ d'entrée. Mais assurez-vous de le nettoyer en premier. Sinon, vous n'aurez qu'à ajouter au texte existant.
input_field.clear () input_field.send_keys (en-tête)
C'était assez facile.
Maintenant, il est temps de soumettre le formulaire. Vous pouvez le faire de deux manières:
soumettre()
méthode.J'ai d'abord soumis le formulaire directement:
form = driver.find_element_by_css_selector ('body> form') form.submit ()
Pour une raison quelconque, cela ne fonctionne pas. Il n'y a pas d'erreur, mais rien ne se passe. Je n'ai pas passé trop de temps à enquêter, car tout l'intérêt de Sélénium et de ce tutoriel est de simuler une personne. J'ai donc utilisé l'autre méthode et j'ai juste cliqué sur le bouton trouvé précédemment:
convertButton.click ()
Le convertisseur de cas en ligne est un peu sophistiqué. Le champ de sortie n'existe pas initialement. Lorsque vous cliquez sur le bouton de conversion et que le formulaire est soumis, le résultat est affiché avec le bouton de copie. Cela signifie que nous devons attendre la fin de la soumission du formulaire pour que le bouton de copie apparaisse et nous pouvons cliquer dessus pour copier le résultat dans le presse-papier..
Le sélénium vous a couvert. Il est compatible avec l'attente de conditions arbitraires et l'expiration du délai si elles ne se matérialisent pas. Voici le code qui attend le bouton de copie. Cela crée un WebDriverWait
objet avec un délai d'attente de cinq secondes. Il crée ensuite une condition pour la présence d'un élément avec le nom de classe copyButton
, puis il appelle l'objet d'attente jusqu'à ce que()
méthode avec la condition.
wait = WebDriverWait (pilote, 5) buttonPresent = presence_of_element_located ((By.CLASS_NAME, 'copyButton')) copyButton = wait.until (buttonPresent)
Le résultat est qu'après avoir cliqué sur le bouton de conversion, il attendra que le bouton de copie apparaisse ou expire au bout de cinq secondes. Si tout va bien, il retournera le copyButton
élément.
Vous pouvez lire le contenu des champs de texte avec field.get_attribute ('valeur')
. Mais, comme je l’ai déjà mentionné, le convertisseur de cas en ligne est plutôt sophistiqué. Sa sortie est une structure imbriquée de plages et de divs, et lorsque vous survolez chaque partie de la sortie, elle vous explique pourquoi elle est capitalisée ou non..
Je pourrais creuser ce labyrinthe et analyser le titre réel, mais il existe un moyen plus simple. Le bouton Copier copie l'en-tête en majuscule dans le presse-papier. Nous pouvons simplement cliquer sur le bouton et lire l'en-tête dans le presse-papiers. J'ai utilisé le module Presse-papiers, que vous pouvez installer avec pipenv installer le presse-papiers
. Le code ci-dessous efface le presse-papier en y copiant une chaîne vide, clique sur le bouton Copier et lit le presse-papier à plusieurs reprises jusqu'à ce qu'il ne soit plus vide..
clipboard.copy (") copyButton.click () result = clipboard.paste () en l'absence de résultat: time.sleep (0.1) result = clipboard.paste ()
D'ACCORD. Nous pouvons capitaliser une seule rubrique. Je mets tout ce code dans une seule fonction:
def capitalize_heading (header): input_field = driver.find_element_by_id ('title') input_field.clear () input_field.send_keys (entête) # form = driver.find_element_by_css_selector ('corps> formulaire') # form.submit () convertButton = \ driver .find_element_by_class_name ('convertButton') convertButton.click () # Attend que le bouton de copie apparaisse wait = WebDriverWait (pilote, 5) buttonPresent = presence_of_element_located ((By.CLASS_NAME, 'copyButton')) copyButton (waitPun). .copy (") copyButton.click () result = clipboard.paste () sans résultat: time.sleep (0.1) result = clipboard.paste () return result
Maintenant, armés de cette capacité, nous pouvons analyser un article entier et mettre en majuscule toutes les rubriques. J'écris mes tutoriels dans Markdown. Toutes mes en-têtes commencent par un ou plusieurs hash (#).
J'ai défini une fonction d'assistance qui prend une ligne et, si elle contient un en-tête, la capitalise correctement à l'aide de la commande capitalize_heading ()
fonction et renvoie le résultat. L'essentiel est de supprimer tous les hachages et espaces principaux et de les restaurer ultérieurement. Nous ne pouvons pas alimenter un en-tête avec des espaces de début car cela confond le convertisseur de cas en ligne:
def capitalize_line (line): tokens = line.split ('#') cap = jetons [-1] space_count = len (cap) - len (cap.lstrip ()) espacement = cap [: space_count] tokens [-1] = spacing + capitalize_heading (heading.lstrip ()) result = '#'. join (jetons) renvoie le résultat
À ce stade, nous pouvons capitaliser une rubrique Markdown. Il est temps de capitaliser tout un document Markdown. Ce code est assez simple: parcourez toutes les lignes, mettez en majuscule chaque ligne qui commence par un hachage et retournez le texte correctement mis en majuscule:
def capitalize_all_headings (markdown)
:capitalized = [] lines = markdown.split ('\ n') pour les lignes: if line.startswith ('#'): line = capitalize_line (line) print (line) capitalized.append (line) return '\ n '.join (en majuscule)
La fonction principale prend un document Markdown d’entrée, le capitalise et enregistre le résultat sous le nom "capitalized.md", que vous pouvez vérifier et utiliser. La seule chose à faire est de savoir si votre document Markdown contient des lignes sans en-tête qui commencent par un hachage. Cela peut arriver si vous bloquez des blocs de code contenant des commentaires Python ou bash.
Fait amusant - le tutoriel que vous lisez en ce moment a été mis à profit avec ce programme.
L'automatisation du navigateur vous permet de prendre le contrôle par programme des applications Web qui ne fournissent pas d'API. Ceci est utile principalement pour le remplissage de formulaires et d'autres activités Web interactives (en cliquant sur "Suivant" sur les CLUF longs?).
Selenium a été principalement conçu pour tester les applications Web, mais il est très efficace pour automatiser toute interaction basée sur un navigateur. Si vous y réfléchissez un peu, vous pouvez probablement trouver de nombreuses applications Web que vous pouvez automatiser et vous simplifier la vie..