refactor: 改进浏览器实例管理,按需创建浏览器实例 (#12)
- 移除全局浏览器单例,改为按需创建浏览器实例 - 添加 configs/browser.go 用于管理无头模式配置 - 更新 service.go 中所有方法,每次调用时创建新的浏览器实例 - 更新测试文件,使用新的浏览器管理方式 - 确保每个浏览器实例使用后正确关闭,避免资源泄漏 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,17 +1,12 @@
|
|||||||
package browser
|
package browser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-rod/rod"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/xpzouying/headless_browser"
|
"github.com/xpzouying/headless_browser"
|
||||||
"github.com/xpzouying/xiaohongshu-mcp/cookies"
|
"github.com/xpzouying/xiaohongshu-mcp/cookies"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
func NewBrowser(headless bool) *headless_browser.Browser {
|
||||||
browser *headless_browser.Browser
|
|
||||||
)
|
|
||||||
|
|
||||||
func Init(headless bool) error {
|
|
||||||
|
|
||||||
opts := []headless_browser.Option{
|
opts := []headless_browser.Option{
|
||||||
headless_browser.WithHeadless(headless),
|
headless_browser.WithHeadless(headless),
|
||||||
@@ -28,15 +23,5 @@ func Init(headless bool) error {
|
|||||||
logrus.Warnf("failed to load cookies: %v", err)
|
logrus.Warnf("failed to load cookies: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
browser = headless_browser.New(opts...)
|
return headless_browser.New(opts...)
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPage() *rod.Page {
|
|
||||||
return browser.NewPage()
|
|
||||||
}
|
|
||||||
|
|
||||||
func Close() {
|
|
||||||
browser.Close()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,13 +13,11 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
headlessModel := false
|
// 登录的时候,需要界面,所以不能无头模式
|
||||||
if err := browser.Init(headlessModel); err != nil {
|
b := browser.NewBrowser(false)
|
||||||
logrus.Fatalf("failed to init browser: %v", err)
|
defer b.Close()
|
||||||
}
|
|
||||||
defer browser.Close()
|
|
||||||
|
|
||||||
page := browser.NewPage()
|
page := b.NewPage()
|
||||||
defer page.Close()
|
defer page.Close()
|
||||||
|
|
||||||
action := xiaohongshu.NewLogin(page)
|
action := xiaohongshu.NewLogin(page)
|
||||||
|
|||||||
14
configs/browser.go
Normal file
14
configs/browser.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package configs
|
||||||
|
|
||||||
|
var (
|
||||||
|
useHeadless = true
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitHeadless(h bool) {
|
||||||
|
useHeadless = h
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsHeadless 是否无头模式。
|
||||||
|
func IsHeadless() bool {
|
||||||
|
return useHeadless
|
||||||
|
}
|
||||||
8
main.go
8
main.go
@@ -3,9 +3,8 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
|
||||||
"github.com/xpzouying/xiaohongshu-mcp/browser"
|
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/xpzouying/xiaohongshu-mcp/configs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -16,10 +15,7 @@ func main() {
|
|||||||
flag.BoolVar(&headless, "headless", true, "是否无头模式")
|
flag.BoolVar(&headless, "headless", true, "是否无头模式")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if err := browser.Init(headless); err != nil {
|
configs.InitHeadless(headless)
|
||||||
logrus.Fatalf("failed to init browser: %v", err)
|
|
||||||
}
|
|
||||||
defer browser.Close()
|
|
||||||
|
|
||||||
if err := startServer(); err != nil {
|
if err := startServer(); err != nil {
|
||||||
logrus.Fatalf("failed to run server: %v", err)
|
logrus.Fatalf("failed to run server: %v", err)
|
||||||
|
|||||||
19
service.go
19
service.go
@@ -47,9 +47,12 @@ type FeedsListResponse struct {
|
|||||||
|
|
||||||
// CheckLoginStatus 检查登录状态
|
// CheckLoginStatus 检查登录状态
|
||||||
func (s *XiaohongshuService) CheckLoginStatus(ctx context.Context) (*LoginStatusResponse, error) {
|
func (s *XiaohongshuService) CheckLoginStatus(ctx context.Context) (*LoginStatusResponse, error) {
|
||||||
// 使用全局单例浏览器创建新页面
|
b := browser.NewBrowser(configs.IsHeadless())
|
||||||
page := browser.NewPage()
|
defer b.Close()
|
||||||
|
|
||||||
|
page := b.NewPage()
|
||||||
defer page.Close()
|
defer page.Close()
|
||||||
|
|
||||||
loginAction := xiaohongshu.NewLogin(page)
|
loginAction := xiaohongshu.NewLogin(page)
|
||||||
|
|
||||||
isLoggedIn, err := loginAction.CheckLoginStatus(ctx)
|
isLoggedIn, err := loginAction.CheckLoginStatus(ctx)
|
||||||
@@ -103,8 +106,10 @@ func (s *XiaohongshuService) processImages(images []string) ([]string, error) {
|
|||||||
|
|
||||||
// publishContent 执行内容发布
|
// publishContent 执行内容发布
|
||||||
func (s *XiaohongshuService) publishContent(ctx context.Context, content xiaohongshu.PublishImageContent) error {
|
func (s *XiaohongshuService) publishContent(ctx context.Context, content xiaohongshu.PublishImageContent) error {
|
||||||
// 使用全局单例浏览器创建新页面
|
b := browser.NewBrowser(configs.IsHeadless())
|
||||||
page := browser.NewPage()
|
defer b.Close()
|
||||||
|
|
||||||
|
page := b.NewPage()
|
||||||
defer page.Close()
|
defer page.Close()
|
||||||
|
|
||||||
action, err := xiaohongshu.NewPublishImageAction(page)
|
action, err := xiaohongshu.NewPublishImageAction(page)
|
||||||
@@ -118,8 +123,10 @@ func (s *XiaohongshuService) publishContent(ctx context.Context, content xiaohon
|
|||||||
|
|
||||||
// ListFeeds 获取Feeds列表
|
// ListFeeds 获取Feeds列表
|
||||||
func (s *XiaohongshuService) ListFeeds(ctx context.Context) (*FeedsListResponse, error) {
|
func (s *XiaohongshuService) ListFeeds(ctx context.Context) (*FeedsListResponse, error) {
|
||||||
// 使用全局单例浏览器创建新页面
|
b := browser.NewBrowser(configs.IsHeadless())
|
||||||
page := browser.NewPage()
|
defer b.Close()
|
||||||
|
|
||||||
|
page := b.NewPage()
|
||||||
defer page.Close()
|
defer page.Close()
|
||||||
|
|
||||||
// 创建 Feeds 列表 action
|
// 创建 Feeds 列表 action
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ func TestGetFeedsList(t *testing.T) {
|
|||||||
|
|
||||||
t.Skip("SKIP: 测试发布")
|
t.Skip("SKIP: 测试发布")
|
||||||
|
|
||||||
_ = browser.Init(false)
|
b := browser.NewBrowser(false)
|
||||||
defer browser.Close()
|
defer b.Close()
|
||||||
|
|
||||||
page := browser.NewPage()
|
page := b.NewPage()
|
||||||
defer page.Close()
|
defer page.Close()
|
||||||
|
|
||||||
// NewFeedsListAction 内部已经处理导航
|
// NewFeedsListAction 内部已经处理导航
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ func TestPublish(t *testing.T) {
|
|||||||
|
|
||||||
t.Skip("SKIP: 测试发布")
|
t.Skip("SKIP: 测试发布")
|
||||||
|
|
||||||
_ = browser.Init(false)
|
b := browser.NewBrowser(false)
|
||||||
defer browser.Close()
|
defer b.Close()
|
||||||
|
|
||||||
page := browser.NewPage()
|
page := b.NewPage()
|
||||||
defer page.Close()
|
defer page.Close()
|
||||||
|
|
||||||
action, err := NewPublishImageAction(page)
|
action, err := NewPublishImageAction(page)
|
||||||
|
|||||||
Reference in New Issue
Block a user