登录 注册

<   Golang如何从html代码中提取img标签的图片地址

2025-09-06

在 Golang 中,你可以使用多种方法从 HTML 代码中提取 <img> 标签的图片地址。以下是一些常用的方法,从简单到复杂:

1. 使用 htmlquery (推荐,最简洁易用)

htmlquery 是一个非常方便的库,它提供了类似 CSS 选择器的语法来查询 HTML 文档。

首先,你需要安装它:

bash
go get github.com/antchfx/htmlquery


然后,你可以这样使用:

go
package main

import (
"fmt"
"log"
"net/http"
"strings"

"github.com/antchfx/htmlquery"
)

func main() {
htmlContent := `
<!DOCTYPE html>
<html>
<head>
<title>Example Page</title>
</head>
<body>
<h1>Images</h1>
<img src="https://example.com/images/logo.png" alt="Company Logo">
<p>Some text here.</p>
<img src="/assets/photo.jpg" alt="A nice photo">
<a href="somepage.html"><img src="thumbnail.gif"></a>
</body>
</html>
`

// 1. 加载 HTML 内容
doc, err := htmlquery.Parse(strings.NewReader(htmlContent))
if err != nil {
log.Fatalf("Failed to parse HTML: %!v(MISSING)", err)
}

// 2. 使用 XPath 查询所有的 img 标签
// //img[@src] 会选择所有有 src 属性的 img 标签
imgNodes, err := htmlquery.Query(doc, "//img[@src]")
if err != nil {
log.Fatalf("Failed to query img nodes: %!v(MISSING)", err)
}

fmt.Println("Extracted Image URLs:")
// 3. 遍历查询到的节点,提取 src 属性
for _, node := range imgNodes {
src := htmlquery.SelectAttr(node, "src")
if src != "" {
fmt.Println(src)
}
}

// --- 示例:从 URL 获取 HTML ---
fmt.Println("\n--- Extracting from URL ---")
url := "https://www.golang.org" // 替换成你想爬取的 URL
resp, err := http.Get(url)
if err != nil {
log.Fatalf("Failed to fetch URL: %!v(MISSING)", err)
}
defer resp.Body.Close()

docFromURL, err := htmlquery.Parse(resp.Body)
if err != nil {
log.Fatalf("Failed to parse HTML from URL: %!v(MISSING)", err)
}

imgNodesFromURL, err := htmlquery.Query(docFromURL, "//img[@src]")
if err != nil {
log.Fatalf("Failed to query img nodes from URL: %!v(MISSING)", err)
}

fmt.Printf("Images found on %!s(MISSING):\n", url)
for _, node := range imgNodesFromURL {
src := htmlquery.SelectAttr(node, "src")
if src != "" {
fmt.Println(src)
}
}
}


解释 htmlquery 的 XPath 表达式 //img[@src]

* //: 表示在整个文档中进行递归查找。
* img: 选择所有 <img> 标签。
* [@src]: 这是一个属性选择器,表示只选择那些具有 src 属性的 <img> 标签。

2. 使用 goquery (jQuery-like API)

goquery 模仿了 jQuery 的 API,如果你熟悉 JavaScript 的 jQuery,会觉得它很亲切。

首先,安装 goquery

bash
go get github.com/PuerkitoBio/goquery


然后,使用方法如下:

go
package main

import (
"fmt"
"log"
"net/http"
"strings"

"github.com/PuerkitoBio/goquery"
)

func main() {
htmlContent := `
<!DOCTYPE html>
<html>
<head>
<title>Example Page</title>
</head>
<body>
<h1>Images</h1>
<img src="https://example.com/images/logo.png" alt="Company Logo">
<p>Some text here.</p>
<img src="/assets/photo.jpg" alt="A nice photo">
<a href="somepage.html"><img src="thumbnail.gif"></a>
</body>
</html>
`

// 1. 使用 goquery 解析 HTML
doc, err := goquery.NewDocumentFromReader(strings.NewReader(htmlContent))
if err != nil {
log.Fatalf("Failed to parse HTML: %!v(MISSING)", err)
}

fmt.Println("Extracted Image URLs:")
// 2. 使用 CSS 选择器选择所有的 img 标签
// "img[src]" 会选择所有有 src 属性的 img 标签
doc.Find("img[src]").Each(func(i int, s *goquery.Selection) {
// 3. 提取 src 属性
src, exists := s.Attr("src")
if exists {
fmt.Println(src)
}
})

// --- 示例:从 URL 获取 HTML ---
fmt.Println("\n--- Extracting from URL ---")
url := "https://www.golang.org" // 替换成你想爬取的 URL
res, err := http.Get(url)
if err != nil {
log.Fatalf("Failed to fetch URL: %!v(MISSING)", err)
}
defer res.Body.Close()

docFromURL, err := goquery.NewDocumentFromReader(res.Body)
if err != nil {
log.Fatalf("Failed to parse HTML from URL: %!v(MISSING)", err)
}

fmt.Printf("Images found on %!s(MISSING):\n", url)
docFromURL.Find("img[src]").Each(func(i int, s *goquery.Selection) {
src, exists := s.Attr("src")
if exists {
fmt.Println(src)
}
})
}


解释 goquery 的 CSS 选择器 "img[src]"

* img: 选择所有 <img> 标签。
* [src]: 这是一个属性选择器,表示只选择那些具有 src 属性的 <img> 标签。

3. 使用标准库 htmlgolang.org/x/net/html (更底层)

如果你不想引入第三方库,可以使用 Golang 的标准库 html 来解析 HTML。这通常需要更底层的操作,包括遍历节点树。

go
package main

import (
"fmt"
"log"
"strings"

"golang.org/x/net/html"
)

func main() {
htmlContent := `
<!DOCTYPE html>
<html>
<head>
<title>Example Page</title>
</head>
<body>
<h1>Images</h1>
<img src="https://example.com/images/logo.png" alt="Company Logo">
<p>Some text here.</p>
<img src="/assets/photo.jpg" alt="A nice photo">
<a href="somepage.html"><img src="thumbnail.gif"></a>
</body>
</html>
`

// 1. 使用 html.Parse 解析 HTML
doc, err := html.Parse(strings.NewReader(htmlContent))
if err != nil {
log.Fatalf("Failed to parse HTML: %!v(MISSING)", err)
}

fmt.Println("Extracted Image URLs:")
// 2. 递归遍历节点树
var extractImages func(*html.Node)
extractImages = func(n *html.Node) {
// 检查当前节点是否是 img 标签
if n.Type == html.ElementNode && n.Data == "img" {
// 遍历 img 标签的属性
for _, a := range n.Attr {
if a.Key == "src" {
fmt.Println(a.Val)
break // 找到 src 属性后就停止遍历当前 img 标签的属性
}
}
}
// 递归遍历子节点
for c := n.FirstChild; c != nil; c = c.NextSibling {
extractImages(c)
}
}

extractImages(doc)
}


解释标准库方法:

* html.Parse(): 将 HTML 内容解析成一个 *html.Node 类型的树形结构。
* extractImages 函数:这是一个递归函数,用来遍历整个节点树。
* n.Type == html.ElementNode && n.Data == "img": 检查当前节点是否是一个 HTML 元素节点,并且其标签名是 img
* n.Attr: 这是一个 []html.Attribute 切片,包含了当前元素的属性。
* a.Key == "src": 查找 src 属性。
* a.Val: 获取 src 属性的值。
* n.FirstChildc.NextSibling: 用于遍历当前节点的子节点。

选择哪种方法?

* htmlquery: 如果你追求 简洁、易读、类似 CSS 选择器 的体验,并且不介意引入一个第三方库,这是 首选
* goquery: 如果你 熟悉 jQuery,并且喜欢这种面向对象、链式调用的风格,goquery 是一个很好的选择。
* 标准库 html: 如果你 严格要求不引入第三方库,或者需要 更精细地控制解析过程,可以使用标准库。但代码会相对复杂一些。

重要注意事项:

* 相对路径和绝对路径: 提取到的 src 属性值可能是相对路径(如 /images/logo.png)或绝对路径(如 https://example.com/images/logo.png)。在实际应用中,你可能需要根据你获取 HTML 的来源,将相对路径转换为完整的 URL。
* JavaScript 动态加载的图片: 上述方法只能提取 HTML 源代码中直接存在的 <img> 标签。如果图片是通过 JavaScript 动态加载的(例如,在用户滚动页面时加载),这些方法将无法捕获到。对于这种情况,你需要使用更强大的工具,如 headless browser(例如 chromedp)。
* HTML 的有效性: HTML 解析库通常能容忍一些不规范的 HTML,但过于破碎的 HTML 可能会导致解析失败或结果不准确。
* 网络请求: 如果你要从 URL 获取 HTML,记得使用 net/http 进行请求,并处理好 resp.Body.Close()

根据你的具体需求和偏好,选择最适合你的方法。对于大多数场景,htmlquery 是一个非常方便且高效的选择。

AI问答 发表 上传 拍照
BBSGOOD.COM ©2025  运行时间: