使用 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()
我正在尝试使用 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()