Обработка искаженного HTML с помощью Go / net / html tokenizer? - PullRequest
0 голосов
/ 09 февраля 2019

Я обнаружил, что html.NewTokenizer() не может автоматически исправить некоторые вещи.Так что вполне возможно, что вы можете получить блуждающий закрывающий тег (html.EndTagToken).Так что <div></p></div> будет html.StartTagToken, html.EndTagToken, html.EndTagToken.

Есть ли рекомендуемое решение для обработки игнорирования / удаления / исправления этих тегов?

Моим первым предположением было бы вручную сохранить слайс []atom.Atom и нажать / нажать длясписок при запуске / завершении каждого тега (после сравнения тега, чтобы убедиться, что вы не получили неожиданный конечный тег).

Вот код, демонстрирующий проблему:

var err error
htm := `<div><div><p></p></p></div>`

tokenizer := html.NewTokenizer(strings.NewReader(htm))

for {

    if tokenizer.Next() == html.ErrorToken {
        err = tokenizer.Err()
        if err == io.EOF {
            err = nil
        }

        return
    }

    token := tokenizer.Token()

    switch token.Type {
    case html.DoctypeToken:
        continue
    case html.CommentToken:
        continue
    case html.SelfClosingTagToken:
        fmt.Println(token.Data)
        continue
    case html.StartTagToken:
        fmt.Printf("<%s>\n", token.Data)

    case html.EndTagToken:
        fmt.Printf("</%s>\n", token.Data)

    case html.TextToken:
        continue
    default:
        continue
    }
}

Вывод:

<div>
<div>
<p>
</p>
</p>
</div>

1 Ответ

0 голосов
/ 10 февраля 2019

FWIW, похоже, что net/html может исправить такие проблемы, когда вы используете его метод Parse.Вот пример, адаптированный из другого ответа SO с использованием вашего искаженного фрагмента HTML:

package main

import (
    "bytes"
    "fmt"
    "log"
    "strings"

    "golang.org/x/net/html"
)

func main() {
    brokenHtml := `<div><div><p></p></p></div>`

    reader := strings.NewReader(brokenHtml)
    root, err := html.Parse(reader)

    if err != nil {
        log.Fatal(err)
    }

    var b bytes.Buffer
    html.Render(&b, root)
    fixedHtml := b.String()

    fmt.Println(fixedHtml)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...