golang解析RSS和Atom订阅源的插件库gofeed的使用
Golang解析RSS和Atom订阅源的插件库gofeed的使用
Gofeed: 一个强大的Golang Feed解析器
gofeed
是一个强大灵活的库,用于解析各种格式和版本的RSS、Atom和JSON订阅源。它能有效处理非标准元素和已知扩展,并对常见的订阅源问题表现出良好的容错性。
特性
全面的订阅源支持
- RSS (0.90 到 2.0)
- Atom (0.3, 1.0)
- JSON (1.0, 1.1)
处理无效订阅源
gofeed
采用尽力而为的方法处理损坏或无效的XML订阅源,能够处理以下问题:
- 未转义的标记
- 未声明的命名空间前缀
- 缺失或非法的标签
- 错误的日期格式
- 以及其他问题
扩展支持
gofeed
将默认命名空间之外的元素视为扩展,将它们存储在Feed.Extensions和Item.Extensions下的树状结构中。这个特性让你可以轻松访问自定义扩展元素。
内置支持流行扩展:
- Dublin Core: 通过
Feed.DublinCoreExt
和Item.DublinCoreExt
访问 - Apple iTunes: 通过
Feed.ITunesExt
和Item.ITunesExt
访问
基本用法
通用订阅源解析器
从URL解析
fp := gofeed.NewParser()
feed, _ := fp.ParseURL("http://feeds.twit.tv/twit.xml")
fmt.Println(feed.Title)
从字符串解析
feedData := `<rss version="2.0">
<channel>
<title>Sample Feed</title>
</channel>
</rss>`
fp := gofeed.NewParser()
feed, _ := fp.ParseString(feedData)
fmt.Println(feed.Title)
从io.Reader解析
file, _ := os.Open("/path/to/a/file.xml")
defer file.Close()
fp := gofeed.NewParser()
feed, _ := fp.Parse(file)
fmt.Println(feed.Title)
带60秒超时的URL解析
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
fp := gofeed.NewParser()
feed, _ := fp.ParseURLWithContext("http://feeds.twit.tv/twit.xml", ctx)
fmt.Println(feed.Title)
带自定义User-Agent的URL解析
fp := gofeed.NewParser()
fp.UserAgent = "MyCustomAgent 1.0"
feed, _ := fp.ParseURL("http://feeds.twit.tv/twit.xml")
fmt.Println(feed.Title)
特定订阅源解析器
RSS订阅源
feedData := `<rss version="2.0">
<channel>
<webMaster>example@site.com (Example Name)</webMaster>
</channel>
</rss>`
fp := rss.Parser{}
rssFeed, _ := fp.Parse(strings.NewReader(feedData))
fmt.Println(rssFeed.WebMaster)
Atom订阅源
feedData := `<feed xmlns="http://www.w3.org/2005/Atom">
<subtitle>Example Atom</subtitle>
</feed>`
fp := atom.Parser{}
atomFeed, _ := fp.Parse(strings.NewReader(feedData))
fmt.Println(atomFeed.Subtitle)
JSON订阅源
feedData := `{"version":"1.0", "home_page_url": "https://daringfireball.net"}`
fp := json.Parser{}
jsonFeed, _ := fp.Parse(strings.NewReader(feedData))
fmt.Println(jsonFeed.HomePageURL)
高级用法
基本认证
fp := gofeed.NewParser()
fp.AuthConfig = &gofeed.Auth{
Username: "foo",
Password: "bar",
}
使用自定义翻译器进行高级解析
步骤1: 定义自定义翻译器
type MyCustomTranslator struct {
defaultTranslator *gofeed.DefaultRSSTranslator
}
func NewMyCustomTranslator() *MyCustomTranslator {
t := &MyCustomTranslator{}
t.defaultTranslator = &gofeed.DefaultRSSTranslator{}
return t
}
func (ct *MyCustomTranslator) Translate(feed interface{}) (*gofeed.Feed, error) {
rss, found := feed.(*rss.Feed)
if !found {
return nil, fmt.Errorf("Feed did not match expected type of *rss.Feed")
}
f, err := ct.defaultTranslator.Translate(rss)
if err != nil {
return nil, err
}
// 自定义逻辑,优先使用iTunes Author而非Managing Editor
if rss.ITunesExt != nil && rss.ITunesExt.Author != "" {
f.Author = rss.ITunesExt.Author
} else {
f.Author = rss.ManagingEditor
}
return f, nil
}
步骤2: 使用自定义翻译器
feedData := `<rss version="2.0">
<channel>
<managingEditor>Ender Wiggin</managingEditor>
<itunes:author>Valentine Wiggin</itunes:author>
</channel>
</rss>`
fp := gofeed.NewParser()
fp.RSSTranslator = NewMyCustomTranslator()
feed, _ := fp.ParseString(feedData)
fmt.Println(feed.Author) // Valentine Wiggin
依赖
- goxpp - XML Pull Parser
- goquery - Go jQuery-like接口
- testify - 单元测试增强
- jsoniter - 更快的JSON解析
许可证
本项目采用MIT许可证
致谢
- cristoper - 实现xml:base相对URI处理
- Mark Pilgrim和Kurt McKee - Universal Feed Parser Python库的灵感来源
- Dan MacTough - node-feedparser提供了混合gofeed.Feed模型应涵盖的字段集灵感
- Matt Jibson - goread项目中的日期解析函数
- Jim Teeuwen - go-pkg-rss库中表示任意订阅源扩展的方法
- Sudhanshu Raheja - 支持JSON Feed解析器
更多关于golang解析RSS和Atom订阅源的插件库gofeed的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang解析RSS和Atom订阅源的插件库gofeed的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用gofeed解析RSS和Atom订阅源
gofeed是一个流行的Go语言库,用于解析RSS和Atom格式的订阅源。它提供了简单易用的API,可以处理各种格式的feed,包括RSS 0.9x, RSS 2.0和Atom 1.0。
安装gofeed
首先需要安装gofeed库:
go get github.com/mmcdole/gofeed
基本用法
1. 解析远程feed
package main
import (
"fmt"
"github.com/mmcdole/gofeed"
)
func main() {
fp := gofeed.NewParser()
feed, err := fp.ParseURL("https://blog.golang.org/feed.atom")
if err != nil {
fmt.Printf("Error fetching feed: %v", err)
return
}
fmt.Println("Feed Title:", feed.Title)
fmt.Println("Feed Link:", feed.Link)
fmt.Println("Feed Description:", feed.Description)
fmt.Println("Last Updated:", feed.Updated)
for _, item := range feed.Items {
fmt.Println("\n---")
fmt.Println("Title:", item.Title)
fmt.Println("Link:", item.Link)
fmt.Println("Published:", item.Published)
fmt.Println("Description:", item.Description)
}
}
2. 解析本地feed文件
package main
import (
"fmt"
"github.com/mmcdole/gofeed"
"os"
)
func main() {
file, err := os.Open("feed.xml")
if err != nil {
fmt.Printf("Error opening file: %v", err)
return
}
defer file.Close()
fp := gofeed.NewParser()
feed, err := fp.Parse(file)
if err != nil {
fmt.Printf("Error parsing feed: %v", err)
return
}
fmt.Println("Feed Title:", feed.Title)
}
高级功能
1. 自定义解析器
fp := gofeed.NewParser()
fp.RSSTranslator = NewCustomTranslator() // 自定义RSS解析器
fp.AtomTranslator = NewCustomAtomTranslator() // 自定义Atom解析器
2. 处理不同类型的feed
fp := gofeed.NewParser()
feed, err := fp.ParseURL("https://example.com/feed")
if err != nil {
fmt.Printf("Error fetching feed: %v", err)
return
}
// 检查feed类型
if feed.FeedType == "rss" {
fmt.Println("This is an RSS feed")
} else if feed.FeedType == "atom" {
fmt.Println("This is an Atom feed")
}
3. 处理feed中的图片
for _, item := range feed.Items {
if item.Image != nil {
fmt.Println("Image URL:", item.Image.URL)
}
// 或者从扩展中获取图片
if ext, ok := item.Extensions["media"]; ok {
if contents, ok := ext["content"]; ok {
for _, content := range contents {
if content.Attrs["medium"] == "image" {
fmt.Println("Media Image:", content.Attrs["url"])
}
}
}
}
}
4. 处理作者信息
for _, item := range feed.Items {
if item.Author != nil {
fmt.Println("Author:", item.Author.Name)
fmt.Println("Author Email:", item.Author.Email)
}
}
错误处理
gofeed提供了详细的错误信息,可以帮助诊断解析问题:
feed, err := fp.ParseURL("https://example.com/feed")
if err != nil {
switch err.(type) {
case *gofeed.HTTPError:
fmt.Println("HTTP Error:", err)
case *gofeed.FeedTypeNotRecognizedError:
fmt.Println("Feed type not recognized:", err)
case *gofeed.FeedParseError:
fmt.Println("Feed parse error:", err)
default:
fmt.Println("Unknown error:", err)
}
return
}
性能考虑
对于需要频繁解析大量feed的应用,可以考虑重用解析器实例:
fp := gofeed.NewParser()
// 在循环中重用解析器
for _, feedURL := range feedURLs {
feed, err := fp.ParseURL(feedURL)
if err != nil {
continue
}
// 处理feed
}
gofeed是一个功能强大且灵活的库,可以满足大多数RSS和Atom解析需求。它支持各种feed格式,处理扩展元素,并提供了良好的错误处理机制。