gpt4 book ai didi

html - goquery- 从一个 html 标签中提取文本并将其添加到下一个标签

转载 作者:IT王子 更新时间:2023-10-29 01:06:51 25 4
gpt4 key购买 nike

是的,很抱歉标题没有解释任何内容。我需要举个例子。

这是另一个 question 的延续我发帖解决了一个问题,但不是所有问题。我已将该问题的大部分背景信息放入这个问题中。此外,我只研究了大约 5 天的 Go(我几个月前才开始学习代码),所以我 90% 确定我已经接近弄清楚我想要什么,问题是我有一些愚蠢的语法错误。

情况

我正在尝试使用 goquery解析网页。 (最终我想把一些数据放在数据库中)。这是它的样子:

<html>
<body>
<h1>
<span class="text">Go </span>
</h1>
<p>
<span class="text">totally </span>
<span class="post">kicks </span>
</p>
<p>
<span class="text">hacks </span>
<span class="post">its </span>
</p>
<h1>
<span class="text">debugger </span>
</h1>
<p>
<span class="text">should </span>
<span class="post">be </span>
</p>
<p>
<span class="text">called </span>
<span class="post">ogle </span>
</p>
<h3>
<span class="statement">true</span>
</h3>
</body>
<html>

目标

我想:

  1. 提取<h1..."text"的内容.
  2. 将提取的内容插入(并连接)到 <p..."text" 的内容中.
  3. 仅对 <p> 执行此操作紧跟 <h1> 的标签标签。
  4. <h1>所有 执行此操作页面上的标签。

再一次,一个例子可以更好地解释 ^this。这就是我想要的样子:

<html>
<body>
<p>
<span class="text">Go totally </span>
<span class="post">kicks </span>
</p>
<p>
<span class="text">hacks </span>
<span class="post">its </span>
</p>
<p>
<span class="text">debugger should </span>
<span class="post">be </span>
</p>
<p>
<span class="text">called </span>
<span class="post">ogle</span>
</p>
<h3>
<span class="statement">true</span>
</h3>
</body>
<html>

解决方案尝试

因为进一步区分<h1>来自 <p> 的标签标签会提供更多解析选项,我已经想出如何更改 class <h1> 的属性对此的标记:

<html>
<body>
<h1>
<span class="title">Go </span>
</h1>
<p>
<span class="text">totally </span>
<span class="post">kicks </span>
</p>
<p>
<span class="text">hacks </span>
<span class="post">its </span>
</p>
<h1>
<span class="title">debugger </span>
</h1>
<p>
<span class="text">should </span>
<span class="post">be </span>
</p>
<p>
<span class="text">called </span>
<span class="post">ogle </span>
</p>
<h3>
<span class="statement">true</span>
</h3>
</body>
<html>

使用此代码:

html_code := strings.NewReader(`
code_example_above
`)
doc, _ := goquery.NewDocumentFromReader(html_code)
doc.Find("h1").Each(func(i int, s *goquery.Selection) {
s.SetAttr("class", "title")
class, _ := s.Attr("class")
if class == "title" {
fmt.Println(class, s.Text())
}
})

我知道我可以选择 <p..."text"以下 <h1..."title"任一个 doc.Find("h1+p") s.Next()doc.Find("h1").Each里面功能:

doc.Find("h1").Each(func(i int, s *goquery.Selection) {
s.SetAttr("class", "title")
class, _ := s.Attr("class")
if class == "title" {
fmt.Println(class, s.Text())
fmt.Println(s.Next().Text())
}
})

我不知道如何插入来自 <h1..."title" 的文本至 <p..."text" .我试过使用 s.After() 的多种变体。 , s.Before() , 和 s.Append() ,例如,像这样:

doc.Find("h1").Each(func(i int, s *goquery.Selection) {
s.SetAttr("class", "title")
class, _ := s.Attr("class")
if class == "title" {
s.After(s.Text())
fmt.Println(s.Next().Text())
}
})

但我不知道如何做我想做的事情。

如果我使用 s.After(s.Next().Text())相反,我得到了这个错误输出:

panic: expected identifier, found 5 instead

goroutine 1 [running]:
code.google.com/p/cascadia.MustCompile(0xc2082f09a0, 0x62, 0x62)
/home/*/go/src/code.google.com/p/cascadia/selector.go:59 +0x77
github.com/PuerkitoBio/goquery.(*Selection).After(0xc2082ea630, 0xc2082f09a0, 0x62, 0x5)
/home/*/go/src/github.com/PuerkitoBio/goquery/manipulation.go:18 +0x32
main.func·001(0x0, 0xc2082ea630)
/home/*/go/test2.go:78 +0x106
github.com/PuerkitoBio/goquery.(*Selection).Each(0xc2082ea600, 0x7cb678, 0x2)
/home/*/go/src/github.com/PuerkitoBio/goquery/iteration.go:7 +0x173
main.ExampleScrape()
/home/*/go/test2.go:82 +0x213
main.main()
/home/*/go/test2.go:175 +0x1b

goroutine 9 [runnable]:
net/http.(*persistConn).readLoop(0xc208047ef0)
/usr/lib/go/src/net/http/transport.go:928 +0x9ce
created by net/http.(*Transport).dialConn
/usr/lib/go/src/net/http/transport.go:660 +0xc9f

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
/usr/lib/go/src/runtime/asm_amd64.s:2232 +0x1

goroutine 10 [select]:
net/http.(*persistConn).writeLoop(0xc208047ef0)
/usr/lib/go/src/net/http/transport.go:945 +0x41d
created by net/http.(*Transport).dialConn
/usr/lib/go/src/net/http/transport.go:661 +0xcbc
exit status 2

(我的脚本行与上面示例的行不匹配,但我脚本的“第 72 行”包含代码 s.After(s.Next().Text())。我不知道 panic: expected identifier, found 5 instead 到底是什么意思。)

总结

总而言之,我的问题是我不太清楚如何使用 goquery。将文本添加到标签。

我想我很接近。有地鼠绝地武士能够并愿意帮助这个学徒吗?

最佳答案

类似这段代码的工作,它找到所有 <h1>节点,然后是所有 <span>这些 <h1> 中的节点节点,寻找类 text 的节点.然后它获取 <h1> 的下一个元素节点,如果它是 <p> ,里面有一个 <span> , 然后它替换最后一个 <span>有了新的 <span>使用新文本并删除 <h1> .

我想知道是否可以使用 goquery 创建节点不用写 html...

package main

import (
"fmt"
"strings"

"github.com/PuerkitoBio/goquery"
)

var htmlCode string = `<html>
...
<html>`

func main() {
doc, _ := goquery.NewDocumentFromReader(strings.NewReader((htmlCode)))
doc.Find("h1").Each(func(i int, h1 *goquery.Selection) {
h1.Find("span").Each(func(j int, s *goquery.Selection) {
if s.HasClass("text") {
if p := h1.Next(); p != nil {
if ps := p.Children().First(); ps != nil && ps.HasClass("text") {
ps.ReplaceWithHtml(
fmt.Sprintf("<span class=\"text\">%s%s</span>)", s.Text(), ps.Text()))
h1.Remove()
}
}
}
})
})
htmlResult, _ := doc.Html()
fmt.Println(htmlResult)
}

关于html - goquery- 从一个 html 标签中提取文本并将其添加到下一个标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27828242/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com