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
|
||||
|
||||
import (
|
||||
"github.com/go-rod/rod"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/xpzouying/headless_browser"
|
||||
"github.com/xpzouying/xiaohongshu-mcp/cookies"
|
||||
)
|
||||
|
||||
var (
|
||||
browser *headless_browser.Browser
|
||||
)
|
||||
|
||||
func Init(headless bool) error {
|
||||
func NewBrowser(headless bool) *headless_browser.Browser {
|
||||
|
||||
opts := []headless_browser.Option{
|
||||
headless_browser.WithHeadless(headless),
|
||||
@@ -28,15 +23,5 @@ func Init(headless bool) error {
|
||||
logrus.Warnf("failed to load cookies: %v", err)
|
||||
}
|
||||
|
||||
browser = headless_browser.New(opts...)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewPage() *rod.Page {
|
||||
return browser.NewPage()
|
||||
}
|
||||
|
||||
func Close() {
|
||||
browser.Close()
|
||||
return headless_browser.New(opts...)
|
||||
}
|
||||
|
||||
@@ -13,13 +13,11 @@ import (
|
||||
|
||||
func main() {
|
||||
|
||||
headlessModel := false
|
||||
if err := browser.Init(headlessModel); err != nil {
|
||||
logrus.Fatalf("failed to init browser: %v", err)
|
||||
}
|
||||
defer browser.Close()
|
||||
// 登录的时候,需要界面,所以不能无头模式
|
||||
b := browser.NewBrowser(false)
|
||||
defer b.Close()
|
||||
|
||||
page := browser.NewPage()
|
||||
page := b.NewPage()
|
||||
defer page.Close()
|
||||
|
||||
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 (
|
||||
"flag"
|
||||
|
||||
"github.com/xpzouying/xiaohongshu-mcp/browser"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/xpzouying/xiaohongshu-mcp/configs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -16,10 +15,7 @@ func main() {
|
||||
flag.BoolVar(&headless, "headless", true, "是否无头模式")
|
||||
flag.Parse()
|
||||
|
||||
if err := browser.Init(headless); err != nil {
|
||||
logrus.Fatalf("failed to init browser: %v", err)
|
||||
}
|
||||
defer browser.Close()
|
||||
configs.InitHeadless(headless)
|
||||
|
||||
if err := startServer(); err != nil {
|
||||
logrus.Fatalf("failed to run server: %v", err)
|
||||
|
||||
19
service.go
19
service.go
@@ -47,9 +47,12 @@ type FeedsListResponse struct {
|
||||
|
||||
// CheckLoginStatus 检查登录状态
|
||||
func (s *XiaohongshuService) CheckLoginStatus(ctx context.Context) (*LoginStatusResponse, error) {
|
||||
// 使用全局单例浏览器创建新页面
|
||||
page := browser.NewPage()
|
||||
b := browser.NewBrowser(configs.IsHeadless())
|
||||
defer b.Close()
|
||||
|
||||
page := b.NewPage()
|
||||
defer page.Close()
|
||||
|
||||
loginAction := xiaohongshu.NewLogin(page)
|
||||
|
||||
isLoggedIn, err := loginAction.CheckLoginStatus(ctx)
|
||||
@@ -103,8 +106,10 @@ func (s *XiaohongshuService) processImages(images []string) ([]string, error) {
|
||||
|
||||
// publishContent 执行内容发布
|
||||
func (s *XiaohongshuService) publishContent(ctx context.Context, content xiaohongshu.PublishImageContent) error {
|
||||
// 使用全局单例浏览器创建新页面
|
||||
page := browser.NewPage()
|
||||
b := browser.NewBrowser(configs.IsHeadless())
|
||||
defer b.Close()
|
||||
|
||||
page := b.NewPage()
|
||||
defer page.Close()
|
||||
|
||||
action, err := xiaohongshu.NewPublishImageAction(page)
|
||||
@@ -118,8 +123,10 @@ func (s *XiaohongshuService) publishContent(ctx context.Context, content xiaohon
|
||||
|
||||
// ListFeeds 获取Feeds列表
|
||||
func (s *XiaohongshuService) ListFeeds(ctx context.Context) (*FeedsListResponse, error) {
|
||||
// 使用全局单例浏览器创建新页面
|
||||
page := browser.NewPage()
|
||||
b := browser.NewBrowser(configs.IsHeadless())
|
||||
defer b.Close()
|
||||
|
||||
page := b.NewPage()
|
||||
defer page.Close()
|
||||
|
||||
// 创建 Feeds 列表 action
|
||||
|
||||
@@ -14,10 +14,10 @@ func TestGetFeedsList(t *testing.T) {
|
||||
|
||||
t.Skip("SKIP: 测试发布")
|
||||
|
||||
_ = browser.Init(false)
|
||||
defer browser.Close()
|
||||
b := browser.NewBrowser(false)
|
||||
defer b.Close()
|
||||
|
||||
page := browser.NewPage()
|
||||
page := b.NewPage()
|
||||
defer page.Close()
|
||||
|
||||
// NewFeedsListAction 内部已经处理导航
|
||||
|
||||
@@ -14,10 +14,10 @@ func TestPublish(t *testing.T) {
|
||||
|
||||
t.Skip("SKIP: 测试发布")
|
||||
|
||||
_ = browser.Init(false)
|
||||
defer browser.Close()
|
||||
b := browser.NewBrowser(false)
|
||||
defer b.Close()
|
||||
|
||||
page := browser.NewPage()
|
||||
page := b.NewPage()
|
||||
defer page.Close()
|
||||
|
||||
action, err := NewPublishImageAction(page)
|
||||
|
||||
Reference in New Issue
Block a user