Подсчет символов из файла HTML с помощью Python

Oct 13 2020

Я только что завершил 2-й уровень Python Challenge на pythonchallenge.com и сейчас изучаю python, поэтому терпите меня и любые глупые ошибки, которые я мог совершить.

Я ищу отзывы о том, что я мог бы сделать лучше в своем коде. В частности, две области:

  • Как мне было легче определить раздел комментариев в HTML-файле? Я использовал метод обхода, который нашел конец комментария (или начало, технически, но он отсчитывается от конца) и дал мне несколько дополнительных символов, которые я смог распознать и предвидеть (дополнительные «->» и «-»). Какое условие лучше нашло бы этот комментарий, чтобы я мог поместить его в новую строку для подсчета?

Вот что я написал:

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)

А это исходный 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:
-->

<!--

За ним следуют тысячи символов, а комментарий заканчивается знаком '->'.

Ответы

2 fartgeek Oct 13 2020 at 20:36

У меня недостаточно репутации для комментариев, поэтому я должен сказать это в ответе. Выглядит неуклюже в использовании

    while x == 4:

а затем сделать

    x = 3

всякий раз, когда вы хотите вырваться из цикла. Похоже, лучше сделать

    while True:

и когда вы хотите выйти из цикла, сделайте

    break

Ура!

1 AJNeufeld Oct 14 2020 at 05:51

Резервный код

pagetext = ""
pagetext = (page.text)

Первая строка присваивает пустую строку pagetext. Вторая строка игнорирует уже существующее содержимое pagetextи присваивает переменной другое значение.

Зачем заморачиваться с первым утверждением? Это просто делает код длиннее, медленнее и труднее для понимания.

Зачем возиться с (...)окружающим page.text? Они также не служат никакой цели.

Имена переменных

Такие переменные i- это палка о двух концах. Вы используете его как индекс цикла, а затем используете его для ссылки на найденное местоположение после завершения цикла. Но iсамо по себе не имеет особого значения. posnможет быть яснее. last_comment_posnбыло бы намного яснее, хотя и очень многословно.

PEP-8 рекомендует использовать подчеркивания для разделения слов в именах переменных: т. Е. Использовать char_countnot charcountи т. Д.

Поиск строки символов

Строки Python имеют встроенные функции для поиска подстроки в более крупной строке. Например, str.findможно быстро найти первое вхождение <!--в текст страницы.

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

Но вы не ищете первого; вы ищете последний. Python снова покрывали Вас, с функцией обратной найти: str.rfind.

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

Но это все равно находит индекс последнего вхождения. Вам нужны символы после маркера комментария, поэтому нам нужно пропустить 4 дополнительных символа:

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

Улучшенный код

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)