正如标题中所述.我需要返回html文档的body标签内的所有内容,包括任何后续的html标签等.我很想知道最好的方法是什么.我有一个使用Gokogiri软件包的工作解决方案,但是我试图远离任何依赖于C库的软件包.有没有办法用go标准库实现这一目标?或者100%的套餐?
自从我发布原始问题以来,我试图使用以下没有解决问题的软件包.(这两者似乎都没有从身体内部返回后续的孩子或嵌套标签.例如:
<!DOCTYPE html>
<html>
<head>
<title>
Title of the document
</title>
</head>
<body>
body content
<p>more content</p>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
将返回正文内容,忽略后续<p>标记和它们包装的文本):
最重要的目标是获取一个看起来像这样的字符串或内容:
<body>
body content
<p>more content</p>
</body>
Run Code Online (Sandbox Code Playgroud)
Joa*_*che 31
这可以通过使用html包递归查找body节点,然后从该节点开始渲染html来解决.
package main
import (
"bytes"
"errors"
"fmt"
"golang.org/x/net/html"
"io"
"strings"
)
func Body(doc *html.Node) (*html.Node, error) {
var body *html.Node
var crawler func(*html.Node)
crawler = func(node *html.Node) {
if node.Type == html.ElementNode && node.Data == "body" {
body = node
return
}
for child := node.FirstChild; child != nil; child = child.NextSibling {
crawler(child)
}
}
crawler(doc)
if body != nil {
return body, nil
}
return nil, errors.New("Missing <body> in the node tree")
}
func renderNode(n *html.Node) string {
var buf bytes.Buffer
w := io.Writer(&buf)
html.Render(w, n)
return buf.String()
}
func main() {
doc, _ := html.Parse(strings.NewReader(htm))
bn, err := Body(doc)
if err != nil {
return
}
body := renderNode(bn)
fmt.Println(body)
}
const htm = `<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
body content
<p>more content</p>
</body>
</html>`
Run Code Online (Sandbox Code Playgroud)
它可以使用标准encoding/xml包完成.但它有点麻烦.在这个例子中,一个警告是它不包括封闭的body标签,但它将包含它的所有子节点.
package main
import (
"bytes"
"encoding/xml"
"fmt"
)
type html struct {
Body body `xml:"body"`
}
type body struct {
Content string `xml:",innerxml"`
}
func main() {
b := []byte(`<!DOCTYPE html>
<html>
<head>
<title>
Title of the document
</title>
</head>
<body>
body content
<p>more content</p>
</body>
</html>`)
h := html{}
err := xml.NewDecoder(bytes.NewBuffer(b)).Decode(&h)
if err != nil {
fmt.Println("error", err)
return
}
fmt.Println(h.Body.Content)
}
Run Code Online (Sandbox Code Playgroud)
可运行的例子:http:
//play.golang.org/p/ZH5iKyjRQp
由于你没有用html包显示你的尝试的源代码,我将不得不猜测你在做什么,但我怀疑你使用的是tokenizer而不是解析器.这是一个使用解析器并执行您要查找的程序:
package main
import (
"log"
"os"
"strings"
"github.com/andybalholm/cascadia"
"golang.org/x/net/html"
)
func main() {
r := strings.NewReader(`<!DOCTYPE html>
<html>
<head>
<title>
Title of the document
</title>
</head>
<body>
body content
<p>more content</p>
</body>
</html>`)
doc, err := html.Parse(r)
if err != nil {
log.Fatal(err)
}
body := cascadia.MustCompile("body").MatchFirst(doc)
html.Render(os.Stdout, body)
}
Run Code Online (Sandbox Code Playgroud)