Compter les caractères d'un fichier HTML avec Python
Je viens de terminer le niveau 2 du Python Challenge sur pythonchallenge.com et je suis en train d'apprendre le python, alors s'il vous plaît, supportez-moi et toutes les erreurs stupides que j'ai pu faire.
Je recherche des commentaires sur ce que j'aurais pu mieux faire dans mon code. Deux domaines en particulier:
- Comment pourrais-je avoir identifié plus facilement la section des commentaires du fichier HTML? J'ai utilisé une méthode de beat-around-the-bush qui a en quelque sorte trouvé la fin du commentaire (ou le début techniquement mais cela compte à partir de la fin) et m'a donné quelques caractères supplémentaires que j'ai pu reconnaître et anticiper (le supplément "->" et "-"). Quelle condition aurait mieux trouvé ce commentaire pour que je puisse le mettre dans une nouvelle chaîne à compter?
Voici ce que j'ai écrit:
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)
Et voici le code HTML source:
<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:
-->
<!--
Suivi de milliers de caractères et le commentaire se termine par '->'
Réponses
Je n'ai pas assez de réputation pour commenter, donc je dois le dire dans une réponse. Il semble maladroit à utiliser
while x == 4:
puis fais
x = 3
chaque fois que vous voulez sortir de la boucle. Ça a l'air mieux de faire
while True:
et quand vous voulez sortir de la boucle, faites
break
À votre santé!
Code redondant
pagetext = ""
pagetext = (page.text)
La première ligne attribue une chaîne vide à pagetext. La deuxième ligne ignore le contenu déjà pagetextprésent et attribue une valeur différente à la variable.
Pourquoi s'embêter avec la première déclaration? Cela rend simplement le code plus long, plus lent et plus difficile à comprendre.
Pourquoi s'embêter avec les (...)alentours page.text? Ils ne servent aucun but.
Noms de variables
Des variables comme isont une arme à double tranchant. Vous l'utilisez comme index de boucle, puis vous l'utilisez pour référencer un emplacement trouvé une fois la boucle terminée. Mais ien soi, cela n'a pas beaucoup de sens. posnpourrait être plus clair. last_comment_posnserait beaucoup plus clair, bien que très verbeux.
PEP-8 recommande d'utiliser des traits de soulignement pour séparer les mots dans les noms de variables: c'est-à-dire, n'utilisez char_countpas charcountetc.
Recherche d'une chaîne de caractères
Les chaînes Python ont des fonctions intégrées pour rechercher une sous-chaîne dans une chaîne plus grande. Par exemple, str.findpourrait trouver rapidement la première occurrence de <!--dans le texte de la page.
i = pagetext.find("<!--")
Mais vous ne cherchez pas le premier; vous cherchez le dernier. Python à nouveau vous a couvert, la fonction de recherche inverse: str.rfind.
i = pagetext.rfind("<!--")
Mais cela trouve toujours l'index de la dernière occurrence. Vous voulez les caractères après le marqueur de commentaire, nous devons donc sauter 4 caractères supplémentaires:
if i >= 0:
newstring = pagetext[i+4:]
Code amélioré
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)