diff --git a/cookies/0d86b848uu2183uu4a08/xhs.json b/cookies/0d86b848uu2183uu4a08/xhs.json index 4b50020..77af278 100644 --- a/cookies/0d86b848uu2183uu4a08/xhs.json +++ b/cookies/0d86b848uu2183uu4a08/xhs.json @@ -1 +1 @@ -[{"name":"websectiga","value":"7750c37de43b7be9de8ed9ff8ea0e576519e8cd2157322eb972ecb429a7735d4","domain":".xiaohongshu.com","path":"/","expires":1776073705,"size":74,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"x-user-id-creator.xiaohongshu.com","value":"65d74a4c0000000005032a98","domain":".xiaohongshu.com","path":"/","expires":1810179755.091531,"size":57,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"xsecappid","value":"ugc","domain":".xiaohongshu.com","path":"/","expires":1807350714,"size":12,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"a1","value":"19d6b2f0b04zdps8dison8k8oibcyzaju3ji7d03d30000118748","domain":".xiaohongshu.com","path":"/","expires":1807155738,"size":54,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"webId","value":"f840cc8b10e0a01b0bdb839482af19d1","domain":".xiaohongshu.com","path":"/","expires":1807155738,"size":37,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"access-token-creator.xiaohongshu.com","value":"customer.creator.AT-68c517626228786611519495vggizcwmifuvnaaw","domain":".xiaohongshu.com","path":"/","expires":1778211754.091569,"size":96,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"sec_poison_id","value":"0e8199c2-5b2c-4b5d-9423-9ce4ae7c7d4a","domain":".xiaohongshu.com","path":"/","expires":1775815110,"size":49,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"customerClientId","value":"231145420384063","domain":".xiaohongshu.com","path":"/","expires":1810179755.091552,"size":31,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"ets","value":"1775619738206","domain":".xiaohongshu.com","path":"/","expires":1778211738.206388,"size":16,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"gid","value":"yjfKDJiJ0J7SyjfKDJi8Dqf884ufUMYf3MlIVqfYTYl3D3q8Svu0VW888yyYW4Y8JD0j8Yd2","domain":".xiaohongshu.com","path":"/","expires":1810372429.581067,"size":75,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"customer-sso-sid","value":"68c5176262287866115194944uxxdffhcemiwvwt","domain":".xiaohongshu.com","path":"/","expires":1776224554.091467,"size":56,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"galaxy_creator_session_id","value":"nWC5PzTFCCSJsLYiRFLFORIWUoUf5c4Egr3v","domain":".xiaohongshu.com","path":"/","expires":1778211755.091586,"size":61,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"acw_tc","value":"0a0d0eb817758145058628343eac7363daa6c0cadc9daf2e0f80b0fb928719","domain":"creator.xiaohongshu.com","path":"/","expires":1775816304.657778,"size":68,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"galaxy.creator.beaker.session.id","value":"1775619757404082990054","domain":".xiaohongshu.com","path":"/","expires":1778211755.091605,"size":54,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"loadts","value":"1775814714949","domain":".xiaohongshu.com","path":"/","expires":1807350714,"size":19,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443}] \ No newline at end of file +[{"name":"gid","value":"yjfKDJiJ0J7SyjfKDJi8Dqf884ufUMYf3MlIVqfYTYl3D3q8Svu0VW888yyYW4Y8JD0j8Yd2","domain":".xiaohongshu.com","path":"/","expires":1810372429.581067,"size":75,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"ets","value":"1775619738206","domain":".xiaohongshu.com","path":"/","expires":1778211738.206388,"size":16,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"a1","value":"19d6b2f0b04zdps8dison8k8oibcyzaju3ji7d03d30000118748","domain":".xiaohongshu.com","path":"/","expires":1807155738,"size":54,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"customer-sso-sid","value":"68c5176262287866115194944uxxdffhcemiwvwt","domain":".xiaohongshu.com","path":"/","expires":1776224554.091467,"size":56,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"x-user-id-creator.xiaohongshu.com","value":"65d74a4c0000000005032a98","domain":".xiaohongshu.com","path":"/","expires":1810179755.091531,"size":57,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"access-token-creator.xiaohongshu.com","value":"customer.creator.AT-68c517626228786611519495vggizcwmifuvnaaw","domain":".xiaohongshu.com","path":"/","expires":1778211754.091569,"size":96,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"galaxy_creator_session_id","value":"nWC5PzTFCCSJsLYiRFLFORIWUoUf5c4Egr3v","domain":".xiaohongshu.com","path":"/","expires":1778211755.091586,"size":61,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"webId","value":"f840cc8b10e0a01b0bdb839482af19d1","domain":".xiaohongshu.com","path":"/","expires":1807155738,"size":37,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"xsecappid","value":"ugc","domain":".xiaohongshu.com","path":"/","expires":1807379925,"size":12,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"loadts","value":"1775843925008","domain":".xiaohongshu.com","path":"/","expires":1807379925,"size":19,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"galaxy.creator.beaker.session.id","value":"1775619757404082990054","domain":".xiaohongshu.com","path":"/","expires":1778211755.091605,"size":54,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"websectiga","value":"2a3d3ea002e7d92b5c9743590ebd24010cf3710ff3af8029153751e41a6af4a3","domain":".xiaohongshu.com","path":"/","expires":1776103125,"size":74,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"sec_poison_id","value":"680df974-cc97-44bd-9c18-b9efaafb66cc","domain":".xiaohongshu.com","path":"/","expires":1775844530,"size":49,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"acw_tc","value":"0a00076417758431730566823e6256f5349e529f992a6ba74dc0835439d93a","domain":"creator.xiaohongshu.com","path":"/","expires":1775844709.365943,"size":68,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"customerClientId","value":"231145420384063","domain":".xiaohongshu.com","path":"/","expires":1810179755.091552,"size":31,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443}] \ No newline at end of file diff --git a/html/bjhpage.html b/html/bjhpage.html new file mode 100644 index 0000000..24bc977 --- /dev/null +++ b/html/bjhpage.html @@ -0,0 +1,7255 @@ +百家号
返回首页
图文
视频
动态
直播
合集
图集
插入
请输入标题(2 - 64字)


0/64
请输入正文
基础信息
选择封面
优质封面有助于获得更多流量查看封面展示页面
AI眼中的人格测试
AI眼中的人格测试
492人参加
我要做个美食家
我要做个美食家
6702人参加
+48

欢迎使用AI助手

热点灵感新鲜出炉,来看看吧

意见反馈
换一换
1
樊振东贴脸开大盛李豪
2
四川一地发生山体崩塌无人员伤亡
3
4月10日调整后92号油价公布
4
湖人更新詹姆斯出战状态
5
特朗普:美国军舰飞机不准撤
6
浪姐一公阚清子团险胜孙怡团
你还可以自定义垂类查询
社会
娱乐
财经
体育
科技
汽车
国际
游戏
音乐
影视
字数 0
已保存
发文设置
手机查看
Rule Center规则中心
问题咨询
Collapse收起
AI工具收起
续写与润色收缩到这里,点击展开可立即体验
新增风险检测
增加图片文本违法违规色情等相关检测,可提前获知部分作品问题与优化建议
\ No newline at end of file diff --git a/internal/entitys/publish.go b/internal/entitys/publish.go index 2391b6e..341d22d 100644 --- a/internal/entitys/publish.go +++ b/internal/entitys/publish.go @@ -2,6 +2,7 @@ package entitys type PublishTaskDetail struct { // publish 表字段 + ID int `db:"ID"` RequestID string `db:"request_id"` PlatIndex string `db:"plat_index"` Title string `db:"title"` diff --git a/internal/manager/publish_manager.go b/internal/manager/publish_manager.go index 3867570..f1cc5b1 100644 --- a/internal/manager/publish_manager.go +++ b/internal/manager/publish_manager.go @@ -194,11 +194,30 @@ func (pm *PublishManager) executeOneTask(workerID int, headless bool) { } log.Printf("[Worker-%d] 开始处理任务 requestID=%s", workerID, task.RequestID) - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // 使用 channel 接收结果,避免 goroutine 泄漏 + resultChan := make(chan *SingleResult, 1) - result := pm.processTask(ctx, task, headless) + go func() { + resultChan <- pm.processTask(ctx, task, headless) + }() + + // 监听 ctx 超时 + var result *SingleResult + select { + case result = <-resultChan: + // 任务正常完成 + case <-ctx.Done(): + // 超时或取消 + log.Printf("[Worker-%d] 任务超时或被取消 requestID=%s, err=%v", workerID, task.RequestID, ctx.Err()) + result = &SingleResult{ + Success: false, + Message: fmt.Sprintf("任务执行超时: %v", ctx.Err()), + } + // 注意:这里不能等待 goroutine 结束,因为 processTask 可能卡住 + // cancel() 会在 defer 中调用,但 processTask 内部需要响应 ctx.Done() + } if result == nil { log.Printf("[Worker-%d] 任务返回空结果", workerID) @@ -246,6 +265,7 @@ func (pm *PublishManager) acquireTask() (*entitys.PublishTaskDetail, error) { var task entitys.PublishTaskDetail querySQL := ` SELECT + p.id, p.request_id, p.plat_index, p.title, @@ -302,7 +322,7 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys. if r := recover(); r != nil { errMsg := fmt.Sprintf("任务执行发生panic: %v", r) taskLogger.Printf("❌ CRITICAL: %s", errMsg) - pm.updatePublishStatus(publishData.RequestID, StatusFailed, errMsg) + pm.updatePublishStatus(publishData.ID, StatusFailed, errMsg) } }() @@ -310,7 +330,7 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys. params, sourceUrl := pm.extractTaskParams(publishData, taskLogger) if params == nil { - pm.updatePublishStatus(publishData.RequestID, StatusFailed, "提取任务参数失败") + pm.updatePublishStatus(publishData.ID, StatusFailed, "提取任务参数失败") return &SingleResult{Success: false, Message: "提取任务参数失败", RequestId: publishData.RequestID} } params.Headless = headless @@ -319,7 +339,7 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys. if publisherClass == nil { errMsg := fmt.Sprintf("不支持的平台: %s", params.PlatIndex) taskLogger.Printf("[任务 %s] ❌ %s", publishData.RequestID, errMsg) - pm.updatePublishStatus(publishData.RequestID, StatusFailed, errMsg) + pm.updatePublishStatus(publishData.ID, StatusFailed, errMsg) return &SingleResult{Success: false, Message: errMsg, RequestId: publishData.RequestID} } @@ -327,7 +347,7 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys. if err != nil { errMsg := fmt.Sprintf("准备文件失败: %v", err) taskLogger.Printf("[任务 %s] ❌ %s", publishData.RequestID, errMsg) - pm.updatePublishStatus(publishData.RequestID, StatusFailed, errMsg) + pm.updatePublishStatus(publishData.ID, StatusFailed, errMsg) return &SingleResult{Success: false, Message: errMsg, RequestId: publishData.RequestID} } defer pm.cleanupFiles(docPath, imgPath, taskLogger, publishData.RequestID) @@ -336,7 +356,7 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys. if err != nil { errMsg := fmt.Sprintf("提取文档内容失败: %v", err) taskLogger.Printf("[任务 %s] ❌ %s", publishData.RequestID, errMsg) - pm.updatePublishStatus(publishData.RequestID, StatusFailed, errMsg) + pm.updatePublishStatus(publishData.ID, StatusFailed, errMsg) return &SingleResult{Success: false, Message: errMsg, RequestId: publishData.RequestID} } params.ImagePath = imgPath @@ -348,10 +368,10 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys. if success { taskLogger.Printf("[任务 %s] ✅ 发布成功: %s", publishData.RequestID, message) - pm.updatePublishStatus(publishData.RequestID, StatusSuccess, message) + pm.updatePublishStatus(publishData.ID, StatusSuccess, message) } else { taskLogger.Printf("[任务 %s] ❌ 发布失败: %s", publishData.RequestID, message) - pm.updatePublishStatus(publishData.RequestID, StatusFailed, message) + pm.updatePublishStatus(publishData.ID, StatusFailed, message) } taskLogger.Printf(strings.Repeat("=", 80)) @@ -360,12 +380,12 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys. } // RetryTask 重试任务(非无头模式) -func (pm *PublishManager) RetryTask(ctx context.Context, requestID string) *SingleResult { +func (pm *PublishManager) RetryTask(ctx context.Context, tokenId int, requestID string) *SingleResult { if requestID == "" { return &SingleResult{Success: false, Message: "requestID不能为空"} } - publishData, err := pm.GetTaskByRequestID(requestID) + publishData, err := pm.GetTaskByRequestID(requestID, tokenId) if err != nil || publishData == nil { return &SingleResult{Success: false, Message: "任务不存在"} } @@ -379,13 +399,14 @@ func (pm *PublishManager) RetryTask(ctx context.Context, requestID string) *Sing } // GetTaskByRequestID 根据RequestID获取任务 -func (pm *PublishManager) GetTaskByRequestID(requestID string) (*entitys.PublishTaskDetail, error) { +func (pm *PublishManager) GetTaskByRequestID(requestID string, tokenId int) (*entitys.PublishTaskDetail, error) { if requestID == "" { return nil, fmt.Errorf("requestID不能为空") } sql := ` SELECT + p.id, p.request_id, p.plat_index, p.title, @@ -403,10 +424,10 @@ func (pm *PublishManager) GetTaskByRequestID(requestID string) (*entitys.Publish pl.desc FROM publish p INNER JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index AND pl.status = 1 - WHERE p.request_id = ? + WHERE p.request_id = ? AND token_id=? ` var task entitys.PublishTaskDetail - err := pm.db.GetOneToStruct(sql, &task, requestID) + err := pm.db.GetOneToStruct(sql, &task, requestID, tokenId) if err != nil { return nil, err } @@ -503,18 +524,18 @@ func (pm *PublishManager) extractContent(docPath string, publisherClass *publish } // updatePublishStatus 更新发布状态 -func (pm *PublishManager) updatePublishStatus(requestID string, status int, message string) error { - if requestID == "" { - return fmt.Errorf("requestID不能为空") +func (pm *PublishManager) updatePublishStatus(id int, status int, message string) error { + if id == 0 { + return fmt.Errorf("id不能为空") } var err error if message != "" { - _, err = pm.db.Execute("UPDATE publish SET status = ?, msg = ? WHERE token_id=? AND request_id = ?", status, message, pm.TokenID, requestID) + _, err = pm.db.Execute("UPDATE publish SET status = ?, msg = ? WHERE id=?", status, message, id) } else { - _, err = pm.db.Execute("UPDATE publish SET status = ? WHERE token_id=? AND request_id = ?", status, pm.TokenID, requestID) + _, err = pm.db.Execute("UPDATE publish SET status = ? WHERE id=?", status, id) } if err != nil { - log.Printf("更新发布状态失败: requestID=%s, status=%d, error=%v", requestID, status, err) + log.Printf("更新发布状态失败: id=%s, status=%d, error=%v", id, status, err) } return err } diff --git a/internal/publisher/baijiahao.go b/internal/publisher/baijiahao.go index 40d0f5f..06e9c92 100644 --- a/internal/publisher/baijiahao.go +++ b/internal/publisher/baijiahao.go @@ -7,6 +7,7 @@ import ( "log" "path/filepath" "strings" + "time" "github.com/go-rod/rod" "github.com/go-rod/rod/lib/proto" @@ -29,17 +30,10 @@ func (p *BaijiahaoPublisher) CheckLoginStatus() bool { } func (p *BaijiahaoPublisher) CheckLogin() (bool, string) { - driverCreated := false - defer func() { - if driverCreated && p.Browser != nil { - p.Close() - } - }() if err := p.SetupDriver(); err != nil { return false, fmt.Sprintf("浏览器启动失败: %v", err) } - driverCreated = true p.Page.MustNavigate(p.EditorURL) p.Sleep(3) @@ -53,17 +47,10 @@ func (p *BaijiahaoPublisher) CheckLogin() (bool, string) { } func (p *BaijiahaoPublisher) WaitLogin() (bool, string) { - driverCreated := false - defer func() { - if driverCreated && p.Browser != nil { - p.Close() - } - }() if err := p.SetupDriver(); err != nil { return false, fmt.Sprintf("浏览器启动失败: %v", err) } - driverCreated = true p.Page.MustNavigate(p.LoginedURL) p.Sleep(3) @@ -98,7 +85,7 @@ func (p *BaijiahaoPublisher) PublishNote() (bool, string) { return false, fmt.Sprintf("浏览器启动失败: %v", err) } - defer p.Page.Close() + defer p.Close() if p.LoadCookies() == nil { p.Page.MustNavigate(p.EditorURL) p.WaitForPageReady(5) @@ -121,14 +108,14 @@ func (p *BaijiahaoPublisher) doPublish() (bool, string) { name string fn func() error }{ - //{"切换到图文编辑模式", p.switchToGraphicMode}, + {"点击hover", p.clickHoverButton}, {"输入内容", p.inputContent}, {"输入标题", p.inputTitle}, {"设置封面", p.uploadImage}, {"点击发布按钮", p.clickPublish}, - {"处理确认弹窗", p.handleConfirmModal}, + //{"处理确认弹窗", p.handleConfirmModal}, } - + //https://baijiahao.baidu.com/builder/rc/clue?aside=0&footer=true&from=news&firstPublish=undefined&word_bag_id=null for _, step := range steps { if err := step.fn(); err != nil { p.LogStep(step.name, false, err.Error()) @@ -141,25 +128,50 @@ func (p *BaijiahaoPublisher) doPublish() (bool, string) { return p.waitForPublishResult() } -func (p *BaijiahaoPublisher) switchToGraphicMode() error { - p.LogInfo("切换到图文编辑模式...") - tabSelectors := []string{ - ".list-item.item-active", - ".header-list-content .list-item", - "div[role='tab']:first-child", +func (p *BaijiahaoPublisher) clickHoverButton() error { + p.LogInfo("点击HoverButton...") + + // 等待弹窗稳定 + p.WaitForPageReady(5) + _, err := p.Page.Element("div.cheetah-tour-content") + if err != nil { + return err } - for _, selector := range tabSelectors { - tab, err := p.Page.Element(selector) - if err == nil && tab != nil { - visible, _ := tab.Visible() - if visible { - p.JSClick(tab) - p.LogInfo(fmt.Sprintf("已点击图文标签: %s", selector)) - p.Sleep(1) - return nil - } + + maxAttempts := 10 + for i := 0; i < maxAttempts; i++ { + // 检查弹窗是否存在 + exists, _, err := p.Page.Has(".cheetah-tour") + if err != nil || !exists { + p.LogInfo("弹窗已关闭") + break } + + // 查找并点击弹窗中的按钮 + result, err := p.Page.Eval(`() => { + const btns = document.querySelectorAll('.cheetah-tour .cheetah-btn, .cheetah-tour-next-btn, .cheetah-tour-close'); + for (const btn of btns) { + if (btn.offsetParent !== null) { + const text = btn.innerText || btn.textContent; + btn.click(); + return text; + } + } + return null; + }`) + + if err != nil { + p.LogInfof("执行点击出错: %v", err) + continue + } + + p.LogInfof("第%d次点击按钮: %v", i+1, result) + + // 等待弹窗响应 + time.Sleep(500 * time.Millisecond) } + + p.LogInfo("引导弹窗处理完成") return nil } diff --git a/internal/publisher/base.go b/internal/publisher/base.go index c75d752..19d1f72 100644 --- a/internal/publisher/base.go +++ b/internal/publisher/base.go @@ -113,76 +113,61 @@ func NewBasePublisher(ctx context.Context, task *TaskParams, config *config.Conf func (b *BasePublisher) SetupDriver() error { b.LogInfo("初始化浏览器。。。。") - b.Headless = true - l := launcher.New().Bin(b.config.Sys.ChromePath) - l.Headless(b.Headless) - // 设置 Leakless 模式(解决 Windows 上的问题) - l.Leakless(false) + userDataDir := filepath.Join(b.config.Sys.ChromeDataDir, b.UserIndex, b.RequestID+fmt.Sprintf("___%d", time.Now().UnixNano())) + //userDataDir := fmt.Sprintf("./chrome_data/user_%d_", time.Now().UnixNano()) + os.MkdirAll(userDataDir, 0755) + l := launcher.New(). + Bin(b.config.Sys.ChromePath). + UserDataDir(userDataDir). + Headless(b.Headless). + Leakless(false).Set("disable-blink-features", "AutomationControlled") + if b.Headless { // 无头模式专用参数 l.Set("headless", "new") // 使用新版无头模式 l.Set("disable-gpu") - l.Set("disable-software-rasterizer") - l.Set("disable-dev-shm-usage") l.Set("no-sandbox") - // 禁用虚拟滚动,避免等待 - //l.Set("disable-scroll-to-text-fragment") + l.Set("disable-dev-shm-usage") + } else { + l.Set("window-size", "1920,1080") + l.Set("start-maximized") + // 移除 headless 相关参数 + l.Delete("headless") } // 设置用户数据目录 - userDataDir := filepath.Join(b.config.Sys.ChromeDataDir, b.UserIndex) - os.MkdirAll(userDataDir, 0755) - l.UserDataDir(userDataDir) - // 为每个用户分配一个可用的随机端口,确保端口不冲突 - //freePort, err := pkg.GetFreePort() - //if err != nil { - // return fmt.Errorf("获取空闲端口失败: %v", err) - //} - l.Set("remote-debugging-port", "0") + // 关键优化:不重新使用已有的数据目录时不要清除 - l.Set("profile-directory", "Default") + //l.Set("profile-directory", "Default") // 设置 Chrome 启动参数 - l.Set("disable-blink-features", "AutomationControlled") - l.Set("no-sandbox") - l.Set("disable-dev-shm-usage") - l.Set("disable-gpu") - l.Set("disable-software-rasterizer") - l.Set("disable-setuid-sandbox") + + //l.Set("no-sandbox") + //l.Set("disable-dev-shm-usage") // 关键:禁用后台限制,让页面在后台也能正常执行 - l.Set("disable-background-timer-throttling") - l.Set("disable-backgrounding-occluded-windows") - l.Set("disable-renderer-backgrounding") - l.Set("disable-ipc-flooding-protection") + //l.Set("disable-background-timer-throttling") + //l.Set("disable-backgrounding-occluded-windows") + //l.Set("disable-renderer-backgrounding") + //l.Set("disable-ipc-flooding-protection") // 窗口大小 l.Set("window-size", "1920,1080") l.Set("lang", "zh-CN") - l.Set("start-maximized") l.Set("force-device-scale-factor", "1") url, err := l.Launch() if err != nil { + return fmt.Errorf("启动浏览器失败: %v", err) } b.Browser = rod.New().Context(b.ctx).ControlURL(url).MustConnect() b.Page = b.Browser.MustPage() - time.Sleep(5000) return nil } -// func (b *BasePublisher) SetupDriver() error { -// b.LogInfo("初始化浏览器。。。。") -// b.Headless = true -// -// b.Browser = rod.New().Context(b.ctx). -// b.Page = b.Browser.MustPage() -// time.Sleep(5000) -// return nil -// } func (b *BasePublisher) Close() { if b.Page != nil { b.Page.Close() @@ -223,6 +208,15 @@ func (b *BasePublisher) LoadCookies() error { return b.Page.SetCookies(cookies) } +func (b *BasePublisher) DelCookies() error { + err := os.Remove(b.CookiesFile) + if err != nil { + return err + } + + return nil +} + func (b *BasePublisher) RefreshPage() error { _, err := b.Page.Eval(`() => location.reload()`) return err @@ -294,7 +288,7 @@ func (b *BasePublisher) LogInfo(message string) { } func (b *BasePublisher) LogInfof(message string, arg ...any) { - b.Logger.Printf("📌 %s", message, arg) + b.Logger.Printf("📌 "+message, arg) } func (b *BasePublisher) LogError(message string) { diff --git a/internal/publisher/csdn.go b/internal/publisher/csdn.go index a741e11..eeb558d 100644 --- a/internal/publisher/csdn.go +++ b/internal/publisher/csdn.go @@ -186,7 +186,7 @@ func (p *CSDNPublisher) PublishNote() (bool, string) { if err := p.SetupDriver(); err != nil { return false, fmt.Sprintf("浏览器启动失败: %v", err) } - defer p.Page.Close() + defer p.Close() // 执行发布流程 steps := []struct { diff --git a/internal/publisher/dysp.go b/internal/publisher/dysp.go index 71f5ce1..3c9e91a 100644 --- a/internal/publisher/dysp.go +++ b/internal/publisher/dysp.go @@ -179,31 +179,21 @@ func (p *DouyinSpPublisher) waitForUploadComplete() error { func (p *DouyinSpPublisher) inputTitle() error { p.LogInfo("输入视频标题...") - titleSelectors := []string{ - "textarea[placeholder*='标题']", - "input[placeholder*='标题']", - ".container-sGoJ9f input", - ".semiInput-EyEyPL input", + exist, titleInput, err := p.Page.Has("input[placeholder*='标题']") + if err != nil { + return err } - - for _, selector := range titleSelectors { - titleInput, err := p.WaitForElementVisible(selector, 5) - if err == nil && titleInput != nil { - p.LogInfo(fmt.Sprintf("找到标题输入框: %s", selector)) - - p.ClearInput(titleInput) - p.SleepMs(300) - titleInput.Input("") - p.SleepMs(300) - titleInput.Input(p.Title) - - p.LogInfo(fmt.Sprintf("标题已输入: %s", p.Title)) - p.SleepMs(500) - return nil - } + if !exist { + return fmt.Errorf("未找到标题输入框") } - - return fmt.Errorf("未找到标题输入框") + p.ClearInput(titleInput) + p.SleepMs(300) + titleInput.Input("") + p.SleepMs(300) + titleInput.Input(p.Title) + p.LogInfo(fmt.Sprintf("标题已输入: %s", p.Title)) + p.SleepMs(500) + return nil } func (p *DouyinSpPublisher) inputDescription() error { @@ -299,22 +289,6 @@ func (p *DouyinSpPublisher) clickPublish() error { p.LogInfo("已点击发布按钮") p.SleepMs(3000) - confirmSelectors := []string{ - ".semi-modal .semi-button-primary", - ".confirm-btn-JwJNCk", - "button:contains('确认')", - "button:contains('确定')", - } - for _, selector := range confirmSelectors { - confirmBtn, _ := p.WaitForElementClickable(selector, 2) - if confirmBtn != nil { - p.JSClick(confirmBtn) - p.LogInfo("已确认发布") - p.SleepMs(2000) - break - } - } - return nil } @@ -374,15 +348,18 @@ func (p *DouyinSpPublisher) InitPage() error { // 尝试加载cookies并检查登录状态 if err := p.LoadCookies(); err == nil { - p.Page.MustNavigate(p.EditorURL) + p.Page.MustNavigate(p.LoginURL) p.WaitForPageReady(5) - p.Sleep(2) + p.Sleep(4) } // 统一检查登录状态 if !p.CheckLoginStatus() { p.LogInfo("未登录或登录已过期,需要重新登录") + p.DelCookies() return fmt.Errorf("需要登录") } + p.Page.MustNavigate(p.EditorURL) + p.WaitForPageReady(5) p.SaveCookies() return nil } @@ -393,7 +370,7 @@ func (p *DouyinSpPublisher) PublishNote() (bool, string) { if err := p.SetupDriver(); err != nil { return false, fmt.Sprintf("浏览器启动失败: %v", err) } - defer p.Page.Close() + defer p.Close() steps := []struct { name string diff --git a/internal/publisher/js.go b/internal/publisher/js.go index 4b2366f..14e4919 100644 --- a/internal/publisher/js.go +++ b/internal/publisher/js.go @@ -56,7 +56,7 @@ func (p *JianshuPublisher) WaitLogin() (bool, string) { defer p.Close() p.Page.MustNavigate(p.EditorURL) - p.Sleep(3) + p.Sleep(10) if p.CheckLoginStatus() { p.SaveCookies() @@ -305,7 +305,7 @@ func (p *JianshuPublisher) PublishNote() (bool, string) { if err := p.SetupDriver(); err != nil { return false, fmt.Sprintf("浏览器启动失败: %v", err) } - defer p.Page.Close() + defer p.Close() steps := []struct { name string diff --git a/internal/publisher/shh.go b/internal/publisher/shh.go index e4cd741..b6c44ca 100644 --- a/internal/publisher/shh.go +++ b/internal/publisher/shh.go @@ -471,13 +471,20 @@ func (p *SohuPublisher) InitPage() error { if err := p.LoadCookies(); err == nil { p.Page.MustNavigate(p.EditorURL) p.WaitForPageReady(5) - p.Sleep(2) + } + // 统一检查登录状态 if !p.CheckLoginStatus() { p.LogInfo("未登录或登录已过期,需要重新登录") return fmt.Errorf("需要登录") } + p.Sleep(3) + + if p.GetCurrentURL() != p.EditorURL { + p.Page.MustNavigate(p.EditorURL) + p.WaitForPageReady(5) + } p.SaveCookies() return nil } @@ -488,7 +495,7 @@ func (p *SohuPublisher) PublishNote() (bool, string) { if err := p.SetupDriver(); err != nil { return false, fmt.Sprintf("浏览器启动失败: %v", err) } - defer p.Page.Close() + defer p.Close() steps := []struct { name string diff --git a/internal/publisher/sphsp.go b/internal/publisher/sphsp.go index 4ecb7a0..831513b 100644 --- a/internal/publisher/sphsp.go +++ b/internal/publisher/sphsp.go @@ -32,7 +32,7 @@ func (p *ShipinhaoVideoPublisher) PublishNote() (bool, string) { if err := p.SetupDriver(); err != nil { return false, fmt.Sprintf("浏览器启动失败: %v", err) } - defer p.Page.Close() + defer p.Close() // 3. 加载 cookies 并检查登录状态 if err := p.LoadCookies(); err == nil { p.Page.Navigate(p.EditorURL) diff --git a/internal/publisher/toutiao.go b/internal/publisher/toutiao.go index 7d10a01..3fe871d 100644 --- a/internal/publisher/toutiao.go +++ b/internal/publisher/toutiao.go @@ -473,7 +473,7 @@ func (p *ToutiaoPublisher) PublishNote() (bool, string) { if err := p.SetupDriver(); err != nil { return false, fmt.Sprintf("浏览器启动失败: %v", err) } - defer p.Page.Close() + defer p.Close() // 执行发布流程 steps := []struct { diff --git a/internal/publisher/xhs.go b/internal/publisher/xhs.go index a8fa728..9519db0 100644 --- a/internal/publisher/xhs.go +++ b/internal/publisher/xhs.go @@ -115,22 +115,13 @@ func (p *XiaohongshuPublisher) inputTitle() error { p.LogInfo("输入标题...") // 查找标题输入框 - titleSelectors := []string{ - "textarea.d-input", - ".d-input input", - "textarea[placeholder*='标题']", - "textarea", - } var titleInput *rod.Element - var err error - for _, selector := range titleSelectors { - titleInput, err = p.WaitForElementVisible(selector, 3) - if err == nil && titleInput != nil { - p.LogInfo(fmt.Sprintf("找到标题输入框: %s", selector)) - break - } + exsist, titleInput, err := p.Page.Has("textarea[placeholder*='标题']") + if exsist && err == nil { + p.LogInfo(fmt.Sprintf("找到标题输入框")) + } if titleInput == nil { @@ -286,8 +277,8 @@ func (p *XiaohongshuPublisher) clickPublish() error { // 输入话题标签 p.LogInfo("输入话题标签...") - tiptap, err := p.WaitForElement(".tiptap-container", 10) - if err == nil && tiptap != nil { + exist, tiptap, err := p.Page.Has(".tiptap-container") + if err == nil && exist { editors, err := tiptap.Elements("[contenteditable='true']") if err == nil && len(editors) > 0 { // 将tags转换为 #tag1 #tag2 格式 @@ -332,11 +323,17 @@ func (p *XiaohongshuPublisher) clickPublish() error { func (p *XiaohongshuPublisher) waitForPublishResult() (bool, string) { p.LogInfo("等待发布结果...") + // 检查URL是否包含success + info, err := p.Page.Info() + if err == nil && strings.Contains(info.URL, "success") { + p.LogInfo(fmt.Sprintf("发布成功,URL包含success: %s", info.URL)) + return true, "发布成功" + } for attempt := 0; attempt < 30; attempt++ { // 检查是否出现失败提示 - toastDiv, err := p.WaitForElement(".creator-publish-toast", 2) - if err == nil && toastDiv != nil { + exist, toastDiv, err := p.Page.Has(".creator-publish-toast") + if err == nil && exist { toastText, err := toastDiv.Text() if err == nil && toastText != "" { p.LogInfo(fmt.Sprintf("发布失败提示: %s", toastText)) @@ -344,13 +341,6 @@ func (p *XiaohongshuPublisher) waitForPublishResult() (bool, string) { } } - // 检查URL是否包含success - info, err := p.Page.Info() - if err == nil && strings.Contains(info.URL, "success") { - p.LogInfo(fmt.Sprintf("发布成功,URL包含success: %s", info.URL)) - return true, "发布成功" - } - p.SleepMs(1000) } @@ -427,7 +417,7 @@ func (p *XiaohongshuPublisher) PublishNote() (bool, string) { if err := p.SetupDriver(); err != nil { return false, fmt.Sprintf("浏览器启动失败: %v", err) } - defer p.Page.Close() + defer p.Close() // 执行发布流程 steps := []struct { diff --git a/internal/publisher/xhssp.go b/internal/publisher/xhssp.go index 46dafe3..9d2a377 100644 --- a/internal/publisher/xhssp.go +++ b/internal/publisher/xhssp.go @@ -175,30 +175,21 @@ func (p *XiaohongshuVideoPublisher) waitForUploadComplete() error { func (p *XiaohongshuVideoPublisher) inputTitle() error { p.LogInfo(fmt.Sprintf("输入视频标题: %s", p.Title)) - titleSelectors := []string{ - "textarea.d-input", - ".d-input input", - "input[type='text']", - "textarea", + exist, titleInput, err := p.Page.Has("input[placeholder*='标题']") + if err != nil { + return err } - - for _, selector := range titleSelectors { - titleInput, err := p.WaitForElementVisible(selector, 5) - if err == nil && titleInput != nil { - p.LogInfo(fmt.Sprintf("找到标题输入框: %s", selector)) - - p.ClearInput(titleInput) - p.SleepMs(300) - titleInput.Input("") - p.SleepMs(300) - titleInput.Input(p.Title) - - p.SleepMs(500) - return nil - } + if !exist { + return fmt.Errorf("未找到标题输入框") } - - return fmt.Errorf("未找到标题输入框") + p.ClearInput(titleInput) + p.SleepMs(300) + titleInput.Input("") + p.SleepMs(300) + titleInput.Input(p.Title) + p.LogInfo(fmt.Sprintf("标题已输入: %s", p.Title)) + p.SleepMs(500) + return nil } func (p *XiaohongshuVideoPublisher) inputDescription() error { diff --git a/internal/publisher/zh.go b/internal/publisher/zh.go index 1063919..c102e5e 100644 --- a/internal/publisher/zh.go +++ b/internal/publisher/zh.go @@ -350,23 +350,16 @@ func (p *ZhihuPublisher) waitForPublishResult(timeout int) (bool, string) { for time.Since(startTime) < time.Duration(timeout)*time.Second { currentURL := p.GetCurrentURL() - // 检查失败弹窗 - failedDiv, err := p.Page.Element(".Notification-textSection") - if err == nil && failedDiv != nil { - visible, _ := failedDiv.Visible() - if visible { - failedReason, _ := failedDiv.Text() - p.LogInfo(fmt.Sprintf("发布失败: %s", failedReason)) - return false, failedReason - } + if !strings.Contains(currentURL, "/edit") { + p.LogInfo(fmt.Sprintf("发布成功!URL: %s", currentURL)) + return true, "发布成功" } - - successKeywords := []string{"/p/", "/article/", "/people/", "/column/"} - for _, keyword := range successKeywords { - if strings.Contains(currentURL, keyword) && !strings.Contains(currentURL, "write") { - p.LogInfo(fmt.Sprintf("发布成功!URL: %s", currentURL)) - return true, "发布成功" - } + // 检查失败弹窗 + exist, failedDiv, _ := p.Page.HasX(".Notification-textSection") + if exist { + failedReason, _ := failedDiv.Text() + p.LogInfo(fmt.Sprintf("发布失败: %s", failedReason)) + return false, failedReason } p.SleepMs(1000) diff --git a/internal/service/a_test.go b/internal/service/a_test.go index ed13a55..b32bb02 100644 --- a/internal/service/a_test.go +++ b/internal/service/a_test.go @@ -2,6 +2,7 @@ package service import ( "fmt" + "os/exec" "sync" "testing" "time" @@ -27,10 +28,14 @@ func TestMultipleChromeProcesses(t *testing.T) { time.Sleep(10 * time.Minute) } +func TestKill(t *testing.T) { + exec.Command("taskkill", "/F", "/IM", "chrome.exe").Run() +} + // TestCustomChromeWithMixedHeadless 使用自定义Chrome浏览器,启动5个进程(偶数有头,奇数无头) func TestCustomChromeWithMixedHeadless(t *testing.T) { // 配置你的Chrome路径 - chromePath := "D:\\gop\\geoGo\\chrome\\chrome.exe" + chromePath := "D:\\goProject\\geogo\\chrome\\chrome.exe" processCount := 5 browsers := make([]*rod.Browser, processCount) @@ -111,7 +116,7 @@ func TestCustomChromeWithMixedHeadless(t *testing.T) { t.Logf("[进程 %d] 无头模式已访问 example.com(不可见)", idx) } - page.MustClose() + //page.MustClose() }(i) } @@ -132,7 +137,7 @@ func TestCustomChromeWithMixedHeadless(t *testing.T) { t.Logf("成功启动 %d/%d 个 Chrome 进程", successCount, processCount) t.Log("浏览器窗口已打开(有头模式可见),按 Enter 键关闭所有进程...") fmt.Scanln() - + select {} // 清理 //for i, browser := range browsers { // if browser != nil { diff --git a/internal/service/publish.go b/internal/service/publish.go index 6ecd292..1b77ce3 100644 --- a/internal/service/publish.go +++ b/internal/service/publish.go @@ -147,7 +147,7 @@ func (s *PublishService) PublishStatus(c *fiber.Ctx, req *entitys.PublishStatusR //} func (s *PublishService) PublishExecuteRetry(c *fiber.Ctx, req *entitys.PublishExecuteRetryRequest) error { - _, err := s.publishBiz.ValidateAccessToken(c.UserContext(), req.AccessToken) + tokenInfo, err := s.publishBiz.ValidateAccessToken(c.UserContext(), req.AccessToken) if err != nil { return err } @@ -156,7 +156,7 @@ func (s *PublishService) PublishExecuteRetry(c *fiber.Ctx, req *entitys.PublishE if err != nil { return err } - result := pm.RetryTask(c.UserContext(), req.RequestID) + result := pm.RetryTask(c.UserContext(), int(tokenInfo.ID), req.RequestID) return pkg.HandleResponse(c, result) } diff --git a/logs/tasks/2026-04-10/run.log b/logs/tasks/2026-04-10/run.log deleted file mode 100644 index 442dad5..0000000 --- a/logs/tasks/2026-04-10/run.log +++ /dev/null @@ -1,485 +0,0 @@ -GOROOT=D:\go #gosetup -GOPATH=D:\go #gosetup -D:\go\bin\go.exe build -o C:\Users\Administrator\AppData\Local\JetBrains\GoLand2025.2\tmp\GoLand\___go_build_geo_cmd_server.exe -gcflags "all=-N -l" geo/cmd/server #gosetup -warning: both GOPATH and GOROOT are the same directory (D:\go); see https://go.dev/wiki/InstallTroubleshooting -"D:\GoLand 2025.2.5\plugins\go-plugin\lib\dlv\windows\dlv.exe" --listen=127.0.0.1:62082 --headless=true --api-version=2 --check-go-version=false --only-same-user=false exec C:\Users\Administrator\AppData\Local\JetBrains\GoLand2025.2\tmp\GoLand\___go_build_geo_cmd_server.exe -- #gosetup -API server listening at: 127.0.0.1:62082 -WARNING: undefined behavior - version of Delve is too old for Go version go1.26.1 (maximum supported version 1.25) - - ┌───────────────────────────────────────────────────┐ - │ Fiber v2.52.12 │ - │ http://127.0.0.1:5001 │ - │ (bound on host 0.0.0.0 and port 5001) │ - │ │ - │ Handlers ............ 17 Processes ........... 1 │ - │ Prefork ....... Disabled PID ............. 22108 │ - └───────────────────────────────────────────────────┘ - - -2026/04/10 16:52:53 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[423.550ms] [rows:1] SELECT * FROM `token` WHERE access_token='6cb55ce2-2556-4908-91b5-5b78f0168cce' AND status=1 LIMIT 1 -token -16:52:53 | 200 | 424.6891ms | 127.0.0.1 | POST | /publish_on | - -2026/04/10 16:52:53 自动发布服务已启动,tokenID=1,worker数量=3 -2026/04/10 16:52:53 [Worker-1] 启动,tokenID=1 -2026/04/10 16:52:53 [Worker-2] 启动,tokenID=1 -2026/04/10 16:52:53 [Worker-0] 启动,tokenID=1 - -2026/04/10 16:52:54 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[412.746ms] [rows:1] - UPDATE publish p - SET p.status = 2,uid='cd76b1df-df01-4a' - WHERE p.request_id = ( - SELECT request_id FROM ( - SELECT p2.request_id - FROM publish p2 - INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index - WHERE p2.token_id = 1 - AND p2.status = 1 - AND p2.publish_time <= '2026-04-10 16:52:53' - AND pl.status = 1 - ORDER BY p2.publish_time ASC - LIMIT 1 - ) AS tmp - ) - AND p.status = 1 - -publish - -2026/04/10 16:52:54 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[418.524ms] [rows:1] - UPDATE publish p - SET p.status = 2,uid='f2a6982a-8bef-4e' - WHERE p.request_id = ( - SELECT request_id FROM ( - SELECT p2.request_id - FROM publish p2 - INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index - WHERE p2.token_id = 1 - AND p2.status = 1 - AND p2.publish_time <= '2026-04-10 16:52:53' - AND pl.status = 1 - ORDER BY p2.publish_time ASC - LIMIT 1 - ) AS tmp - ) - AND p.status = 1 - -publish - -2026/04/10 16:52:54 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[425.694ms] [rows:1] - UPDATE publish p - SET p.status = 2,uid='eba6d8a6-88c3-49' - WHERE p.request_id = ( - SELECT request_id FROM ( - SELECT p2.request_id - FROM publish p2 - INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index - WHERE p2.token_id = 1 - AND p2.status = 1 - AND p2.publish_time <= '2026-04-10 16:52:53' - AND pl.status = 1 - ORDER BY p2.publish_time ASC - LIMIT 1 - ) AS tmp - ) - AND p.status = 1 - -publish - -2026/04/10 16:52:54 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[391.244ms] [rows:1] - SELECT - p.request_id, - p.plat_index, - p.title, - p.tag, - p.user_index, - p.url, - p.img, - p.publish_time, - p.status, - pl.index as plat_index_value, - pl.status as plat_status, - pl.login_url, - pl.edit_url, - pl.logined_url, - pl.desc - FROM publish p - INNER JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index AND pl.status = 1 - WHERE uid='cd76b1df-df01-4a' AND p.token_id = 1 - ORDER BY p.publish_time DESC - LIMIT 1 - -publish -2026/04/10 16:52:54.478724 ================================================================================ -2026/04/10 16:52:54.478724 任务开始 | RequestID: 6 | 时间: 2026-04-10 16:52:54.478 -2026/04/10 16:52:54.478724 ================================================================================ -2026/04/10 16:52:54.478724 [任务 6] 开始处理(headless=true) -2026/04/10 16:52:54.478724 [任务 6] 任务详情 - 平台:zh,标题:地推看过来!!!,用户:0d86b848uu2183uu4a08 -2026/04/10 16:52:54.478724 [任务 6] 标签解析完成: [#地推 #四川地推 #创业] -2026/04/10 16:52:54.478724 [任务 6] 开始下载文档... -2026/04/10 16:52:54 [Worker-1] 开始处理任务 requestID=6 - -2026/04/10 16:52:54 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[406.859ms] [rows:1] - SELECT - p.request_id, - p.plat_index, - p.title, - p.tag, - p.user_index, - p.url, - p.img, - p.publish_time, - p.status, - pl.index as plat_index_value, - pl.status as plat_status, - pl.login_url, - pl.edit_url, - pl.logined_url, - pl.desc - FROM publish p - INNER JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index AND pl.status = 1 - WHERE uid='f2a6982a-8bef-4e' AND p.token_id = 1 - ORDER BY p.publish_time DESC - LIMIT 1 - -publish -2026/04/10 16:52:54.499312 ================================================================================ -2026/04/10 16:52:54.499312 任务开始 | RequestID: 4 | 时间: 2026-04-10 16:52:54.499 -2026/04/10 16:52:54.499312 ================================================================================ -2026/04/10 16:52:54.499840 [任务 4] 开始处理(headless=true) -2026/04/10 16:52:54.499840 [任务 4] 任务详情 - 平台:xhssp,标题:萌妹,用户:0d86b848uu2183uu4a08 -2026/04/10 16:52:54.499840 [任务 4] 标签解析完成: [萌妹 宅舞 超性感] -2026/04/10 16:52:54.499840 [任务 4] 开始下载文档... - -2026/04/10 16:52:54 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[401.220ms] [rows:1] - SELECT - p.request_id, - p.plat_index, - p.title, - p.tag, - p.user_index, - p.url, - p.img, - p.publish_time, - p.status, - pl.index as plat_index_value, - pl.status as plat_status, - pl.login_url, - pl.edit_url, - pl.logined_url, - pl.desc - FROM publish p - INNER JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index AND pl.status = 1 - WHERE uid='eba6d8a6-88c3-49' AND p.token_id = 1 - ORDER BY p.publish_time DESC - LIMIT 1 - -publish -2026/04/10 16:52:54.501413 ================================================================================ -2026/04/10 16:52:54.501413 任务开始 | RequestID: 5 | 时间: 2026-04-10 16:52:54.501 -2026/04/10 16:52:54.501413 ================================================================================ -2026/04/10 16:52:54.501413 [任务 5] 开始处理(headless=true) -2026/04/10 16:52:54.501413 [任务 5] 任务详情 - 平台:sphsp,标题:盘点全网最火的meme原型,用户:0d86b848uu2183uu4a08 -2026/04/10 16:52:54.501413 [任务 5] 标签解析完成: [猫 meme 万恶之源] -2026/04/10 16:52:54.501413 [任务 5] 开始下载文档... -2026/04/10 16:52:54 [Worker-2] 开始处理任务 requestID=4 -2026/04/10 16:52:54 [Worker-0] 开始处理任务 requestID=5 -2026/04/10 16:52:54.568721 [任务 6] ✅ 文档下载成功: D:\gop\geoGo\docs\6.docx -2026/04/10 16:52:54.569769 [任务 6] 开始下载图片... -2026/04/10 16:52:54.629638 [任务 6] ✅ 图片下载成功: D:\gop\geoGo\images\6_1e3dcdb4-0f8a-4b57-aac2-85ecff03ff12.jpg -2026/04/10 16:52:55.723048 [任务 4] ✅ 文档下载成功: D:\gop\geoGo\docs\4.mp4 -2026/04/10 16:52:55.723048 [任务 4] 开始下载图片... -2026/04/10 16:52:56.014721 [任务 5] ✅ 文档下载成功: D:\gop\geoGo\docs\5.mp4 -2026/04/10 16:52:56.015773 [任务 5] 开始下载图片... -2026/04/10 16:52:56.206874 [任务 5] ✅ 图片下载成功: D:\gop\geoGo\images\5_003e4110-e937-491f-8cf2-92df3de00a8c.png -2026/04/10 16:52:56.206874 [任务 5] 开始执行发布... -2026/04/10 16:52:56.206874 📌 ================================================== -2026/04/10 16:52:56.206874 📌 开始执行:sphsp -2026/04/10 16:52:56.206874 📌 标题: 盘点全网最火的meme原型 -2026/04/10 16:52:56.206874 📌 标签: [猫 meme 万恶之源] -2026/04/10 16:52:56.206874 📌 ================================================== -2026/04/10 16:52:56.206874 📌 初始化浏览器。。。。 -2026/04/10 16:52:56.233002 [任务 4] ✅ 图片下载成功: D:\gop\geoGo\images\4_769c6040-bff9-472b-9b9c-33d8f74cf61f.png -2026/04/10 16:52:56.233002 [任务 4] 开始执行发布... -2026/04/10 16:52:56.233002 📌 ================================================== -2026/04/10 16:52:56.233002 📌 开始执行:xhssp -2026/04/10 16:52:56.233002 📌 标题: 萌妹 -2026/04/10 16:52:56.233002 📌 标签: [萌妹 宅舞 超性感] -2026/04/10 16:52:56.233002 📌 ================================================== -2026/04/10 16:52:56.233002 📌 初始化浏览器。。。。 -2026/04/10 16:52:56.907120 [任务 6] 开始提取文档内容... -2026/04/10 16:52:58.614081 [任务 6] ✅ 内容提取成功,长度: 69 -2026/04/10 16:52:58.614081 [任务 6] 开始执行发布... -2026/04/10 16:52:58.614081 📌 ================================================== -2026/04/10 16:52:58.614081 📌 开始执行:zh -2026/04/10 16:52:58.614081 📌 标题: 地推看过来!!! -2026/04/10 16:52:58.614081 📌 标签: [#地推 #四川地推 #创业] -2026/04/10 16:52:58.614081 📌 ================================================== -2026/04/10 16:52:58.614081 📌 初始化浏览器。。。。 -2026/04/10 16:52:58.616804 ✅ 初始化页面: 成功 -2026/04/10 16:52:59.468517 [任务 5] ❌ 发布失败: 需要登录 -2026/04/10 16:52:59.617059 📌 开始上传视频: D:\gop\geoGo\docs\4.mp4 -2026/04/10 16:52:59.646726 📌 视频文件已选择: D:\gop\geoGo\docs\4.mp4 -2026/04/10 16:52:59.646726 📌 等待视频上传完成... - -2026/04/10 16:52:59 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[429.171ms] [rows:1] UPDATE publish SET status = 3, msg = '需要登录' WHERE token_id=1 AND request_id = '5' -publish -2026/04/10 16:52:59.897687 ================================================================================ -2026/04/10 16:52:59.897687 任务结束 | RequestID: 5 | 结果: false -2026/04/10 16:52:59.898712 [任务 5] 已删除文档文件: D:\gop\geoGo\docs\5.mp4 -2026/04/10 16:52:59.899367 [任务 5] 已删除图片文件: D:\gop\geoGo\images\5_003e4110-e937-491f-8cf2-92df3de00a8c.png -2026/04/10 16:52:59 [Worker-0] 任务失败: 需要登录 -2026/04/10 16:53:00.050108 📌 发布按钮已可点击,视频上传完成 -2026/04/10 16:53:00.050108 ✅ 上传视频: 成功 -2026/04/10 16:53:01.050256 📌 输入视频标题: 萌妹 -2026/04/10 16:53:01.755888 📌 未登录或登录已过期,需要重新登录 -2026/04/10 16:53:01.755888 ❌ 初始化页面: 失败 需要登录 -2026/04/10 16:53:01.779792 [任务 6] ❌ 发布失败: 初始化页面失败: 需要登录 - -2026/04/10 16:53:02 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[427.718ms] [rows:1] UPDATE publish SET status = 3, msg = '初始化页面失败: 需要登录' WHERE token_id=1 AND request_id = '6' -publish -2026/04/10 16:53:02.207510 ================================================================================ -2026/04/10 16:53:02.207510 任务结束 | RequestID: 6 | 结果: false -2026/04/10 16:53:02.208014 [任务 6] 已删除文档文件: D:\gop\geoGo\docs\6.docx -2026/04/10 16:53:02.208014 [任务 6] 已删除图片文件: D:\gop\geoGo\images\6_1e3dcdb4-0f8a-4b57-aac2-85ecff03ff12.jpg -2026/04/10 16:53:02 [Worker-1] 任务失败: 初始化页面失败: 需要登录 - -2026/04/10 16:53:02 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[406.214ms] [rows:1] - UPDATE publish p - SET p.status = 2,uid='e3a191eb-07d2-48' - WHERE p.request_id = ( - SELECT request_id FROM ( - SELECT p2.request_id - FROM publish p2 - INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index - WHERE p2.token_id = 1 - AND p2.status = 1 - AND p2.publish_time <= '2026-04-10 16:53:01' - AND pl.status = 1 - ORDER BY p2.publish_time ASC - LIMIT 1 - ) AS tmp - ) - AND p.status = 1 - -publish -2026/04/10 16:53:02.529767 ❌ 输入标题: 失败 未找到标题输入框 -2026/04/10 16:53:02.529767 [任务 4] ❌ 发布失败: 输入标题失败: 未找到标题输入框 - -2026/04/10 16:53:02 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[379.609ms] [rows:1] - SELECT - p.request_id, - p.plat_index, - p.title, - p.tag, - p.user_index, - p.url, - p.img, - p.publish_time, - p.status, - pl.index as plat_index_value, - pl.status as plat_status, - pl.login_url, - pl.edit_url, - pl.logined_url, - pl.desc - FROM publish p - INNER JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index AND pl.status = 1 - WHERE uid='e3a191eb-07d2-48' AND p.token_id = 1 - ORDER BY p.publish_time DESC - LIMIT 1 - -publish -2026/04/10 16:53:02.686657 ================================================================================ -2026/04/10 16:53:02.686657 任务开始 | RequestID: 1 | 时间: 2026-04-10 16:53:02.686 -2026/04/10 16:53:02.686657 ================================================================================ -2026/04/10 16:53:02.686657 [任务 1] 开始处理(headless=true) -2026/04/10 16:53:02.686657 [任务 1] 任务详情 - 平台:xhs,标题:房地产新格局,用户:0d86b848uu2183uu4a08 -2026/04/10 16:53:02.686657 [任务 1] 标签解析完成: [房地产 房地产格局] -2026/04/10 16:53:02.686657 [任务 1] 开始下载文档... -2026/04/10 16:53:02 [Worker-0] 开始处理任务 requestID=1 -2026/04/10 16:53:02.750797 [任务 1] ✅ 文档下载成功: D:\gop\geoGo\docs\1.docx -2026/04/10 16:53:02.750797 [任务 1] 开始下载图片... - -2026/04/10 16:53:02 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[445.705ms] [rows:1] UPDATE publish SET status = 3, msg = '输入标题失败: 未找到标题输入框' WHERE token_id=1 AND request_id = '4' -publish -2026/04/10 16:53:02.975473 ================================================================================ -2026/04/10 16:53:02.975473 任务结束 | RequestID: 4 | 结果: false -2026/04/10 16:53:02.976009 [任务 4] 已删除文档文件: D:\gop\geoGo\docs\4.mp4 -2026/04/10 16:53:02.976539 [任务 4] 已删除图片文件: D:\gop\geoGo\images\4_769c6040-bff9-472b-9b9c-33d8f74cf61f.png -2026/04/10 16:53:02 [Worker-2] 任务失败: 输入标题失败: 未找到标题输入框 -2026/04/10 16:53:03.042424 [任务 1] ✅ 图片下载成功: D:\gop\geoGo\images\1_9ffe0dd7-108b-455d-aca4-bf729eba7ab9.png -2026/04/10 16:53:03.042424 [任务 1] 开始提取文档内容... - -2026/04/10 16:53:04 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[378.221ms] [rows:1] - UPDATE publish p - SET p.status = 2,uid='5b37ab96-e0de-46' - WHERE p.request_id = ( - SELECT request_id FROM ( - SELECT p2.request_id - FROM publish p2 - INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index - WHERE p2.token_id = 1 - AND p2.status = 1 - AND p2.publish_time <= '2026-04-10 16:53:04' - AND pl.status = 1 - ORDER BY p2.publish_time ASC - LIMIT 1 - ) AS tmp - ) - AND p.status = 1 - -publish -2026/04/10 16:53:04.715720 [任务 1] ✅ 内容提取成功,长度: 5372 -2026/04/10 16:53:04.715720 [任务 1] 开始执行发布... -2026/04/10 16:53:04.715720 📌 ================================================== -2026/04/10 16:53:04.715720 📌 开始执行:xhs -2026/04/10 16:53:04.715720 📌 标题: 房地产新格局 -2026/04/10 16:53:04.715720 📌 标签: [房地产 房地产格局] -2026/04/10 16:53:04.715720 📌 ================================================== -2026/04/10 16:53:04.715720 📌 初始化浏览器。。。。 - -2026/04/10 16:53:05 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[421.319ms] [rows:1] - SELECT - p.request_id, - p.plat_index, - p.title, - p.tag, - p.user_index, - p.url, - p.img, - p.publish_time, - p.status, - pl.index as plat_index_value, - pl.status as plat_status, - pl.login_url, - pl.edit_url, - pl.logined_url, - pl.desc - FROM publish p - INNER JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index AND pl.status = 1 - WHERE uid='5b37ab96-e0de-46' AND p.token_id = 1 - ORDER BY p.publish_time DESC - LIMIT 1 - -publish -2026/04/10 16:53:05.009080 ================================================================================ -2026/04/10 16:53:05.009080 任务开始 | RequestID: 2 | 时间: 2026-04-10 16:53:05.009 -2026/04/10 16:53:05.009080 ================================================================================ -2026/04/10 16:53:05.009080 [任务 2] 开始处理(headless=true) -2026/04/10 16:53:05.009080 [任务 2] 任务详情 - 平台:xhs,标题:健身与猝死的关系,用户:0d86b848uu2183uu4a08 -2026/04/10 16:53:05.009080 [任务 2] 标签解析完成: [健身 猝死] -2026/04/10 16:53:05.009080 [任务 2] 开始下载文档... -2026/04/10 16:53:05 [Worker-1] 开始处理任务 requestID=2 -2026/04/10 16:53:05.067271 [任务 2] ✅ 文档下载成功: D:\gop\geoGo\docs\2.docx -2026/04/10 16:53:05.067271 [任务 2] 开始下载图片... -2026/04/10 16:53:05.309691 [任务 2] ✅ 图片下载成功: D:\gop\geoGo\images\2_ec459546-2873-4539-ae96-4d99c19ec62d.jpg -2026/04/10 16:53:05.309691 [任务 2] 开始提取文档内容... - -2026/04/10 16:53:05 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[401.004ms] [rows:0] - UPDATE publish p - SET p.status = 2,uid='d54d1bab-80a4-4a' - WHERE p.request_id = ( - SELECT request_id FROM ( - SELECT p2.request_id - FROM publish p2 - INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index - WHERE p2.token_id = 1 - AND p2.status = 1 - AND p2.publish_time <= '2026-04-10 16:53:04' - AND pl.status = 1 - ORDER BY p2.publish_time ASC - LIMIT 1 - ) AS tmp - ) - AND p.status = 1 - -publish -2026/04/10 16:53:06.894855 [任务 2] ✅ 内容提取成功,长度: 2274 -2026/04/10 16:53:06.894855 [任务 2] 开始执行发布... -2026/04/10 16:53:06.894855 📌 ================================================== -2026/04/10 16:53:06.894855 📌 开始执行:xhs -2026/04/10 16:53:06.894855 📌 标题: 健身与猝死的关系 -2026/04/10 16:53:06.894855 📌 标签: [健身 猝死] -2026/04/10 16:53:06.894855 📌 ================================================== -2026/04/10 16:53:06.894855 📌 初始化浏览器。。。。 -2026/04/10 16:53:07.849886 ✅ 初始化: 成功 -2026/04/10 16:53:08.352714 ✅ 保存cookie: 成功 -2026/04/10 16:53:09.245978 ✅ 初始化: 成功 -2026/04/10 16:53:09.748755 ✅ 保存cookie: 成功 -2026/04/10 16:53:10.331882 📌 已点击上传按钮 -2026/04/10 16:53:11.332203 ✅ 点击上传按钮: 成功 -2026/04/10 16:53:11.832762 📌 输入文章内容... -2026/04/10 16:53:12.378724 📌 清空编辑器失败: eval js error: TypeError: Cannot set properties of undefined (setting 'innerText') - at HTMLDivElement. (:1:44) - at HTMLDivElement. (:1:127) -2026/04/10 16:53:12.748818 📌 内容已输入,长度: 2274 -2026/04/10 16:53:12.748818 ✅ 输入内容: 成功 -2026/04/10 16:53:13.249362 📌 输入标题... - -2026/04/10 16:53:37 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[438.945ms] [rows:0] - UPDATE publish p - SET p.status = 2,uid='49e9bf0f-120a-4c' - WHERE p.request_id = ( - SELECT request_id FROM ( - SELECT p2.request_id - FROM publish p2 - INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index - WHERE p2.token_id = 1 - AND p2.status = 1 - AND p2.publish_time <= '2026-04-10 16:53:37' - AND pl.status = 1 - ORDER BY p2.publish_time ASC - LIMIT 1 - ) AS tmp - ) - AND p.status = 1 - -publish -2026/04/10 16:54:02 任务执行超时,[Worker-0] context deadline exceeded requestID=1 -2026/04/10 16:54:02.688485 click fail:context deadline exceeded -2026/04/10 16:54:02.688485 ❌ 点击上传按钮: 失败 JS点击按钮失败: context deadline exceeded -2026/04/10 16:54:02.689219 [任务 1] ❌ 发布失败: 点击上传按钮失败: JS点击按钮失败: context deadline exceeded - -2026/04/10 16:54:03 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[421.134ms] [rows:1] UPDATE publish SET status = 3, msg = '任务执行超时,[Worker-0] context deadline exceeded requestID=1' WHERE token_id=1 AND request_id = '1' -publish - -2026/04/10 16:54:03 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[470.041ms] [rows:1] UPDATE publish SET status = 3, msg = '点击上传按钮失败: JS点击按钮失败: context deadline exceeded' WHERE token_id=1 AND request_id = '1' -publish -2026/04/10 16:54:03.159260 ================================================================================ -2026/04/10 16:54:03.159260 任务结束 | RequestID: 1 | 结果: false -2026/04/10 16:54:03.159767 [任务 1] 已删除文档文件: D:\gop\geoGo\docs\1.docx -2026/04/10 16:54:03.160296 [任务 1] 已删除图片文件: D:\gop\geoGo\images\1_9ffe0dd7-108b-455d-aca4-bf729eba7ab9.png -2026/04/10 16:54:05 任务执行超时,[Worker-1] context deadline exceeded requestID=2 -2026/04/10 16:54:05.009280 ❌ 输入标题: 失败 未找到标题输入框 -2026/04/10 16:54:05.009280 [任务 2] ❌ 发布失败: 输入标题失败: 未找到标题输入框 - -2026/04/10 16:54:05 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[403.700ms] [rows:1] UPDATE publish SET status = 3, msg = '任务执行超时,[Worker-1] context deadline exceeded requestID=2' WHERE token_id=1 AND request_id = '2' -publish - -2026/04/10 16:54:05 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms -[428.723ms] [rows:1] UPDATE publish SET status = 3, msg = '输入标题失败: 未找到标题输入框' WHERE token_id=1 AND request_id = '2' -publish -2026/04/10 16:54:05.438513 ================================================================================ -2026/04/10 16:54:05.438513 任务结束 | RequestID: 2 | 结果: false -2026/04/10 16:54:05.439077 [任务 2] 已删除文档文件: D:\gop\geoGo\docs\2.docx -2026/04/10 16:54:05.439641 [任务 2] 已删除图片文件: D:\gop\geoGo\images\2_ec459546-2873-4539-ae96-4d99c19ec62d.jpg - -