Jag skriver en hel del handledning för Envato Tuts +. Dessa handledning har rubriker som måste följa vissa regler för kapitalisering. Tuts + ger oss författare ett webbaserat verktyg som tar texten i en rubrik och returnerar en riktigt aktiverad rubrik. När jag skriver min handledning försöker jag komma in i flödet, och byter till huvudverktyget bryter mitt flöde. Jag brukade bara flyga den och göra själva kapitaliseringen.
Det visar sig att jag ofta gjorde misstag, vilket orsakade extra arbete till Tuts + redaktörerna som var tvungna att rätta till dem. Som programmerare bestämde jag mig för att programmera mig ut ur problemet. Jag skriver fortfarande mina egna rubriker, men när jag är klar kör jag ett litet Python-program som analyserar min artikel, upptäcker alla rubriker, och kör dem sedan genom Tuts + capitalization-verktyget och aktiverar ordentligt alla rubriker.
Eftersom huvudverktyget är en webbaserad applikation och inte ett API, var jag tvungen att automatisera webbläsaren för att kunna ringa upp den och extrahera de aktiverade rubrikerna. I den här handledningen lär du dig hur du kontrollerar webbläsaren i Python via Selen och gör det att göra budgivning.
Att kapitalisera rubriker är inte raketvetenskap, men det är inte heller trivialt. Det finns flera stilar, med viss överlappning och vissa variationer. Detta är mer eller mindre konsensus:
Då finns det en massa undantag och speciella situationer (t ex rubrik strömmar till nästa rad). Men det här är allt. Även om jag bestämde mig för att skriva min egen kapitaliseringskod, valde Tuts + redan sin smak och jag måste överensstämma med sin valda stil.
Tuts + kapitaliseringsverktyget är ett internt verktyg som endast ska användas av Tuts + instruktörer, så jag kan inte använda dem som en demo. Men jag hittade ett liknande verktyg som heter Title Case Converter. Det är en webbapplikation med ett stort textområde där du kan skriva din rubrik (eller titel), en konverteringsknapp som du klickar på för att skicka formuläret, ett utmatningsområde som visas med en ordentlig aktiverad rubrik och slutligen en kopieringsknapp som kopierar konverterad rubrik till Urklipp.
OK. Jag ska använda den elektroniska fallkonverteraren, men det finns inget API. Detta är inte ett stort problem. Jag kan automatisera webbläsaren och simulera en användare som skriver rubriken i inmatningsfältet, klickar på knappen konvertera, väntar på att utmatningen ska dyka upp, klicka på kopieringsknappen och slutligen klistra in den ordinarie kapitaliserade rubriken från urklippet.
Det första steget är att välja en webbläsarautomatisering. Jag valde Selenium WebDriver, som jag har använt framgångsrikt tidigare. Resten av planen är:
Den fullständiga källkoden finns på GitLab.
Selen har automatiserat webbläsare sedan 2004. Under 2008 slogs det samman med WebDriver-projektet, som tar upp några av begränsningarna i det ursprungliga Seleniet (t ex körs i JavaScript-sandlådan).
Selen erbjuder fortfarande den ursprungliga smaken av Selen som kallas Selenium RC (fjärrkontroll). Det har också en IDE för att skriva automatiserade test sviter och ett verktyg som heter Selen Grid som vågar Selen RC för stora test sviter som måste köras i flera miljöer. Vi kommer att begränsa oss till programmatisk åtkomst till webbläsaren via WebDriver API (t.ex. Selen 2).
Installera Selen är lika enkelt som pipenv selen
. Om du inte är bekant med Pipenv, kolla in Revisiting Python Packaging With Pipenv. Du behöver också en viss webbdrivrutin. Det finns webdrivrutiner för olika webbläsare och bakändar. Du hittar den fullständiga listan på Selen-webbplatsen.
Jag valde Chrome-webdrivrutinen för den här handledningen. Här är den senaste versionen.
Det är en enda zip-fil som innehåller en enda körbar (det finns Windows, MacOS och Linux versioner). När du har laddat ner den, packa upp den och släpp den i din sökväg.
grattis! Du är nu redo att använda Selenium WebDriver från Python.
Selen gör det väldigt lätt att starta en webbläsare. Så länge du har rätt webbdrivrutin i din väg importerar du bara selenium.webdriver
modul och ring den rätta metoden för att starta din webbläsare efter eget val:
från selenimport webdriver driver = webdriver.Chrome ()
När du har ett förarobjekt kan du ringa skaffa sig()
metod för att navigera till vilken webbsida som helst. Så här navigerar du till Title Case Converter:
driver.get ( 'https://titlecaseconverter.com')
Vi behöver ett sätt att hitta elementen på sidan du vill interagera med. Det enklaste sättet är att inspektera webbsidan i webbläsaren och hitta ids för målelementen. I följande skärmdump kan du se att inmatningsfältet har id-titeln:
Omvandlingsknappen har inget ID, men det är inget problem som du ser snart. Här är koden för att hitta formuläret och textfälten med id:
input_field = driver.find_element_by_id ('title')
Om ett element du vill interagera med inte har ett ID kan du hitta det med hjälp av olika andra metoder, t.ex. namn, klassnamn eller CSS-väljare. Se alla alternativ i denna Selen guide.
Till exempel, för att hitta konvertera-knappen, använde jag sitt klassnamn:
convertButton = \ driver.find_element_by_class_name ('convertButton')
För att fylla i inmatningsfältet kan vi använda send_keys ()
metod för vårt inmatningsfältelement. Men se till att rensa den först. Annars lägger du bara till den befintliga texten.
input_field.clear () input_field.send_keys (rubrik)
Det var ganska enkelt.
Nu är det dags att skicka in formuläret. Du kan göra det på två sätt:
lämna()
metod.Jag lämnade in formuläret direkt:
form = driver.find_element_by_css_selector ('body> form') form.submit ()
Av någon anledning fungerar det inte. Det finns inget fel, men inget händer. Jag spenderade inte för mycket tid på att undersöka eftersom hela punkten i Selen och denna handledning är att simulera en person. Så jag använde den andra metoden och klickade bara på knappen jag hittat tidigare:
convertButton.click ()
Den elektroniska fallkonverteraren är lite snygg. Utmatningsfältet finns inte i början. När du klickar på knappen konvertera och formuläret skickas visas utmatningen tillsammans med kopieringsknappen. Det betyder att vi måste vänta tills formulärinsändningen är klar innan kopieringsknappen visas och vi kan klicka på den för att kopiera utmatningen till urklippet.
Selen har fått dig täckt. Den har stöd för att vänta på godtyckliga förutsättningar och tidsbestämma om de inte uppstår. Här är koden som väntar på kopieringsknappen. Det skapar en WebDriverWait
objekt med en fem-sekunders timeout. Det skapar då ett villkor för närvaron av ett element med klassnamnet copyButton
, och då kallas det vänta objektet fram tills()
metod med villkoret.
vänta = WebDriverWait (förare, 5) buttonPresent = presence_of_element_located ((By.CLASS_NAME, "copyButton")) copyButton = wait.until (buttonPresent)
Resultatet är att efter att ha klickat på knappen för att konvertera, väntar den tills kopieringsknappen visas eller går ut efter fem sekunder. Om allt är bra kommer det att returnera copyButton
element.
Du kan läsa innehållet i textfält med field.get_attribute ( 'värde')
. Men, som jag nämnde tidigare, är online-fallkonverteraren ganska snygg. Dess produktion är en kapslad struktur av spänner och div, och när du svävar över varje del av produktionen, berättar den dig varför den är aktiverad eller inte.
Jag kunde borra ner den här labyrinten och analysera den aktuella rubriken, men det finns ett enklare sätt. Kopieringsknappen kopierar den aktiverade rubriken till urklippet. Vi kan bara klicka på knappen och läsa rubriken från Urklipp. Jag använde urklippsmodulen, som du kan installera med pipenv installera urklipp
. Koden nedan rensar klippbordet genom att kopiera en tom sträng till den, klicka på kopieringsknappen och upprepade gånger läser urklippet tills det inte är tomt.
clipboard.copy (") copyButton.click () result = clipboard.paste () medan inte resultatet: time.sleep (0.1) result = clipboard.paste ()
OK. Vi kan kapitalisera ett enda rubrik. Jag lägger all denna kod i en enda funktion:
def capitalize_heading (rubrik): input_field = driver.find_element_by_id ('title') input_field.clear () input_field.send_keys (rubrik) # form = driver.find_element_by_css_selector ('body> form') # form.submit () convertButton = \ drivrutin .find_element_by_class_name ('convertButton') convertButton.click () # Vänta på att kopiera knappen visas wait = WebDriverWait (driver, 5) buttonPresent = presence_of_element_located ((By.CLASS_NAME, 'copyButton')) copyButton = wait.until (buttonPresent) Urklipp .copy (") copyButton.click () result = clipboard.paste () men inte resultat: time.sleep (0.1) result = clipboard.paste () returnera resultat
Nu beväpnad med denna förmåga kan vi analysera en hel artikel och kapitalisera alla rubriker. Jag skriver mina tutorials i Markdown. Alla mina rubriker börjar med en eller flera haschar (#).
Jag definierade en hjälpfunktion som tar en linje och, om den innehåller en rubrik, aktiverar den ordentligt med hjälp av capitalize_heading ()
funktionen och returnerar resultatet. Det viktigaste är att strippa alla ledande hash och utrymmen och återställa dem senare. Vi kan inte mata en rubrik med ledande utrymmen eftersom det förvirrar onlineomvandlaren:
def kapitalize_line (linje): tokens = line.split ('#') rubrik = tokens [-1] space_count = len (rubrik) - len (heading.lstrip ()) spacing = rubrik [: space_count] tokens [-1] = avstånd + capitalize_heading (heading.lstrip ()) result = '#'. gå med (tokens) returresultat
Vid denna tidpunkt kan vi kapitalisera en Markdown-rubrik. Det är dags att kapitalisera ett helt Markdown-dokument. Denna kod är ganska enkel-iterera över alla linjer, kapitalisera varje rad som börjar med en hash och returnera den ordentligt aktiverade texten:
def capitalize_all_headings (markdown)
:capitalized = [] lines = markdown.split ('\ n') för rad i rader: om line.startswith ('#'): line = capitalize_line (line) print (line) capitalized.append (line) return \ n ' .join (aktiverade)
Huvudfunktionen tar ett inmatningsmarknadsdokument, aktiverar det och sparar resultatet som "capitalized.md", vilket du kan kontrollera och använda. Det enda du måste vara försiktig med är om ditt Markdown-dokument innehåller rader utan rubrik som börjar med en hash. Detta kan hända om du innehåller huvudkodsblock som innehåller Python eller bash-kommentarer.
Roligt faktum - den handledning du läser just nu aktiverades med det här programmet.
Genom att automatisera webbläsaren kan du programmatiskt ta kontroll över webbapplikationer som inte tillhandahåller ett API. Det här är användbart mestadels för formulärfyllning och andra interaktiva webbaktiviteter (klicka på "Nästa" på långa EULA)?.
Selen var främst avsedd för testning av webbapplikationer, men det är bra att automatisera vilken webbläsarsamverkan som helst. Om du tycker lite, kan du förmodligen hitta många webbapplikationer som du kan automatisera och göra ditt liv enklare.