การนับอักขระจากไฟล์ HTML ด้วย Python

Oct 13 2020

ฉันเพิ่งจบระดับ 2 ของ The 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_countไม่charcountเป็นต้น

ค้นหาสตริงของอักขระ

สตริง Python มีฟังก์ชันในตัวสำหรับค้นหาสตริงย่อยในสตริงที่ใหญ่กว่า ตัวอย่างเช่นstr.findสามารถค้นหาเหตุการณ์แรก<!--ในข้อความของหน้าได้อย่างรวดเร็ว

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

แต่คุณไม่ได้มองหาคนแรก คุณกำลังมองหาคนสุดท้าย 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)