{"id":13367133,"url":"https://github.com/mmcdole/Gofeed","last_synced_at":"2025-03-12T18:31:56.192Z","repository":{"id":37405561,"uuid":"50220146","full_name":"mmcdole/gofeed","owner":"mmcdole","description":"Parse RSS, Atom and JSON feeds in Go","archived":false,"fork":false,"pushed_at":"2025-01-03T00:17:58.000Z","size":11116,"stargazers_count":2655,"open_issues_count":43,"forks_count":210,"subscribers_count":44,"default_branch":"master","last_synced_at":"2025-03-11T14:42:26.848Z","etag":null,"topics":["atom","atom-feed","feed","go","golang","jsonfeed","parser","rss","rss-feed"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mmcdole.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-01-23T02:44:34.000Z","updated_at":"2025-03-09T16:45:20.000Z","dependencies_parsed_at":"2024-03-01T04:30:02.027Z","dependency_job_id":"3417337c-92a1-4106-8758-00aa1e3b23c3","html_url":"https://github.com/mmcdole/gofeed","commit_stats":{"total_commits":187,"total_committers":50,"mean_commits":3.74,"dds":0.53475935828877,"last_synced_commit":"9455e2b8fe26b593582a0018c18b3a1aa58f2afe"},"previous_names":["mmcdole/go-feed"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmcdole%2Fgofeed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmcdole%2Fgofeed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmcdole%2Fgofeed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmcdole%2Fgofeed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mmcdole","download_url":"https://codeload.github.com/mmcdole/gofeed/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243271443,"owners_count":20264457,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atom","atom-feed","feed","go","golang","jsonfeed","parser","rss","rss-feed"],"created_at":"2024-07-30T00:01:39.364Z","updated_at":"2025-03-12T18:31:56.165Z","avatar_url":"https://github.com/mmcdole.png","language":"Go","readme":"# gofeed\n\n[![Build Status](https://travis-ci.org/mmcdole/gofeed.svg?branch=master)](https://travis-ci.org/mmcdole/gofeed) [![Coverage Status](https://coveralls.io/repos/github/mmcdole/gofeed/badge.svg?branch=master)](https://coveralls.io/github/mmcdole/gofeed?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/mmcdole/gofeed)](https://goreportcard.com/report/github.com/mmcdole/gofeed) [![](https://godoc.org/github.com/mmcdole/gofeed?status.svg)](http://godoc.org/github.com/mmcdole/gofeed) [![License](http://img.shields.io/:license-mit-blue.svg)](http://doge.mit-license.org)\n\n# Gofeed: A Robust Feed Parser for Golang\n\n\u003cimg src=\"https://github.com/mmcdole/gofeed/assets/3767096/ab4e7b0e-1472-4249-880c-c6784000ed31\" width=\"150\" height=\"150\"\u003e \n\u003cbr /\u003e\u003cbr /\u003e\n\n`gofeed` is a powerful and flexible library designed for parsing **RSS**, **Atom**, and **JSON** feeds across various formats and versions. It effectively manages non-standard elements and known extensions, and demonstrates resilience against common feed issues.\n\n## Table of Contents\n- [Features](#features)\n- [Overview](#overview)\n- [Basic Usage](#basic-usage)\n- [Advanced Usage](#advanced-usage)\n- [Dependencies](#dependencies)\n- [License](#license)\n- [Credits](#credits)\n\n## Features\n\n### Comprehensive Feed Support\n- RSS (0.90 to 2.0)\n- Atom (0.3, 1.0)\n- JSON (1.0, 1.1)\n\n### Handling Invalid Feeds\n`gofeed` takes a best-effort approach to deal with broken or invalid XML feeds, capable of handling issues like:\n- Unescaped markup\n- Undeclared namespace prefixes\n- Missing or illegal tags\n- Incorrect date formats\n- ...and more.\n\n### Extension Support\n\n`gofeed` treats elements outside the feed's default namespace as extensions, storing them in tree-like structures under Feed.Extensions and Item.Extensions. This feature allows you to access custom extension elements easily.\n\nBuilt-In Support for Popular Extensions\nFor added convenience, gofeed includes native support for parsing certain well-known extensions into dedicated structs. Currently, it supports:\n\n- Dublin Core: Accessible via `Feed.DublinCoreExt` and `Item.DublinCoreExt`\n- Apple iTunes: Accessible via `Feed.ITunesExt` and `Item.ITunesExt`\n  \n## Overview\n\nIn `gofeed`, you have two primary choices for feed parsing: a universal parser for handling multiple feed types seamlessly, and specialized parsers for more granular control over individual feed types.\n\n\n### Universal Feed Parser \n\nThe universal `gofeed.Parser` is designed to make it easy to work with various types of feeds—RSS, Atom, JSON—by converting them into a unified `gofeed.Feed` model. This is especially useful when you're dealing with multiple feed formats and you want to treat them the same way.\n\nThe universal parser uses built-in translators like `DefaultRSSTranslator`, `DefaultAtomTranslator`, and `DefaultJSONTranslator` to convert between the specific feed types and the universal feed. Not happy with the defaults? Implement your own `gofeed.Translator` to tailor the translation process to your needs.\n\n### Specialized Feed Parsers: RSS, Atom, JSON\n\nAlternatively, if your focus is on a single feed type, then using a specialized parser offers advantages in terms of performance and granularity. For example, if you're interested solely in RSS feeds, you can use `rss.Parser` directly. These feed-specific parsers map fields to their corresponding models, ensuring names and structures that match the feed type exactly.\n\n## Basic Usage\n\n### Universal Feed Parser\n\nHere's how to parse feeds using `gofeed.Parser`:\n\n#### From a URL\n```go\nfp := gofeed.NewParser()\nfeed, _ := fp.ParseURL(\"http://feeds.twit.tv/twit.xml\")\nfmt.Println(feed.Title)\n```\n\n#### From a String\n\n```go\nfeedData := `\u003crss version=\"2.0\"\u003e\n\u003cchannel\u003e\n\u003ctitle\u003eSample Feed\u003c/title\u003e\n\u003c/channel\u003e\n\u003c/rss\u003e`\nfp := gofeed.NewParser()\nfeed, _ := fp.ParseString(feedData)\nfmt.Println(feed.Title)\n```\n\n#### From an io.Reader\n\n```go\nfile, _ := os.Open(\"/path/to/a/file.xml\")\ndefer file.Close()\nfp := gofeed.NewParser()\nfeed, _ := fp.Parse(file)\nfmt.Println(feed.Title)\n```\n\n#### From a URL with a 60s Timeout\n\n```go\nctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)\ndefer cancel()\nfp := gofeed.NewParser()\nfeed, _ := fp.ParseURLWithContext(\"http://feeds.twit.tv/twit.xml\", ctx)\nfmt.Println(feed.Title)\n```\n\n#### From a URL with a Custom User-Agent\n\n```go\nfp := gofeed.NewParser()\nfp.UserAgent = \"MyCustomAgent 1.0\"\nfeed, _ := fp.ParseURL(\"http://feeds.twit.tv/twit.xml\")\nfmt.Println(feed.Title)\n```\n\n### Feed Specific Parsers\n\nIf you have a usage scenario that requires a specialized parser:\n\n#### RSS Feed\n\n```go\nfeedData := `\u003crss version=\"2.0\"\u003e\n\u003cchannel\u003e\n\u003cwebMaster\u003eexample@site.com (Example Name)\u003c/webMaster\u003e\n\u003c/channel\u003e\n\u003c/rss\u003e`\nfp := rss.Parser{}\nrssFeed, _ := fp.Parse(strings.NewReader(feedData))\nfmt.Println(rssFeed.WebMaster)\n```\n\n#### Atom Feed\n\n```go\nfeedData := `\u003cfeed xmlns=\"http://www.w3.org/2005/Atom\"\u003e\n\u003csubtitle\u003eExample Atom\u003c/subtitle\u003e\n\u003c/feed\u003e`\nfp := atom.Parser{}\natomFeed, _ := fp.Parse(strings.NewReader(feedData))\nfmt.Println(atomFeed.Subtitle)\n```\n\n#### JSON Feed\n\n```go\nfeedData := `{\"version\":\"1.0\", \"home_page_url\": \"https://daringfireball.net\"}`\nfp := json.Parser{}\njsonFeed, _ := fp.Parse(strings.NewReader(feedData))\nfmt.Println(jsonFeed.HomePageURL)\n```\n\n## Advanced Usage\n\n#### With Basic Authentication\n\n```go\nfp := gofeed.NewParser()\nfp.AuthConfig = \u0026gofeed.Auth{\n  Username: \"foo\",\n  Password: \"bar\",\n}\n```\n\n#### Using Custom Translators for Advanced Parsing\n\nIf you need more control over how fields are parsed and prioritized, you can specify your own custom translator. Below is an example that shows how to create a custom translator to give the `/rss/channel/itunes:author` field higher precedence than the `/rss/channel/managingEditor` field in RSS feeds.\n\n##### Step 1: Define Your Custom Translator\n\nFirst, we'll create a new type that embeds the default RSS translator provided by the library. We'll override its Translate method to implement our custom logic.\n\n```go\ntype MyCustomTranslator struct {\n  defaultTranslator *gofeed.DefaultRSSTranslator\n}\n\nfunc NewMyCustomTranslator() *MyCustomTranslator {\n  t := \u0026MyCustomTranslator{}\n  t.defaultTranslator = \u0026gofeed.DefaultRSSTranslator{}\n  return t\n}\n\nfunc (ct *MyCustomTranslator) Translate(feed interface{}) (*gofeed.Feed, error) {\n  rss, found := feed.(*rss.Feed)\n  if !found {\n    return nil, fmt.Errorf(\"Feed did not match expected type of *rss.Feed\")\n  }\n\n  f, err := ct.defaultTranslator.Translate(rss)\n  if err != nil {\n    return nil, err\n  }\n\n  // Custom logic to prioritize iTunes Author over Managing Editor\n  if rss.ITunesExt != nil \u0026\u0026 rss.ITunesExt.Author != \"\" {\n    f.Author = rss.ITunesExt.Author\n  } else {\n    f.Author = rss.ManagingEditor\n  }\n  \n  return f, nil\n}\n```\n\n##### Step 2: Use Your Custom Translator\n\nOnce your custom translator is defined, you can tell gofeed.Parser to use it instead of the default one.\n\n```go\nfeedData := `\u003crss version=\"2.0\"\u003e\n\u003cchannel\u003e\n\u003cmanagingEditor\u003eEnder Wiggin\u003c/managingEditor\u003e\n\u003citunes:author\u003eValentine Wiggin\u003c/itunes:author\u003e\n\u003c/channel\u003e\n\u003c/rss\u003e`\n\nfp := gofeed.NewParser()\nfp.RSSTranslator = NewMyCustomTranslator()\nfeed, _ := fp.ParseString(feedData)\nfmt.Println(feed.Author) // Valentine Wiggin\n```\n\n## Dependencies\n\n* [goxpp](https://github.com/mmcdole/goxpp) - XML Pull Parser\n* [goquery](https://github.com/PuerkitoBio/goquery) - Go jQuery-like interface\n* [testify](https://github.com/stretchr/testify) - Unit test enhancements\n* [jsoniter](https://github.com/json-iterator/go) - Faster JSON Parsing\n\n## License\n\nThis project is licensed under the [MIT License](https://raw.githubusercontent.com/mmcdole/gofeed/master/LICENSE)\n\n## Credits\n\n* [cristoper](https://github.com/cristoper) for his work on implementing xml:base relative URI handling.\n* [Mark Pilgrim](https://en.wikipedia.org/wiki/Mark_Pilgrim) and [Kurt McKee](http://kurtmckee.org) for their work on the excellent [Universal Feed Parser](https://github.com/kurtmckee/feedparser) Python library. This library was the inspiration for the `gofeed` library.\n* [Dan MacTough](http://blog.mact.me) for his work on [node-feedparser](https://github.com/danmactough/node-feedparser). It provided inspiration for the set of fields that should be covered in the hybrid `gofeed.Feed` model.\n* [Matt Jibson](https://mattjibson.com/) for his date parsing function in the [goread](https://github.com/mjibson/goread) project.\n* [Jim Teeuwen](https://github.com/jteeuwen) for his method of representing arbitrary feed extensions in the [go-pkg-rss](https://github.com/jteeuwen/go-pkg-rss) library.\n* [Sudhanshu Raheja](https://revolt.ist) for supporting JSON Feed parser\n","funding_links":[],"categories":["文本处理","文本處理"],"sub_categories":["高级控制台界面","高級控制台界面"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmcdole%2FGofeed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmmcdole%2FGofeed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmcdole%2FGofeed/lists"}