英文:
goquery- Concatenate a tag with the one that follows
问题
一些背景信息,我刚开始学习Go语言(3或4天),但我开始对它感到更加熟悉了。
我正在尝试使用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>
我想要做以下操作:
- 提取
<h1...class="text">
的内容。 - 插入(并连接)提取的内容到
<p...class="text">
的内容中。 - 只对紧随在
<h1>
标签后面的<p>
标签进行操作。 - 对页面上的所有
<h1>
标签都进行操作。
所以我希望它的结果如下所示:
<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>
代码的开头如下:
package main
import (
"fmt"
"strings"
"github.com/PuerkitoBio/goquery"
)
func main() {
html_code := strings.NewReader(`code_example_above`)
doc, _ := goquery.NewDocumentFromReader(html_code)
我知道可以使用以下代码读取<h1...class="text">
:
h3_tag := doc.Find("h3 .text")
我也知道可以使用以下代码将<h1...class="text">
的内容添加到<p...class="text">
的内容中:
doc.Find("p .text").Before("h3 .text")
^但是这个命令会将<h1...class="text">
的内容插入到每个<p...class="text">
的内容之前。
然后,我发现了一个更接近我想要的结果的方法:
doc.Find("p .text").First().Before("h3 .text")
^这个命令将<h1...class="text">
的内容仅插入到第一个<p...class="text">
的内容之前(更接近我想要的结果)。
我还尝试使用goquery
的Each()
函数,但是我无法通过该方法更接近我想要的结果(尽管我确定可以使用Each()
来实现,对吗?)
我最大的问题是我无法找出如何将每个<h1...class="text">
与紧随其后的<p...class="text">
关联起来。
如果有帮助的话,<h1...class="text">
在我尝试解析的网页上总是紧随着<p...class="text">
。
我的大脑已经不够用了。有没有Go的天才知道如何做到这一点并愿意解释一下?提前谢谢。
编辑
我发现了另一种方法:
doc.Find("h1").Each(func(i int, s *goquery.Selection) {
nex := s.Next().Text()
fmt.Println(s.Text(), nex, "\n\n")
})
^这会打印出我想要的内容,即每个<h1...class="text">
的内容,后面紧跟着它的<p...class="text">
的内容。我原以为s.Next()
会输出下一个<h1>
的实例,但它输出的是doc
中的下一个标签——即正在迭代的*goquery.Selection
。这样正确吗?
或者,正如mattn
指出的,我也可以使用doc.Find("h1+p")
。
我仍然无法将<h1...class="text">
附加到<p...class="text">
上。我将其作为另一个问题发布,因为你可以将这个问题分解为多个问题,而且Mattn
已经回答了其中一个。
英文:
For some background info, I'm new to Go (3 or 4 days), but I'm starting to get more comfortable with it.
I'm trying to use goquery
to parse a webpage. (Eventually I want to put some of the data in a database). For my problem, an example will be the easiest way to explain it:
<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>
I'd like to:
- Extract the content of
<h1..."text"
. - Insert (and concatenate) this extracted content into the content of
<p..."text"
. - Only do this for the
<p>
tag that immediately follows the<h1>
tag. - Do this for all of the
<h1>
tags on the page.
So this is what I want it to look like:
<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>
With the code starting off like this,
package main
import (
"fmt"
"strings"
"github.com/PuerkitoBio/goquery"
)
func main() {
html_code := strings.NewReader(`code_example_above`)
doc, _ := goquery.NewDocumentFromReader(html_code)
I know that I can read <h1..."text"
with:
h3_tag := doc.Find("h3 .text")
I also know that I can add the content of <h1..."text"
to the content of <p..."text"
with this:
doc.Find("p .text").Before("h3 .text")
^But this command inserts the content from every single case of <h1..."text"
before every single case of <p..."text"
.
Then, I found out how to get a step closer to what I want:
doc.Find("p .text").First().Before("h3 .text")
^This command inserts the content from every single case of <h1..."text"
only before the first case of <p..."text"
(which is closer to what I want).
I also tried using goquery
's Each()
function, but I could not get any closer to what I wanted with that method (though I'm sure there's a way to do it with Each()
, right?)
My biggest issue is that I can't figure out how to associate each instance of <h1..."text"
with the <p..."text"
instance that immediately follows it.
If it helps, <h1..."text"
is always followed by <p..."text"
on the web pages I'm trying to parse.
My brain's out of juice. Do any Go geniuses know how to do this and are willing to explain it? Thanks in advance.
EDIT
I found out something else I can do:
doc.Find("h1").Each(func(i int, s *goquery.Selection) {
nex := s.Next().Text()
fmt.Println(s.Text(), nex, "\n\n")
})
^This prints out what I want--the contents of each instance of <h1..."text"
followed by its immediate instance of <p..."text"
. I had thought that s.Next()
would output the next instance of <h1>
, but it outputs the next tag in doc
--the *goquery.Selection
that it's iterating through. Is that correct?
Or, as mattn
pointed out, I could also use doc.Find("h1+p")
.
I'm still having trouble appending <h1..."text"
to <p..."text"
. I'll post it as another question because you can break this one down into multiple questions, and Mattn
already answered one.
答案1
得分: 1
我不知道你正在使用goquery编写什么代码。但也许,你期望的是邻居选择器。
h1+p
这将返回具有相邻的p标签的h1标签。
英文:
I don't know what you are writing code with goquery. But maybe, your expected is neighbor selector.
h1+p
This returns h1 tags which has p tag in neighbor.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论