使用 GoQuery 在换行符上拆分元素

Split element on line break with GoQuery

我正在尝试使用 GoQuery 从页面获取内容,但由于某些原因我无法在换行符处进行拆分 (br)。

HTML,看起来像这样:

<ul>
    <li>I'm skipped</li>

    <li> 
        Text Into  - <p>Whatever</p>
        <p>
            Line 1<br />
            Line 2<br />
            Line 3<br />
            Line 4<br />
            Line N
        </p>
    </li> 
</ul>

转到代码:

doc, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
    panic(err)
}

doc.Find("ul").Each(func(i int, s *goquery.Selection) {

    str := s.Find("li p").Next().Text()

    fmt.Println(str, "--")

})

出于某种原因,我无法获取每一行,用 p 标记中的分隔符分隔,因为上面的单个 item.Output 代码是:

Line1Line2Line3Line4LineN--

但我尝试实现的输出应该如下所示:

Line1--
Line2--
Line3--
Line4--
LineN--

由于我是 Go 新手,请在评论中告诉我如果有什么不清楚的地方,我会尽量解释。

谢谢。

好的,我设法找到了一个 solution.Not 当然如果这是正确的方法,所以如果有人有更好的东西 - 请分享它。

所以我基本上将 li p 的值存储为 HTML,然后使用 strings.Split 在每个 br 标记上断开,并且由于 strings.Split returns 一段字符串,我只是循环它。

title, err := s.Find("li p").Next().Html()
if err != nil {
    panic(err)
}

splittedTitles := strings.Split(title, "<br/>")

for _, str := range splittedTitles {
    fmt.Println(str, "--")
}

我 运行 你显示的代码,我在字符串中得到换行符。假设你使用的是最新版本的 goquery,你也应该是,除非你的html不是

<p>
    Line 1<br />
    Line 2<br />
    Line 3<br />
    Line 4<br />
    Line N
</p>

但实际上是这样的:

<p>
    Line 1<br />Line 2<br />Line 3<br />Line 4<br />Line N
</p>

(请记住,例如,当您打开 chrome 开发工具时,它可能 显示它 作为前者,即使实际来源是后者)

在这种情况下,这是预期的行为:

let html_1 = $(`<p>
        Line 1<br />
        Line 2<br />
        Line 3<br />
        Line 4<br />
        Line N
    </p>`);

let html_2 = $(`<p>
        Line 1<br />Line 2<br />Line 3<br />Line 4<br />Line N
    </p>`);
    
console.log({html1: html_1.text(), html2: html_2.text()});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

要解决,您可能只需要这样做:

p := s.Find("li p").Next()
p.SetHtml(strings.Replace(p.Html(), "<br />", "<br />\n", -1)).Text()

不过,您可能需要考虑是使用 <br/> 还是 <br /><br>,因为我不确定它会如何呈现。

.Text() 将:

Text gets the combined text contents of each element in the set of matched elements, including their descendants.

所以您真正想要做的是获取内容并过滤掉任何 br 标签。正如戴夫的回答所说,那里有换行符,所以我也修剪了那些:

package main

import (
    "fmt"
    "github.com/PuerkitoBio/goquery"
    "strings"
)

var input string = `
<ul>
    <li>I'm skipped</li>

    <li> 
        Text Into  - <p>Whatever</p>
        <p>
            Line 1<br />
            Line 2<br />
            Line 3<br />
            Line 4<br />
            Line N
        </p>
    </li> 
</ul>
`

func main() {
    doc, err := goquery.NewDocumentFromReader(strings.NewReader(input))
    if err != nil {
        panic(err)
    }

    doc.Find("ul").Each(func(i int, s *goquery.Selection) {

        p := s.Find("li p").Next()
        p.Contents().Each(func(i int, s *goquery.Selection) {
            if !s.Is("br") {
                fmt.Println(strings.TrimSpace(s.Text()), "--")
            }

        })

    })
}

生产:

Line 1 --
Line 2 --
Line 3 --
Line 4 --
Line N --

我认为如果您在调用 .Text() 方法之前将 <br/> 替换为 '\n' 或 '--' 会更好。

    // html is the result of `.Html()` method
    str := strings.Replace(html, "<br/>", "\n", -1)
    doc, err := goquery.NewDocumentFromReader(strings.NewReader(str))
    if err != nil {
        return ""
    }
    return doc.Text()