Đếm ký tự từ tệp HTML với Python

Oct 13 2020

Tôi vừa hoàn thành cấp độ 2 của Thử thách Python trên pythonchallenge.com và tôi đang trong quá trình học python nên hãy chịu khó và mọi lỗi ngớ ngẩn mà tôi có thể đã mắc phải.

Tôi đang tìm kiếm một số phản hồi về những gì tôi có thể đã làm tốt hơn trong mã của mình. Hai lĩnh vực cụ thể:

  • Làm cách nào để tôi có thể dễ dàng xác định phần bình luận của tệp HTML hơn? Tôi đã sử dụng phương pháp beat-around-the-bush để tìm thấy phần cuối của nhận xét (hoặc phần đầu về mặt kỹ thuật nhưng nó được tính từ phần cuối) và cung cấp cho tôi một số ký tự bổ sung mà tôi có thể nhận ra và dự đoán (phần bổ sung "->" và "-"). Điều kiện nào tốt hơn nên tìm thấy nhận xét này để tôi có thể đặt nó vào một chuỗi mới để được tính?

Đây là những gì tôi đã viết:

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)

Và đây là HTML nguồn:

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

<!--

Theo sau là hàng nghìn ký tự và nhận xét kết thúc bằng '->'

Trả lời

2 fartgeek Oct 13 2020 at 20:36

Tôi không có đủ danh tiếng để bình luận, vì vậy tôi phải nói điều này trong một câu trả lời. Nó trông rất khó sử dụng

    while x == 4:

và sau đó làm

    x = 3

bất cứ khi nào bạn muốn thoát ra khỏi vòng lặp. Có vẻ tốt hơn để làm

    while True:

và khi bạn muốn thoát ra khỏi vòng lặp, hãy làm

    break

Chúc mừng!

1 AJNeufeld Oct 14 2020 at 05:51

Mã dự phòng

pagetext = ""
pagetext = (page.text)

Dòng đầu tiên gán một chuỗi trống cho pagetext. Dòng thứ hai bỏ qua nội dung đã có pagetextvà gán một giá trị khác cho biến.

Tại sao phải bận tâm với tuyên bố đầu tiên? Nó chỉ đơn giản là làm cho mã dài hơn, chậm hơn và khó hiểu hơn.

Tại sao phải bận tâm với (...)xung quanh page.text? Họ cũng không phục vụ bất kỳ mục đích nào.

Tên biến

Biến like ilà một con dao hai lưỡi. Bạn đang sử dụng nó như một chỉ mục vòng lặp, và sau đó bạn đang sử dụng nó để tham chiếu đến một vị trí được tìm thấy sau khi vòng lặp kết thúc. Nhưng itự nó không có nhiều ý nghĩa. posncó thể rõ ràng hơn. last_comment_posnsẽ rõ ràng hơn nhiều, mặc dù rất dài dòng.

PEP-8 khuyến nghị sử dụng dấu gạch dưới để tách các từ trong tên biến: tức là, char_countkhông sử dụng, charcountv.v.

Tìm kiếm một chuỗi ký tự

Chuỗi Python có các hàm tích hợp để tìm kiếm một chuỗi con trong một chuỗi lớn hơn. Ví dụ, str.findcó thể nhanh chóng tìm thấy lần xuất hiện đầu tiên của <!--văn bản trang.

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

Nhưng bạn không tìm kiếm cái đầu tiên; bạn đang tìm kiếm cái cuối cùng. Python một lần nữa bạn có bảo hiểm, với chức năng tìm ngược lại: str.rfind.

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

Nhưng điều này vẫn tìm thấy chỉ mục của lần xuất hiện cuối cùng. Bạn muốn các ký tự sau điểm đánh dấu nhận xét, vì vậy chúng ta cần bỏ qua 4 ký tự bổ sung sau:

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

Cải tiến mã

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)