Conteggio dei caratteri da un file HTML con Python
Ho appena completato il livello 2 di The Python Challenge su pythonchallenge.com e sto imparando Python quindi per favore abbi pazienza con me e qualsiasi stupido errore che potrei aver fatto.
Sto cercando un feedback su cosa avrei potuto fare di meglio nel mio codice. Due aree in particolare:
- Come avrei potuto identificare più facilmente la sezione dei commenti del file HTML? Ho usato un metodo beat-around-the-bush che ha trovato la fine del commento (o l'inizio tecnicamente ma sta contando dalla fine) e mi ha dato alcuni caratteri extra che ero in grado di riconoscere e anticipare (l'extra "->" e "-"). Quale condizione avrebbe trovato meglio questo commento in modo da poterlo inserire in una nuova stringa da contare?
Questo è quello che ho scritto:
from collections import Counter
import requests
page = requests.get('http://www.pythonchallenge.com/pc/def/ocr.html')
pagetext = ""
pagetext = (page.text)
#find out what number we are going back to
i = 1
x = 4
testchar = ""
testcharstring = ""
while x == 4:
testcharstring = pagetext[-i:]
testchar = testcharstring[0]
if testchar == "-":
testcharstring = pagetext[-(i+1)]
testchar = testcharstring[0]
if testchar == "-":
testcharstring = pagetext[-(i+2)]
testchar = testcharstring[0]
if testchar == "!":
testcharstring = pagetext[-(i+3)]
testchar = testcharstring[0]
if testchar == "<":
x = 3
else:
i += 1
x = 4
else:
i += 1
x = 4
else:
i += 1
print(i)
newstring = pagetext[-i:]
charcount = Counter(newstring)
print(charcount)
E questo è il codice HTML sorgente:
<html>
<head>
<title>ocr</title>
<link rel="stylesheet" type="text/css" href="../style.css">
</head>
<body>
<center><img src="ocr.jpg">
<br><font color="#c03000">
recognize the characters. maybe they are in the book, <br>but MAYBE they
are in the page source.</center>
<br>
<br>
<br>
<font size="-1" color="gold">
General tips:
<li>Use the hints. They are helpful, most of the times.</li>
<li>Investigate the data given to you.</li>
<li>Avoid looking for spoilers.</li>
<br>
Forums: <a href="http://www.pythonchallenge.com/forums"/>Python Challenge Forums</a>,
read before you post.
<br>
IRC: irc.freenode.net #pythonchallenge
<br><br>
To see the solutions to the previous level, replace pc with pcc, i.e. go
to: http://www.pythonchallenge.com/pcc/def/ocr.html
</body>
</html>
<!--
find rare characters in the mess below:
-->
<!--
Seguito da migliaia di caratteri e il commento si conclude con "->"
Risposte
Non ho abbastanza reputazione per commentare, quindi devo dirlo in una risposta. Sembra goffo da usare
while x == 4:
e poi fallo
x = 3
ogni volta che vuoi uscire dal giro. Sembra meglio da fare
while True:
e quando vuoi uscire dal giro fai
break
Saluti!
Codice ridondante
pagetext = ""
pagetext = (page.text)
La prima riga assegna una stringa vuota a pagetext. La seconda riga ignora i contenuti già presenti pagetexte assegna un valore diverso alla variabile.
Perché preoccuparsi della prima affermazione? Rende semplicemente il codice più lungo, più lento e più difficile da capire.
Perché preoccuparsi dei (...)dintorni page.text? Inoltre non servono a nessuno scopo.
Nomi variabili
Variabili come isono un'arma a doppio taglio. Lo stai usando come indice del ciclo e quindi lo stai usando per fare riferimento a una posizione trovata dopo che il ciclo è terminato. Ma di iper sé non ha molto significato. posnpotrebbe essere più chiaro. last_comment_posnsarebbe molto più chiaro, anche se molto prolisso.
PEP-8 consiglia di utilizzare trattini bassi per separare le parole nei nomi delle variabili: ad esempio, char_countnon utilizzare charcountecc.
Ricerca di una stringa di caratteri
Le stringhe Python hanno funzioni incorporate per la ricerca di una sottostringa in una stringa più grande. Ad esempio, str.findpotrebbe trovare rapidamente la prima occorrenza di <!--nel testo della pagina.
i = pagetext.find("<!--")
Ma non stai cercando il primo; stai cercando l'ultimo. Python di nuovo ha coperto, con la funzione find inverso: str.rfind.
i = pagetext.rfind("<!--")
Ma questo trova ancora l'indice dell'ultima occorrenza. Vuoi i caratteri dopo il marcatore di commento, quindi dobbiamo saltare avanti di 4 caratteri aggiuntivi:
if i >= 0:
newstring = pagetext[i+4:]
Codice migliorato
import requests
from collections import Counter
page = requests.get('http://www.pythonchallenge.com/pc/def/ocr.html')
page.raise_for_status() # Crash if the request didn't succeed
page_text = page.text
posn = page_text.rfind("<!--")
print(posn)
if posn >= 0:
comment_text = page_text[posn+4:] # Fix! This is to end of string, not end of comment!
char_count = Counter(comment_text)
print(char_count)