Contando caracteres de um arquivo HTML com Python

Oct 13 2020

Acabei de concluir o nível 2 do Desafio Python em pythonchallenge.com e estou no processo de aprender Python, então, por favor, tenha paciência comigo e quaisquer erros bobos que eu possa ter cometido.

Estou procurando algum feedback sobre o que eu poderia ter feito melhor em meu código. Duas áreas especificamente:

  • Como poderia ter identificado mais facilmente a seção de comentários do arquivo HTML? Eu usei um método improvisado que encontrou o final do comentário (ou o início tecnicamente, mas está contando a partir do final) e me deu alguns caracteres extras que eu fui capaz de reconhecer e antecipar (o extra "->" e "-"). Qual condição teria encontrado melhor esse comentário para que eu pudesse colocá-lo em uma nova string para ser contado?

Isto é o que escrevi:

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 este é o código-fonte HTML:

<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:
-->

<!--

Seguido por milhares de caracteres e o comentário termina com '->'

Respostas

2 fartgeek Oct 13 2020 at 20:36

Não tenho reputação suficiente para comentar, então devo dizer isso em uma resposta. Parece desajeitado de usar

    while x == 4:

e então faça

    x = 3

sempre que você quiser sair do loop. Parece melhor fazer

    while True:

e quando você quiser sair do circuito, faça

    break

Felicidades!

1 AJNeufeld Oct 14 2020 at 05:51

Código Redundante

pagetext = ""
pagetext = (page.text)

A primeira linha atribui uma string vazia a pagetext. A segunda linha ignora o conteúdo já existente pagetexte atribui um valor diferente à variável.

Por que se preocupar com a primeira declaração? Isso simplesmente torna o código mais longo, mais lento e mais difícil de entender.

Por que se preocupar com a (...)volta page.text? Eles também não estão servindo a nenhum propósito.

Nomes de Variáveis

Variáveis ​​como isão uma faca de dois gumes. Você o está usando como um índice de loop e, em seguida, para fazer referência a um local encontrado após o término do loop. Mas ipor si só não tem muito significado. posnpode ser mais claro. last_comment_posnseria muito mais claro, embora muito prolixo.

O PEP-8 recomenda o uso de sublinhados para separar palavras em nomes de variáveis: ou seja, char_countnão use charcountetc.

Procurando por uma seqüência de caracteres

As strings Python têm funções integradas para pesquisar uma substring em uma string maior. Por exemplo, str.findpode localizar rapidamente a primeira ocorrência de <!--no texto da página.

i = pagetext.find("<!--")

Mas você não está procurando pelo primeiro; você está procurando o último. Python novamente você tem coberto, com a função find inverso: str.rfind.

i = pagetext.rfind("<!--")

Mas isso ainda encontra o índice da última ocorrência. Você quer os caracteres após o marcador de comentário, então precisamos pular 4 caracteres adicionais:

if i >= 0:
    newstring = pagetext[i+4:]

Código melhorado

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)