Come ho imparato a smettere di preoccuparmi e ad amare lo strumento di capitalizzazione

Panoramica

Scrivo un sacco di tutorial per Envato Tuts +. Questi tutorial hanno intestazioni che devono seguire determinate regole di capitalizzazione. Tuts + fornisce a noi autori uno strumento basato sul web che prende il testo di un'intestazione e restituisce un'intestazione correttamente in maiuscolo. Quando scrivo le mie esercitazioni cerco di entrare nel flusso e il passaggio allo strumento di capitalizzazione interrompe il mio flusso. Ho usato semplicemente la vela e faccio la maiuscola. 

Ho scoperto che spesso commettevo errori, il che ha causato un ulteriore lavoro agli editori Tuts + che dovevano correggerli. Essendo un programmatore, ho deciso di programmare la mia via d'uscita dal problema. Scrivo ancora le mie intestazioni, ma quando ho finito, eseguo un piccolo programma Python che analizza il mio articolo, rileva tutte le intestazioni e poi le esegue attraverso il tool Tuts + maiuscole e capitalizza correttamente tutte le intestazioni. 

Poiché lo strumento di capitalizzazione è un'applicazione basata su Web e non un'API, ho dovuto automatizzare il browser per richiamarlo ed estrarre le intestazioni in maiuscolo. In questo tutorial imparerai come controllare il browser in Python tramite Selenium e fargli fare le tue offerte. 

Come capitalizzare le intestazioni

Capitalizzare i titoli non è una scienza missilistica, ma non è neanche banale. Esistono diversi stili, con alcune sovrapposizioni e alcune varianti. Questo è più o meno il consenso:

  • Capitalizza tutte le parole con quattro o più lettere.
  • Capitalizza sempre la prima e l'ultima parola.
  • Non capitalizzare articoli: a, an, the.
  • Non capitalizzare le congiunzioni brevi: e, o, né, per, ma, così, ancora.

Poi ci sono un sacco di eccezioni e situazioni speciali (ad esempio, l'intestazione scorre alla riga successiva). Ma questo è tutto discutibile. Anche se ho deciso di scrivere il mio codice di maiuscole, Tuts + ha già scelto il loro gusto e ho bisogno di conformarmi allo stile scelto.

Il convertitore di casi online

Lo strumento di capitalizzazione Tuts + è uno strumento interno destinato a essere utilizzato solo dagli istruttori di Tuts +, quindi non posso utilizzarlo come demo. Tuttavia, ho trovato uno strumento simile chiamato Title Case Converter. È un'applicazione web con un'ampia area di testo in cui è possibile digitare l'intestazione (o titolo), un pulsante di conversione che si fa clic per inviare il modulo, un'area di output che appare con un'intestazione correttamente in maiuscolo e infine un pulsante di copia che copia l'intestazione titolo convertito negli appunti.

Un piano per l'automazione dello strumento di capitalizzazione

OK. Utilizzerò il convertitore di casi online, ma non ci sono API. Questo non è un grosso problema. Posso automatizzare il browser e simulare un utente che digita l'intestazione nel campo di input, fare clic sul pulsante di conversione, attendere che l'output venga visualizzato, fare clic sul pulsante di copia e infine incollare l'intestazione correttamente in maiuscolo dagli Appunti.

Il primo passo è scegliere un'automazione del browser. Ho scelto Selenium WebDriver, che ho usato con successo prima. Il resto del piano è:

  • Avvia un browser.
  • Passare all'URL del convertitore case online.
  • Trova tutti gli elementi necessari.
  • Compila il campo di inserimento.
  • Invia il modulo.
  • Attendi l'uscita.
  • Fai clic sul pulsante di copia.
  • Leggi l'intestazione in maiuscolo dagli appunti.

Il codice sorgente completo può essere trovato su GitLab.

Introduzione al selenio

Selenium ha automatizzato i browser dal 2004. Nel 2008 si è fuso con il progetto WebDriver, che risolve alcuni dei limiti del Selenium originale (ad esempio, nell'esecuzione nella sandbox JavaScript). 

Il selenio offre ancora il sapore originale del selenio chiamato selenio RC (telecomando). Ha anche un IDE per scrivere suite di test automatizzate e uno strumento chiamato Selenium Grid che scala Selenium RC per suite di test di grandi dimensioni che devono essere eseguite in più ambienti. Ci limiteremo all'accesso programmatico al browser tramite l'API WebDriver (a.k.a Selenium 2).

Installazione di Selenium e un driver Web

Installare Selenium è semplice come pipenv selenio. Se non hai familiarità con Pipenv, controlla Revisionare Python Packaging con Pipenv. Hai anche bisogno di un driver web specifico. Esistono driver Web per diversi browser e back-end. È possibile trovare l'elenco completo sul sito Web di Selenium.

Ho scelto il driver web di Chrome per questo tutorial. Ecco l'ultima versione.

È un singolo file zip che contiene un singolo file eseguibile (ci sono versioni di Windows, macOS e Linux). Una volta scaricato, decomprimilo e rilascia il tuo percorso.

Congratulazioni! Ora sei pronto per usare Selenium WebDriver da Python.

Avvio del browser

Selenium semplifica molto il lancio di un browser. Finché hai il driver web giusto nel tuo percorso, devi semplicemente importare il selenium.webdriver modulo e chiama il metodo corretto per avviare il tuo browser di scelta:

da selenium import webdriver driver = webdriver.Chrome ()

Navigazione verso un URL

Una volta che hai un oggetto driver, puoi chiamare il ottenere() metodo per navigare in qualsiasi pagina web. Ecco come accedere al convertitore di Case Title: 

driver.get ( 'https://titlecaseconverter.com')

Trovare elementi

Abbiamo bisogno di un modo per individuare gli elementi nella pagina con cui vuoi interagire. Il modo più semplice è di ispezionare la pagina Web nel browser e trovare gli id ​​degli elementi di destinazione. Nello screenshot seguente, puoi vedere che il campo di input ha il "titolo" id:

Il pulsante di conversione non ha ID, ma non è un problema, come vedrai presto. Ecco il codice per individuare il modulo e i campi di testo per id:

input_field = driver.find_element_by_id ('title')

Se un elemento con cui vuoi interagire non ha un ID, puoi trovarlo usando vari altri metodi come nome, nome classe o selettore CSS. Vedi tutte le opzioni in questa guida del selenio.  

Ad esempio, per individuare il pulsante di conversione, ho usato il suo nome di classe:

convertButton = \ driver.find_element_by_class_name ('convertButton')

Popolazione di campi di testo

Per popolare il campo di input, possiamo usare il send_keys () metodo del nostro elemento del campo di input. Ma assicurati di cancellarlo prima. Altrimenti, aggiungerai semplicemente il testo esistente.

input_field.clear () input_field.send_keys (titolo) 

E 'stato abbastanza facile.

Fare clic sui pulsanti e inviare moduli

Ora è il momento di inviare il modulo. Puoi farlo in due modi:

  • Trova l'elemento del modulo sulla pagina e chiamane il relativo Sottoscrivi() metodo.
  • Trova il pulsante di conversione e fai clic.

Inizialmente ho inviato il modulo direttamente:

form = driver.find_element_by_css_selector ('body> form') form.submit () 

Per qualche ragione, non funziona. Non c'è errore, ma non succede nulla. Non ho speso troppo tempo a studiare perché l'intero punto di Selenium e questo tutorial è quello di simulare una persona. Quindi ho usato l'altro metodo e ho fatto clic sul pulsante che ho trovato prima:

convertButton.click ()

In attesa di invio di moduli

Il convertitore di case online è piuttosto elaborato. Il campo di output non esiste inizialmente. Dopo aver fatto clic sul pulsante di conversione e inviato il modulo, l'output viene visualizzato insieme al pulsante di copia. Ciò significa che dobbiamo attendere che l'invio del modulo sia completo prima che appaia il pulsante di copia e possiamo cliccarlo per copiare l'output negli Appunti.

Il selenio ti ha coperto. Ha il supporto per l'attesa di condizioni arbitrarie e il timeout se non si concretizzano. Ecco il codice che attende il pulsante di copia. Crea a WebDriverWait oggetto con un timeout di cinque secondi. Quindi crea una condizione per la presenza di un elemento con il nome della classe copyButton, e poi chiama l'oggetto di attesa fino a() metodo con la condizione.

wait = WebDriverWait (driver, 5) buttonPresent = presence_of_element_located ((By.CLASS_NAME, 'copyButton')) copyButton = wait.until (buttonPresent) 

Il risultato è che dopo aver fatto clic sul pulsante di conversione, attenderà fino a quando il pulsante di copia non verrà visualizzato o scadrà dopo cinque secondi. Se tutto va bene, restituirà il copyButton elemento.

Leggere la Intestazione capitalizzata

Puoi leggere il contenuto dei campi di testo con field.get_attribute ( 'valore'). Ma, come ho detto prima, il convertitore di case online è piuttosto stravagante. Il suo output è una struttura nidificata di spans e div e, quando si passa con il mouse su ciascuna parte dell'output, viene indicato il motivo per cui è in maiuscolo o in maiuscolo. 

Potrei scavare questo labirinto e analizzare la rotta attuale, ma c'è un modo più semplice. Il pulsante Copia copia l'intestazione in maiuscolo negli Appunti. Possiamo semplicemente fare clic sul pulsante e leggere l'intestazione dagli appunti. Ho usato il modulo appunti, che puoi installare con pipenv installa appunti. Il codice sottostante cancella gli appunti copiando una stringa vuota, fa clic sul pulsante di copia e legge ripetutamente gli appunti finché non è vuoto.

clipboard.copy (") copyButton.click () result = clipboard.paste () while not result: time.sleep (0.1) result = clipboard.paste ()

Capitalizzare un intero documento Markdown

OK. Possiamo capitalizzare un'unica voce. Ho inserito tutto questo codice in un'unica funzione:

def capitalize_heading (heading): input_field = driver.find_element_by_id ('title') input_field.clear () input_field.send_keys (heading) # form = driver.find_element_by_css_selector ('body> form') # form.submit () convertButton = \ driver .find_element_by_class_name ('convertButton') convertButton.click () # Attendi che appaia il pulsante copia wait = WebDriverWait (driver, 5) buttonPresent = presence_of_element_located ((By.CLASS_NAME, 'copyButton')) copyButton = wait.until (buttonPresent) Appunti .copy (") copyButton.click () result = clipboard.paste () while not result: time.sleep (0.1) result = clipboard.paste () restituisce risultato

Ora, armato di questa capacità, possiamo analizzare un intero articolo e capitalizzare tutti i titoli. Scrivo i miei tutorial in Markdown. Tutte le mie intestazioni iniziano con uno o più hash (#). 

Ho definito una funzione di aiuto che prende una linea e, se contiene un'intestazione, la capitalizza correttamente usando il comando capitalize_heading () funzione e restituisce il risultato. La cosa principale è spogliare tutti gli hash e gli spazi principali e ripristinarli in seguito. Non possiamo alimentare un'intestazione con spazi iniziali perché confonde il convertitore di casi online: 

def capitalize_line (line): tokens = line.split ('#') heading = token [-1] space_count = len (heading) - len (heading.lstrip ()) spacing = heading [: space_count] token [-1] = spaziatura + capitalize_heading (heading.lstrip ()) result = '#'. join (token) restituisce risultato

A questo punto, possiamo capitalizzare un'intestazione di Markdown. È ora di capitalizzare un intero documento Markdown. Questo codice è piuttosto semplice, iterato su tutte le righe, capitalizza ogni riga che inizia con un hash e restituisce il testo correttamente in maiuscolo:

def capitalize_all_headings (markdown):
 capitalized = [] lines = markdown.split ('\ n') per linee in linea: if line.startswith ('#'): line = capitalize_line (riga) print (riga) capitalized.append (riga) return '\ n ' .join (in maiuscolo)

La funzione principale prende un documento Markdown di input, lo capitalizza e salva il risultato come "capitalized.md", che puoi controllare e utilizzare. L'unica cosa da fare attenzione è se il tuo documento Markdown contiene righe non di intestazione che iniziano con un hash. Questo può accadere se si testa blocchi di codice che contengono commenti di bash o Python.

Fatto divertente: il tutorial che stai leggendo in questo momento è stato in maiuscolo utilizzando questo programma.

Conclusione

L'automazione del browser consente di assumere il controllo a livello di codice delle applicazioni Web che non forniscono un'API. Questo è utile soprattutto per il riempimento di moduli e altre attività web interattive (facendo clic su "Avanti" su EULA lunghi?). 

Selenium è stato progettato principalmente per testare le applicazioni Web, ma è ottimo per automatizzare qualsiasi interazione basata su browser. Se ci pensi un po ', puoi probabilmente trovare molte applicazioni web che puoi automatizzare e semplificarti la vita.