golang访问MyAnimeList API的客户端插件库go-myanimelist的使用
golang访问MyAnimeList API的客户端插件库go-myanimelist的使用
项目介绍
go-myanimelist 是一个用于访问 MyAnimeList API v2 的 Go 客户端库。该项目已更新以支持 MyAnimeList API v2,并且自2017年3月起被收录在 awesome-go 中。
安装
使用以下命令安装该包:
go get github.com/nstratos/go-myanimelist/mal
使用方式
导入包:
import "github.com/nstratos/go-myanimelist/mal"
首先创建一个新的 mal 客户端:
c := mal.NewClient(nil)
然后使用客户端的服务(User、Anime、Manga 和 Forum)来访问不同的 MyAnimeList API 方法。
认证
访问公开信息
要访问公共信息,你需要在请求中添加 X-MAL-CLIENT-ID
头部。可以通过创建一个带有自定义传输的 http.Client
来实现:
type clientIDTransport struct {
Transport http.RoundTripper
ClientID string
}
func (c *clientIDTransport) RoundTrip(req *http.Request) (*http.Response, error) {
if c.Transport == nil {
c.Transport = http.DefaultTransport
}
req.Header.Add("X-MAL-CLIENT-ID", c.ClientID)
return c.Transport.RoundTrip(req)
}
func main() {
publicInfoClient := &http.Client{
// 从 https://myanimelist.net/apiconfig 创建客户端ID
Transport: &clientIDTransport{ClientID: "<Your application client ID>"},
}
c := mal.NewClient(publicInfoClient)
// ...
}
使用 OAuth2 认证
推荐使用 golang.org/x/oauth2
包。完成 OAuth2 流程后,你将获得一个包含访问令牌、刷新令牌和过期日期的 oauth2 令牌。
const storedToken = `
{
"token_type": "Bearer",
"access_token": "yourAccessToken",
"refresh_token": "yourRefreshToken",
"expiry": "2021-06-01T16:12:56.1319122Z"
}`
oauth2Token := new(oauth2.Token)
_ = json.Unmarshal([]byte(storedToken), oauth2Token)
// 从 https://myanimelist.net/apiconfig 创建客户端ID和密钥
//
// 如果选择应用类型为"other",则密钥目前是可选的
oauth2Conf := &oauth2.Config{
ClientID: "<Enter your registered MyAnimeList.net application client ID>",
ClientSecret: "<Enter your registered MyAnimeList.net application client secret>",
Endpoint: oauth2.Endpoint{
AuthURL: "https://myanimelist.net/v1/oauth2/authorize",
TokenURL: "https://myanimelist.net/v1/oauth2/token",
AuthStyle: oauth2.AuthStyleInParams,
},
}
oauth2Client := oauth2Conf.Client(ctx, oauth2Token)
// oauth2Client 将在令牌过期时刷新令牌
c := mal.NewClient(oauth2Client)
完整示例
以下是一个完整的示例,展示如何使用 go-myanimelist 库访问 MyAnimeList API:
package main
import (
"context"
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/nstratos/go-myanimelist/mal"
"golang.org/x/oauth2"
)
func main() {
// 使用 OAuth2 认证
const storedToken = `
{
"token_type": "Bearer",
"access_token": "yourAccessToken",
"refresh_token": "yourRefreshToken",
"expiry": "2021-06-01T16:12:56.1319122Z"
}`
oauth2Token := new(oauth2.Token)
_ = json.Unmarshal([]byte(storedToken), oauth2Token)
oauth2Conf := &oauth2.Config{
ClientID: "<Your Client ID>",
ClientSecret: "<Your Client Secret>",
Endpoint: oauth2.Endpoint{
AuthURL: "https://myanimelist.net/v1/oauth2/authorize",
TokenURL: "https://myanimelist.net/v1/oauth2/token",
AuthStyle: oauth2.AuthStyleInParams,
},
}
ctx := context.Background()
oauth2Client := oauth2Conf.Client(ctx, oauth2Token)
// 创建客户端
c := mal.NewClient(oauth2Client)
// 获取用户信息
user, _, err := c.User.MyInfo(ctx)
if err != nil {
fmt.Printf("Error getting user info: %v\n", err)
return
}
fmt.Printf("User: %+v\n", user)
// 搜索动漫
animeList, _, err := c.Anime.List(ctx, "hokuto no ken",
mal.Fields{"rank", "popularity", "my_list_status"},
mal.Limit(5),
)
if err != nil {
fmt.Printf("Error searching anime: %v\n", err)
return
}
fmt.Println("Anime search results:")
for _, a := range animeList {
fmt.Printf("- %s (Rank: %d, Popularity: %d)\n", a.Title, a.Rank, a.Popularity)
}
// 获取动漫详情
animeDetails, _, err := c.Anime.Details(ctx, 967,
mal.Fields{
"alternative_titles",
"media_type",
"num_episodes",
"start_season",
"source",
"genres",
"studios",
"average_episode_duration",
},
)
if err != nil {
fmt.Printf("Error getting anime details: %v\n", err)
return
}
fmt.Printf("Anime details: %+v\n", animeDetails)
// 更新我的动漫列表状态
_, _, err = c.Anime.UpdateMyListStatus(ctx, 967,
mal.AnimeStatusWatching,
mal.NumEpisodesWatched(73),
mal.Score(8),
mal.Comments("You wa shock!"),
mal.StartDate(time.Date(2022, 02, 20, 0, 0, 0, 0, time.UTC)),
mal.FinishDate(time.Time{}), // 移除现有日期
)
if err != nil {
fmt.Printf("Error updating anime list: %v\n", err)
return
}
fmt.Println("Successfully updated anime list")
}
更多功能
该库还支持以下功能:
- 获取用户动漫/漫画列表
- 获取动漫/漫画排名
- 删除列表项等
测试
运行单元测试:
go test -cover
运行集成测试:
go test --client-id='<your app client ID>' --oauth2-token='<your oauth2 token>'
许可证
MIT
更多关于golang访问MyAnimeList API的客户端插件库go-myanimelist的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang访问MyAnimeList API的客户端插件库go-myanimelist的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用go-myanimelist访问MyAnimeList API
go-myanimelist 是一个非官方的Golang客户端库,用于访问MyAnimeList API。下面我将介绍如何使用这个库来与MyAnimeList API交互。
安装
首先安装go-myanimelist库:
go get github.com/nstratos/go-myanimelist/mal
认证设置
要使用MyAnimeList API,你需要先注册一个客户端ID。可以在MyAnimeList开发者页面申请。
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/nstratos/go-myanimelist/mal"
)
func main() {
// 从环境变量获取客户端ID
clientID := os.Getenv("MAL_CLIENT_ID")
if clientID == "" {
log.Fatal("请设置MAL_CLIENT_ID环境变量")
}
// 创建客户端
client, err := mal.NewClient(clientID)
if err != nil {
log.Fatal(err)
}
}
基本使用示例
1. 搜索动漫
func searchAnime(client *mal.Client, query string) {
ctx := context.Background()
// 搜索动漫
result, _, err := client.Anime.Search(ctx, query,
mal.Fields{"rank", "popularity", "mean", "media_type", "num_episodes"},
mal.Limit(5),
)
if err != nil {
log.Fatal(err)
}
fmt.Println("搜索结果:")
for _, anime := range result {
fmt.Printf("ID: %5d, 标题: %-30s, 评分: %.2f, 集数: %d\n",
anime.ID, anime.Title, anime.Mean, anime.NumEpisodes)
}
}
2. 获取动漫详情
func getAnimeDetails(client *mal.Client, animeID int) {
ctx := context.Background()
// 获取动漫详情
anime, _, err := client.Anime.Details(ctx, animeID,
mal.Fields{
"id", "title", "main_picture", "alternative_titles",
"start_date", "end_date", "synopsis", "mean", "rank",
"popularity", "num_list_users", "num_scoring_users",
"nsfw", "created_at", "updated_at", "media_type",
"status", "genres", "my_list_status", "num_episodes",
"start_season", "broadcast", "source", "average_episode_duration",
"rating", "pictures", "background", "related_anime",
"related_manga", "recommendations", "studios", "statistics",
},
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("动漫详情:\nID: %d\n标题: %s\n类型: %s\n状态: %s\n评分: %.2f\n简介: %s\n",
anime.ID, anime.Title, anime.MediaType, anime.Status, anime.Mean, anime.Synopsis)
}
3. 获取用户动漫列表
func getUserAnimeList(client *mal.Client, username string) {
ctx := context.Background()
// 获取用户动漫列表
list, _, err := client.Anime.List(ctx, username,
mal.Fields{"list_status"},
mal.Limit(10),
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s的动漫列表:\n", username)
for _, anime := range list {
status := anime.ListStatus.Status
if status == "" {
status = "未观看"
}
fmt.Printf("%s - %s (进度: %d/%d)\n",
anime.Anime.Title, status,
anime.ListStatus.NumEpisodesWatched, anime.Anime.NumEpisodes)
}
}
4. 更新用户动漫列表状态
func updateAnimeStatus(client *mal.Client, animeID int) {
ctx := context.Background()
// 需要OAuth2认证
// 这里假设你已经有了OAuth2 token
// 实际使用中需要实现OAuth2流程获取token
// 更新动漫状态
_, err := client.Anime.UpdateMyListStatus(ctx, animeID,
mal.AnimeStatusWatching,
mal.NumEpisodesWatched(5),
mal.Score(8),
)
if err != nil {
log.Fatal(err)
}
fmt.Println("动漫状态更新成功")
}
OAuth2认证流程
要更新用户数据,需要OAuth2认证。以下是基本流程:
func oauth2Example(clientID string) {
// 创建OAuth2配置
oauth2Config := &oauth2.Config{
ClientID: clientID,
Endpoint: mal.Endpoint,
RedirectURL: "urn:ietf:wg:oauth:2.0:oob", // 用于CLI应用
}
// 生成授权URL
authURL := oauth2Config.AuthCodeURL("state", oauth2.AccessTypeOffline)
fmt.Printf("请访问以下URL授权:\n%s\n", authURL)
// 用户授权后获取code
fmt.Print("请输入授权码: ")
var code string
if _, err := fmt.Scan(&code); err != nil {
log.Fatal(err)
}
// 交换code获取token
ctx := context.Background()
token, err := oauth2Config.Exchange(ctx, code)
if err != nil {
log.Fatal(err)
}
// 使用token创建认证客户端
authClient := oauth2Config.Client(ctx, token)
client := mal.NewWithClient(authClient)
// 现在可以使用认证后的client进行操作...
}
完整示例
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/nstratos/go-myanimelist/mal"
"golang.org/x/oauth2"
)
func main() {
clientID := os.Getenv("MAL_CLIENT_ID")
if clientID == "" {
log.Fatal("请设置MAL_CLIENT_ID环境变量")
}
// 创建客户端
client, err := mal.NewClient(clientID)
if err != nil {
log.Fatal(err)
}
// 搜索示例
searchAnime(client, "Attack on Titan")
// 获取详情示例
// getAnimeDetails(client, 16498) // Shingeki no Kyojin ID
// 用户列表示例
// getUserAnimeList(client, "some_username")
// OAuth2示例 (需要实际实现)
// oauth2Example(clientID)
}
注意事项
- MyAnimeList API有请求限制,请合理控制请求频率
- 敏感操作需要OAuth2认证
- 字段选择使用mal.Fields可以优化API响应大小
- 错误处理在实际应用中很重要,示例中简化了错误处理
这个库提供了对MyAnimeList API的全面覆盖,你可以根据需要扩展上述示例来实现更多功能。