Merge branch 'master' of http://222.71.114.84:7070/r/AutoMediaPublisher
| | |
| | | data/docx_final/ |
| | | data/docx_selected/ |
| | | data/images_layer/ |
| | | data/video_draft/ |
| | | data/video_final/ |
| | | data/media_draft/ |
| | | data/media_final/ |
| | | |
| | | data/taijiniao/ |
| | | data/dajiala_top15_data.json |
| | |
| | | # 开发环境,基于当前文件往上两级 |
| | | BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")) |
| | | |
| | | VIDEO_DIR_DRAFT = os.path.join(BASE_DIR, "data/video_draft") |
| | | VIDEO_DIR_FINAL = os.path.join(BASE_DIR, "data/video_final") |
| | | VIDEO_DIR_DRAFT = os.path.join(BASE_DIR, "data/media_draft") |
| | | VIDEO_DIR_FINAL = os.path.join(BASE_DIR, "data/media_final") |
| | | COOKIE_DIR = os.path.join(BASE_DIR, "data/cookies") |
| | | DOCX_DIR_DOWNLOADED = os.path.join(BASE_DIR, "data/docx_downloaded") |
| | | DOCX_DIR_SELECTED = os.path.join(BASE_DIR, "data/docx_selected") |
| New file |
| | |
| | | STORY_PROMPT_PARAMETERS ={ |
| | | "who": [ |
| | | "从深圳程序员老公的视角", |
| | | "从杭州全职太太的视角", |
| | | "从北京国企干部老妈的视角", |
| | | "从广州海归博士老公的视角", |
| | | "从长沙开美容院的嫂子的视角", |
| | | "从西安卖房中介的弟弟的视角", |
| | | "从成都摆摊卖卤味的姐姐的视角", |
| | | "从南京大学刚毕业女儿的视角", |
| | | "从重庆网红媳妇的视角", |
| | | "从上海离婚律师的闺蜜视角", |
| | | "从河北县城人民医院医生的妈妈视角", |
| | | "从东北下岗工人爸爸的视角", |
| | | "从福建小镇高中班主任的视角", |
| | | "从云南开民宿的大姑姐视角", |
| | | "从天津做抖音直播的表妹视角", |
| | | "从合肥房地产开发商小叔子的视角", |
| | | "从青岛刚生完二胎的嫂子的视角", |
| | | "从贵阳出租车司机爸爸的视角", |
| | | "从济南做公考辅导老师的表姐视角", |
| | | "从南昌全款买房男友的视角", |
| | | "从兰州单亲妈妈的视角", |
| | | "从哈尔滨家政保姆的视角", |
| | | "从太原刚离婚的闺蜜视角", |
| | | "从大理混文创圈的小白视角", |
| | | "从呼和浩特部队转业父亲的视角", |
| | | "从石家庄搞装修的小姨夫视角", |
| | | "从宁波开公司三婚小白的视角", |
| | | "从郑州幼儿园老师的视角", |
| | | "从厦门富二代男朋友的视角", |
| | | "从长春退休老教师奶奶的视角", |
| | | "从乌鲁木齐民族学校支教女儿的视角", |
| | | "从中山银行工作的儿媳视角", |
| | | "从南宁夜市摊贩的老公视角", |
| | | "从苏州互联网大厂女同事的视角", |
| | | "从温州炒房团二叔的视角", |
| | | "从珠海跨境电商老板娘的视角", |
| | | "从汕头农村老家的大姨妈视角", |
| | | "从湖南怀化农村彩礼谈崩的表弟视角", |
| | | "从湖北宜昌刚转正女公务员视角", |
| | | "从安徽六安初中校长父亲的视角", |
| | | "从四川绵阳被催婚的女研究生视角", |
| | | "从山东临沂菜市场卖鸡蛋的妈的视角", |
| | | "从江西赣州火车站擦鞋阿姨的视角", |
| | | "从广西北海夜市摆摊夫妻的视角", |
| | | "从贵州遵义装修工地的舅舅视角", |
| | | "从内蒙古包头矿区出身母亲的视角", |
| | | "从海南三亚做旅拍摄影的小叔子的视角", |
| | | "从西藏拉萨支教女老师的视角", |
| | | "从宁夏银川药企高管嫂子的视角", |
| | | "从甘肃陇南教体局表哥的视角", |
| | | "从新疆伊犁援疆医生的视角", |
| | | "从重庆高铁上偶遇的大姐视角", |
| | | "从北京学区房投资人父亲的视角", |
| | | "从深圳月入三万却住出租屋女儿的视角", |
| | | "从广州KTV夜场驻唱男友的视角", |
| | | "从长沙婚介所老板娘的视角", |
| | | "从成都二胎奶爸下班后的视角", |
| | | "从天津开串串香的妹夫视角", |
| | | "从南京养老院护工的视角", |
| | | "从上海育儿焦虑妈妈群管理员的视角", |
| | | "从青岛婚礼摄影师的视角", |
| | | "从合肥法院执行局的妹夫视角", |
| | | "从西安小商品批发市场的老婆视角", |
| | | "从南昌火锅店老板娘的视角", |
| | | "从济南公园跳广场舞阿姨的视角", |
| | | "从哈尔滨大专刚毕业女儿的视角", |
| | | "从厦门写公众号搞副业的妈妈视角", |
| | | "从大理自由摄影师的大舅哥视角", |
| | | "从太原老旧小区保安大爷的视角", |
| | | "从呼和浩特去考研的侄女视角", |
| | | "从石家庄初恋女友的视角", |
| | | "从郑州公务员父亲的视角", |
| | | "从南宁乡镇基层干部的视角", |
| | | "从苏州独居中年未婚姐姐的视角", |
| | | "从温州离异带娃的堂哥视角", |
| | | "从珠海跨省探亲婆婆的视角", |
| | | "从汕头同乡微信群里爆料的视角", |
| | | "从广西村口看热闹的奶奶视角", |
| | | "从贵州回乡建房的外甥视角", |
| | | "从海南房产中介的视角", |
| | | "从新疆街头发传单的学生视角", |
| | | "从上海家庭会议群里的小姑子视角", |
| | | "从北京离异男律师的视角", |
| | | "从杭州焦虑考编的准女婿视角", |
| | | "从广州996搬砖程序员的前女友视角", |
| | | "从成都脱口秀演员闺蜜的视角", |
| | | "从天津婚礼现场的前任视角", |
| | | "从重庆火锅店老板的闺蜜视角", |
| | | "从南京网友线下见面的视角", |
| | | "从合肥宠物医院的实习医生视角", |
| | | "从长沙失业又复合的前夫视角", |
| | | "从大理短租房房东的视角", |
| | | "从深圳高薪但孤独女儿的视角", |
| | | "从珠海打算裸辞去支教的表妹视角" |
| | | ], |
| | | "what": [ |
| | | "婆婆发现媳妇手机里的秘密聊天记录", |
| | | "老公突然宣布要离婚,理由让人震惊", |
| | | "小姑子暗中破坏新婚生活", |
| | | "孩子被陌生人接走引发全家混乱", |
| | | "婆媳为一张遗嘱争执不下", |
| | | "闺蜜背后捅刀,抢走好闺蜜老公", |
| | | "老公事业失败隐瞒家人真相", |
| | | "妻子发现老公出轨同事", |
| | | "家庭聚会爆发口角,揭露多年秘密", |
| | | "丈夫身患重病却瞒着妻子", |
| | | "小姑子设计嫁祸媳妇偷钱", |
| | | "婆婆私自处理孙子教育问题", |
| | | "前任突然出现搅局", |
| | | "丈夫被举报职务违规,家庭陷入危机", |
| | | "妻子怀孕遭遇流产,夫妻矛盾激化", |
| | | "婆婆强行干涉儿子婚姻生活", |
| | | "媳妇被邻居陷害偷窃", |
| | | "丈夫意外发现自己并非亲生父亲", |
| | | "家中遗产被律师悄悄改写", |
| | | "儿媳为了孩子与婆婆冷战数月", |
| | | "丈夫旧爱归来,家庭陷入纷争", |
| | | "媳妇意外怀上二胎,丈夫态度突然转变", |
| | | "婆婆暗中给孙子换学校", |
| | | "小姑子故意向父母抹黑媳妇", |
| | | "孩子的亲生父亲身份曝光", |
| | | "老公深夜神秘失踪,引发全家恐慌", |
| | | "妻子被小三威胁分手", |
| | | "婆婆与儿媳争夺家庭财产", |
| | | "丈夫偷偷背着妻子还债", |
| | | "媳妇发现丈夫曾有双重身份", |
| | | "前夫带孩子归来,引发抚养权大战", |
| | | "婆婆私自拿走结婚礼金", |
| | | "丈夫被老板调职外地,夫妻感情考验", |
| | | "妻子误会丈夫与女同事亲密", |
| | | "儿媳与公公之间暗生情愫", |
| | | "婆婆组织家庭投票决定儿子婚姻", |
| | | "小姑子暗中拍摄家庭矛盾视频外泄", |
| | | "丈夫被好友骗财,妻子倾力相助", |
| | | "婆婆发现儿媳隐瞒真实学历", |
| | | "儿子突然宣布结婚,媳妇不满", |
| | | "妻子发现丈夫旧手机藏有秘密照片", |
| | | "婆婆私下策划家庭聚会背后暗藏阴谋", |
| | | "小姑子在朋友圈散布家庭不和谣言", |
| | | "丈夫被朋友出卖,事业一落千丈", |
| | | "妻子得知婆婆曾经隐瞒重大病情", |
| | | "儿媳为了事业离家出走", |
| | | "婆婆偷偷帮儿子安排相亲", |
| | | "丈夫在外有私生子,家庭风暴爆发", |
| | | "妻子发现老公隐藏的巨额债务", |
| | | "婆婆与媳妇为装修风格争执", |
| | | "儿媳借机逼迫婆婆出售老宅", |
| | | "丈夫深夜与陌生女子通话", |
| | | "妻子发现婆婆竟是自己亲生母亲", |
| | | "小姑子故意制造家庭冷战", |
| | | "婆婆秘密帮助儿媳复职", |
| | | "丈夫隐瞒生病住院消息", |
| | | "媳妇私自卖掉家庭资产", |
| | | "妻子遭遇网络暴力,丈夫无力保护", |
| | | "婆婆暗中资助儿子创业", |
| | | "小姑子偷藏家中重要文件", |
| | | "丈夫为家庭默默承担巨额贷款", |
| | | "妻子怀疑婆婆监视自己", |
| | | "儿媳深夜外出,被丈夫误会出轨", |
| | | "婆婆与邻居合谋拆迁风波", |
| | | "丈夫与前女友秘密联系", |
| | | "妻子被发现参加秘密聚会", |
| | | "小姑子抢走家族生意关键客户", |
| | | "婆婆因旧疾隐瞒病情", |
| | | "丈夫丢失重要合同,危及家庭经济", |
| | | "妻子发现丈夫暗中设立私房账户", |
| | | "儿媳拒绝婆婆安排的生活方式", |
| | | "婆婆为儿子秘密买房", |
| | | "小姑子举报家族企业违规", |
| | | "丈夫遭遇职场性骚扰", |
| | | "妻子发现婆婆与前夫有联系", |
| | | "婆婆计划让儿媳放弃工作", |
| | | "丈夫暗中帮助前妻还债", |
| | | "妻子意外发现家庭老照片真相", |
| | | "小姑子偷偷拍摄家庭秘密", |
| | | "婆婆为孙子教育费用暗中筹款", |
| | | "丈夫被迫辞职,家庭陷入困境", |
| | | "妻子秘密学习理财", |
| | | "儿媳与婆婆和解,家庭气氛缓和", |
| | | "婆婆要求儿子加快买房速度", |
| | | "丈夫与闺蜜关系暧昧", |
| | | "妻子发现丈夫以前有犯罪记录", |
| | | "小姑子设计让婆婆失望", |
| | | "婆婆患病未告知儿媳", |
| | | "丈夫暗中调查妻子手机", |
| | | "妻子怀疑小姑子窥探隐私", |
| | | "儿媳为了孩子忍让婆婆", |
| | | "婆婆计划搬到儿子家同住", |
| | | "丈夫失业,妻子独自撑起家庭", |
| | | "妻子发现丈夫双重生活", |
| | | "小姑子闹家庭聚会变故", |
| | | "婆婆安排儿子与邻居女儿相亲", |
| | | "丈夫被诬陷贪污", |
| | | "妻子发现儿子与小姑子秘密联络", |
| | | "丈夫突然提出全家搬迁引发矛盾", |
| | | "妻子发现婆婆藏匿儿子过去丑闻", |
| | | "小姑子意外怀孕,家庭陷入混乱", |
| | | "婆婆偷偷带孙子参加补习班", |
| | | "丈夫外出出差时被卷入商业纠纷", |
| | | "妻子秘密联系前男友引发误会", |
| | | "小姑子暗地里搞垮嫂子的生意", |
| | | "婆婆与邻居联手对付媳妇", |
| | | "丈夫意外失忆,家庭身份错乱", |
| | | "妻子发现丈夫背着她买豪车", |
| | | "儿媳无意间发现家族财产分配秘密", |
| | | "婆婆与媳妇为孙子教育费用争吵", |
| | | "丈夫在外有二婚妻子被发现", |
| | | "妻子被婆婆设计陷害职场失意", |
| | | "小姑子利用手机监听家庭对话", |
| | | "婆婆暗中干预儿子事业", |
| | | "丈夫拒绝带孩子回婆家过年", |
| | | "妻子发现小姑子对儿子有非分之想", |
| | | "婆婆偷偷修改遗嘱内容", |
| | | "丈夫与外遇女同事被抓现行", |
| | | "妻子被邻居误解偷拿孩子玩具", |
| | | "小姑子设计嫁祸弟媳家暴", |
| | | "婆婆逼迫儿媳放弃梦想职业", |
| | | "丈夫为家庭隐瞒负债真相", |
| | | "妻子发现丈夫手机中隐藏多重身份", |
| | | "儿媳与婆婆因家务问题冷战", |
| | | "婆婆偷偷带孙子参加宗教仪式", |
| | | "丈夫被卷入网络诈骗案", |
| | | "妻子被小姑子陷害导致亲家关系破裂", |
| | | "小姑子抢占家庭关键财产", |
| | | "婆婆与儿媳争夺孙子抚养权", |
| | | "丈夫外遇被妻子当场抓包", |
| | | "妻子发现丈夫私藏豪宅钥匙", |
| | | "儿媳为家庭牺牲自我事业", |
| | | "婆婆密谋拆散儿子和媳妇的感情", |
| | | "丈夫背着家人进行赌博", |
| | | "妻子发现小姑子操控家庭微信群", |
| | | "小姑子暗中挑拨离间婆媳关系", |
| | | "婆婆偷偷资助儿子创业失败", |
| | | "丈夫因失业沉默不语", |
| | | "妻子被误认为偷窃家产", |
| | | "儿媳与婆婆为家务事争吵升级", |
| | | "婆婆暗中拿走结婚礼金", |
| | | "丈夫与前妻秘密联络", |
| | | "妻子发现婆婆隐藏健康问题", |
| | | "小姑子利用亲戚关系谋取利益", |
| | | "婆婆强制安排儿子相亲", |
| | | "丈夫深夜接陌生电话被妻子怀疑", |
| | | "妻子被好友背叛情感崩溃", |
| | | "儿媳为孩子教育与婆婆对立", |
| | | "婆婆设计儿媳事业失败", |
| | | "丈夫隐瞒重大病情", |
| | | "妻子发现丈夫秘密贷款", |
| | | "小姑子故意制造家庭矛盾", |
| | | "婆婆背着家人卖掉老宅", |
| | | "丈夫被亲戚陷害名誉受损", |
| | | "妻子遭遇职场性骚扰", |
| | | "儿媳发现婆婆私藏家族秘密", |
| | | "婆婆逼迫儿媳放弃工作", |
| | | "丈夫被妻子发现双重生活", |
| | | "妻子暗中调查丈夫行踪", |
| | | "小姑子设计挤走嫂子生活圈", |
| | | "婆婆秘密操控家庭经济", |
| | | "丈夫意外遗失重要文件", |
| | | "妻子发现婆婆与小姑子合谋", |
| | | "儿媳为家庭牺牲健康", |
| | | "婆婆偷偷联系儿媳前男友", |
| | | "丈夫被迫辞职家庭陷入危机", |
| | | "妻子发现丈夫私藏银行卡", |
| | | "小姑子抢走孙子抚养权", |
| | | "婆婆逼迫儿子购置豪宅", |
| | | "丈夫暗中还债不告诉家人", |
| | | "妻子遭遇网络暴力", |
| | | "儿媳与婆婆冰释前嫌", |
| | | "婆婆要求儿媳生二胎", |
| | | "丈夫与妻子好友暧昧", |
| | | "妻子发现丈夫昔日犯罪记录", |
| | | "小姑子陷害婆婆健康", |
| | | "婆婆患病瞒着家人", |
| | | "丈夫暗中监视妻子手机", |
| | | "妻子怀疑小姑子偷看日记", |
| | | "儿媳为婆婆忍让", |
| | | "婆婆计划搬到儿子家住", |
| | | "丈夫失业妻子撑家", |
| | | "妻子发现丈夫隐藏秘密", |
| | | "小姑子制造家庭风波", |
| | | "婆婆安排儿子相亲", |
| | | "丈夫被诬陷贪污", |
| | | "妻子发现儿子秘密交往小姑子", |
| | | "哥哥突然背叛弟弟,抢夺家族企业控制权", |
| | | "姐姐隐瞒结婚事实,秘密生下孩子", |
| | | "父亲突然宣布要再婚,引发全家反弹", |
| | | "母亲发现儿子隐瞒多年的债务", |
| | | "表弟无意泄露家族秘密,导致亲戚反目", |
| | | "邻居举报家里养宠物扰民,邻里关系紧张", |
| | | "高中同学回乡搅乱旧情,引发三角恋", |
| | | "小叔子私自挪用公款被抓,家庭蒙羞", |
| | | "大姑子偷走妹妹的嫁妆,家族撕裂", |
| | | "堂兄弟因土地纠纷闹到法庭", |
| | | "闺蜜暗地与丈夫私会,友情破裂", |
| | | "外婆偏心孙子,忽视孙女的成长", |
| | | "姨妈误传家丑,亲戚群内群起攻击", |
| | | "表姐突然归国,带来不可告人的秘密", |
| | | "舅舅为了一笔遗产起诉侄子", |
| | | "弟媳被误会与邻居男子暧昧,家庭冷战", |
| | | "堂姐抢了表哥的女朋友,家族不和", |
| | | "爷爷临终前揭露家族隐秘历史", |
| | | "奶奶反对孙子婚事,双方家庭剑拔弩张", |
| | | "好友突然失联,留下神秘遗书", |
| | | "妹妹因职场晋升暗算姐姐", |
| | | "弟弟偷偷在外养小三,妻子崩溃", |
| | | "外公遗产被非法转移,家庭成员大闹", |
| | | "叔叔暗中筹备家庭聚会,却被背叛", |
| | | "邻居陷害家里孩子偷窃,闹上派出所", |
| | | "高中同学会上旧情复燃,引发丈夫嫉妒", |
| | | "大伯被传染病隔离,家庭面临恐慌", |
| | | "表弟欠下巨额赌债,全家被牵连", |
| | | "姑姑干涉儿子婚姻,制造家庭裂痕", |
| | | "闺蜜无意泄露隐私,友情破裂", |
| | | "父亲醉驾被抓,影响家族名声", |
| | | "母亲偷偷拿走女儿结婚礼金", |
| | | "兄弟因遗产分配闹翻,断绝往来", |
| | | "嫂子在家暴风波中选择离开", |
| | | "爷爷的遗愿被继承人篡改", |
| | | "奶奶的偏心引发兄弟姐妹争吵", |
| | | "表姐被前夫纠缠,家人出手相助", |
| | | "舅舅赌博输钱,家里陷入困境", |
| | | "妹妹秘密经营副业,遭遇合伙人背叛", |
| | | "弟弟被老板陷害,面临失业", |
| | | "外公突然失踪,家人四处寻找", |
| | | "叔叔借钱不还,引发家庭纷争", |
| | | "邻居纠缠不休,干扰家人生活", |
| | | "高中同学结婚典礼遭遇冷场", |
| | | "大伯患病隐瞒,家庭成员矛盾加剧", |
| | | "表弟偷拿家中贵重物品被抓", |
| | | "姑姑因嫉妒制造家庭谣言", |
| | | "闺蜜参与传销,家庭陷入危机", |
| | | "父亲被揭发有外遇,家庭濒临破裂", |
| | | "母亲拒绝接受继母,家庭冷战", |
| | | "兄弟为争夺生意合作权互相拆台", |
| | | "嫂子出轨被丈夫发现,闹上媒体", |
| | | "爷爷因财产问题与子女反目成仇", |
| | | "奶奶偏爱孙女,疏远孙子", |
| | | "表姐离婚归来,带着复杂情绪", |
| | | "舅舅卷入诈骗案,家庭蒙羞", |
| | | "妹妹秘密怀孕,选择独自生子", |
| | | "弟弟为朋友担保,陷入财务危机", |
| | | "外公遗嘱公开,意外揭露家族秘密", |
| | | "叔叔私吞公款,被举报", |
| | | "邻居因停车纠纷与家人争执", |
| | | "高中同学聚会爆发激烈争吵", |
| | | "大伯拒绝接受孙媳妇,制造冷场", |
| | | "表弟被捕,家族名誉受损", |
| | | "姑姑插手儿媳教育孩子,引发争端", |
| | | "闺蜜私下和丈夫暧昧,友情终结", |
| | | "父亲身患重病隐瞒妻子", |
| | | "母亲为家庭牺牲健康,精神崩溃", |
| | | "兄弟因家庭财产断绝关系", |
| | | "嫂子隐瞒过去被揭发", |
| | | "爷爷的遗物被人偷偷拿走", |
| | | "奶奶隐瞒家庭秘密多年", |
| | | "表姐突然出现,带来危机", |
| | | "舅舅赌博输光积蓄", |
| | | "妹妹被误会偷窃,遭冷落", |
| | | "弟弟被解雇,家庭陷入困境", |
| | | "外公去世,遗产争夺战爆发", |
| | | "叔叔背着家人贷款买房", |
| | | "邻居举报家人噪音扰民", |
| | | "高中同学之间旧账重提", |
| | | "大伯与弟媳关系紧张", |
| | | "表弟私自卖掉祖产", |
| | | "姑姑不断挑拨离间家庭成员", |
| | | "闺蜜骗走家中财产", |
| | | "父亲被指控职务不当", |
| | | "母亲被儿媳排斥", |
| | | "兄弟创业失败,债务缠身", |
| | | "嫂子失踪引发寻找行动", |
| | | "爷爷遗嘱被篡改", |
| | | "奶奶因偏见与家人决裂", |
| | | "表姐隐瞒婚姻状态", |
| | | "舅舅被控欺诈", |
| | | "妹妹偷偷辞职", |
| | | "弟弟遭遇职场排挤", |
| | | "外公留下神秘信件", |
| | | "叔叔失联数月", |
| | | "邻居与家人爆发肢体冲突", |
| | | "高中同学意外重逢引发纷争" |
| | | ], |
| | | "style": [ |
| | | "像小红书热帖一样,狗血又欲罢不能", |
| | | "像豆瓣日记一样细腻讽刺,层层递进", |
| | | "像情感主播口播剧本,3分钟一个反转", |
| | | "像综艺吐槽大会,语速快、爆点多", |
| | | "像短视频第一人称碎碎念,代入感强", |
| | | "像微博超话爆料贴,带点真实和狗带感", |
| | | "像公众号爆款情感文,温柔中藏利刃", |
| | | "像知乎热帖“我嫁进了一个奇葩家庭”,内容真实又极限拉扯", |
| | | "假装是“当事人匿名投稿”,引发评论狂潮", |
| | | "写得像剧本分镜头,直接可拍短剧", |
| | | "像朋友圈吐槽文,短小精悍直击痛点", |
| | | "像网络论坛情感版,长篇大论层层剖析", |
| | | "像情感脱口秀,幽默又扎心", |
| | | "像都市言情小说,细节丰富感情纠结", |
| | | "像微博小剧场,情绪张扬反转频繁", |
| | | "像知乎问答,理性加情绪混合爆发", |
| | | "像微头条短文,干脆利落又抓人", |
| | | "像快手直播间吐槽,观众互动感强", |
| | | "像微信读书评论区,深度共鸣", |
| | | "像抖音剧情短视频脚本,节奏紧凑反转巧妙", |
| | | "像知乎私信,匿名倾诉带点无奈", |
| | | "像B站弹幕互动,热烈又犀利", |
| | | "像微博故事接龙,层层递进剧情", |
| | | "像小红书真人分享,细节真实代入感强", |
| | | "像微信朋友圈文案,情绪波动明显", |
| | | "像豆瓣影评,情绪冷静但暗藏批判", |
| | | "像直播带货间隙爆料,轻松调侃又抓眼球", |
| | | "像网络小说章节,留悬念", |
| | | "像公众号连载文,环环相扣", |
| | | "像微博问答爆料,悬念不断", |
| | | "像知乎匿名吐槽,情绪直白", |
| | | "像短视频弹幕热门评论合集", |
| | | "像电台情感节目文稿,温柔又犀利", |
| | | "像头条号情感专栏,数据支撑加爆点", |
| | | "像小红书达人感悟,真实又有情绪", |
| | | "像情感微信群长文,层层揭露", |
| | | "像知乎热门回答,观点鲜明且带感", |
| | | "像微博热搜文案,短小精炼冲击强", |
| | | "像朋友圈自嘲段子,幽默中透彻", |
| | | "像喜马拉雅音频剧本,分段对话", |
| | | "像B站UP主自述,情绪饱满", |
| | | "像公众号留言区辩论,观点碰撞", |
| | | "像微博达人爆料,内容丰富细致", |
| | | "像抖音达人讲述,语速快张力强", |
| | | "像知乎情感专栏,分析深入", |
| | | "像短视频第一视角剧情,情感细腻", |
| | | "像网络小说快章节,吸引续看", |
| | | "像微博故事连载,节奏明快", |
| | | "像微信公众号用户投稿,情绪饱满", |
| | | "像知乎冷笑话加情感,风趣又苦涩", |
| | | "像小红书婚姻心情分享,感同身受", |
| | | "像直播间情感互动,观众共鸣", |
| | | "像微博段子手爆料,幽默中带刀", |
| | | "像知乎情感话题热点,理性情绪兼具", |
| | | "像豆瓣读书笔记,情感深刻", |
| | | "像微信公众号爆款标题党文案", |
| | | "像微博超话追星粉丝爆料", |
| | | "像短视频剧情解说,剧情跌宕", |
| | | "像知乎匿名问答,情绪真实", |
| | | "像电台情感访谈稿,温暖真诚", |
| | | "像微博话题讨论,观点多元", |
| | | "像知乎情感故事集,细腻又引发共鸣", |
| | | "像豆瓣影评剧透,情绪渐进", |
| | | "像朋友圈生活随笔,真实又感性", |
| | | "像小红书日常感悟,温暖治愈", |
| | | "像微信公众号深度分析,数据与情感结合", |
| | | "像微博爆料帖,劲爆细节", |
| | | "像抖音情感短剧,节奏紧凑", |
| | | "像知乎匿名情感咨询,细致分析", |
| | | "像直播间情感吐槽,语速快", |
| | | "像小红书短篇故事,情绪浓烈", |
| | | "像微博故事会,反转频繁", |
| | | "像知乎心理学视角,剖析深刻", |
| | | "像微信公众号婚姻情感指南", |
| | | "像微博达人生活揭秘", |
| | | "像抖音爆款短剧脚本", |
| | | "像知乎热点讨论帖", |
| | | "像小红书真情告白", |
| | | "像豆瓣用户日记,感受细腻", |
| | | "像微博情感语录,简洁犀利", |
| | | "像微信公众号情感调研报告", |
| | | "像知乎匿名爆料,真实震撼", |
| | | "像直播间互动问答,幽默犀利", |
| | | "像小红书达人经验分享", |
| | | "像微博热门评论合集", |
| | | "像知乎深度分析文", |
| | | "像微信公众号婚姻困惑集锦", |
| | | "像抖音剧情反转合集", |
| | | "像微博故事类短文", |
| | | "像知乎经典情感案例", |
| | | "像小红书真实感悟", |
| | | "像豆瓣社区吐槽", |
| | | "像微博达人视频解说", |
| | | "像微信公众号生活杂谈", |
| | | "像知乎匿名日记", |
| | | "像直播间粉丝互动文", |
| | | "像小红书情感碎片", |
| | | "像微博热点追踪", |
| | | "像知乎心理学爆料", |
| | | "像微信公众号婚姻教训", |
| | | "像抖音情感讲述", |
| | | "像微博段子手故事", |
| | | "像知乎问答热点", |
| | | "像小红书故事合集", |
| | | "像豆瓣用户吐槽", |
| | | "像微博达人情感分析", |
| | | "像微信公众号情感解读", |
| | | "像知乎情感经验分享", |
| | | "像直播间观众爆料", |
| | | "像小红书真实故事", |
| | | "像微博热点评论", |
| | | "像知乎情感日记", |
| | | "像微信公众号婚姻建议", |
| | | "像抖音故事集锦", |
| | | "像微博故事解说", |
| | | "像知乎情感热门帖子" |
| | | ], |
| | | "level": [ |
| | | "狗血程度拉满,能拍100集家庭伦理剧", |
| | | "每段都要有反转,观众看完只会说:真的假的?", |
| | | "剧情要让人“笑中带骂”,越离谱越真实", |
| | | "前期温情,后期爆炸,结尾反转再反转", |
| | | "每一节都要像朋友圈爆料:不信你能看完不截图", |
| | | "冷静叙述+炸裂剧情,像亲历者默默讲述惊天内幕", |
| | | "既真实又狗血,让人分不清你是在讲故事还是记录命运", |
| | | "抓住“人性的小恶”,让人忍不住转发说“这太像我同事了”", |
| | | "剧情张力十足,能让人一口气看完凌晨三点", |
| | | "细节惊人,反转层出不穷,根本停不下来", |
| | | "充满职场与家庭双线纠葛,层层踩点痛点", |
| | | "各种意想不到的“黑天鹅”事件不断袭来", |
| | | "情绪波动极大,从欢喜到愤怒瞬间切换", |
| | | "故事人物既可恨又可怜,观众情感难以割舍", |
| | | "台词犀利,段段爆炸,引发深度讨论", |
| | | "悬念环环相扣,每个细节都藏玄机", |
| | | "反转力度大到让人怀疑人生", |
| | | "狗血却真实,堪比现实生活浓缩版", |
| | | "虐心剧情与喜剧元素完美融合,笑中带泪", |
| | | "节奏紧凑,情绪起伏像坐过山车", |
| | | "矛盾激烈,冲突火花四溅", |
| | | "带着浓浓的人情味,又狠辣至极", |
| | | "人物刻画细腻,真实感爆棚", |
| | | "剧情切换自然,跌宕起伏不停歇", |
| | | "让人边吐槽边上头,根本停不下来", |
| | | "让人忍不住发朋友圈吐槽和转发", |
| | | "每个角色都有自己的隐秘和故事", |
| | | "冲突升级,仿佛随时能炸裂", |
| | | "每段对话都暗藏伏笔", |
| | | "高能反转接二连三,让人大呼过瘾", |
| | | "细节铺垫严密,剧情发展出人意料", |
| | | "结尾大反转,彻底颠覆之前认知", |
| | | "剧情张力强,抓人眼球不松手", |
| | | "表现人性阴暗面,戳中观众痛点", |
| | | "既残酷又温暖,充满人生百态", |
| | | "剧情跌宕起伏,带来情感高潮", |
| | | "故事内容多线交织,层层递进", |
| | | "精致又刺激,令人无法释卷", |
| | | "口语化表达,增强代入感", |
| | | "剧情生动,仿佛身临其境", |
| | | "反转设计巧妙,令人大开眼界", |
| | | "细节丰富,构建真实感强烈的场景", |
| | | "叙事节奏快,紧抓观众注意力", |
| | | "故事逻辑紧密,环环相扣", |
| | | "剧情充满张力和戏剧性", |
| | | "角色性格立体,冲突真实", |
| | | "紧张刺激,带来情感共鸣", |
| | | "人物动机复杂,情节跌宕", |
| | | "让人欲罢不能,剧情深刻", |
| | | "充满悬念与爆点,反转不断", |
| | | "笑中带泪,触动心灵深处", |
| | | "引发观众共情与反思", |
| | | "让人忍不住刷屏转发", |
| | | "剧情跌宕起伏,抓住观众情绪", |
| | | "情节设计精巧,反转出人意料", |
| | | "令人兴奋且感动,戏剧张力十足", |
| | | "人物冲突激烈,表现真实人性", |
| | | "既狗血又感人,情感充沛", |
| | | "吸引力强,观众停不下来", |
| | | "剧情节奏明快,情绪波动大", |
| | | "细节打磨精致,营造强烈代入感", |
| | | "叙事流畅,情感递进有序", |
| | | "表现多重情感,剧情丰满", |
| | | "层层铺垫,高潮迭起", |
| | | "话题性强,引发热议", |
| | | "让人回味无穷,欲罢不能", |
| | | "反转让人目瞪口呆,剧情跌宕", |
| | | "狗血元素和现实生活完美结合", |
| | | "故事紧凑,环环相扣", |
| | | "情感纠结,矛盾激烈", |
| | | "剧情丰富,细节生动", |
| | | "让人笑中带泪,心情复杂", |
| | | "表现人性弱点,直击痛点", |
| | | "吸引观众深度关注", |
| | | "剧情铺陈细致,层次丰富", |
| | | "情节设置巧妙,反转不断", |
| | | "让人欲罢不能的情感拉扯", |
| | | "狗血程度媲美顶级电视剧", |
| | | "故事充满张力与悬念", |
| | | "刻画细腻,人物丰富", |
| | | "冲突激烈,反转频繁", |
| | | "表现家庭伦理的复杂性", |
| | | "情感真挚,极具感染力", |
| | | "紧凑剧情,抓人眼球", |
| | | "节奏明快,情绪起伏大", |
| | | "构思巧妙,充满惊喜", |
| | | "引发强烈情感共鸣", |
| | | "令人心跳加速的剧情发展", |
| | | "叙事手法多样,层次分明", |
| | | "情感表达真切,动人心弦", |
| | | "反转设计精彩绝伦", |
| | | "剧情细节真实且抓人", |
| | | "充满戏剧张力与情感纠葛", |
| | | "故事内容丰富多彩", |
| | | "令人感同身受,难以忘怀", |
| | | "让人忍不住一看再看", |
| | | "狗血元素与现实冲突交织", |
| | | "情节跌宕起伏,引发讨论", |
| | | "情感刻画深刻,令人共鸣", |
| | | "剧情紧凑,节奏把控精准", |
| | | "人物形象丰满,冲突真实", |
| | | "令人震撼的剧情反转", |
| | | "狗血又真实,令人上瘾", |
| | | "剧情铺垫细腻,结局精彩", |
| | | "情感描写细致,感染力强", |
| | | "让人欲罢不能,连看不舍", |
| | | "冲突激烈,情绪张扬", |
| | | "叙述生动,引发共情" |
| | | ] |
| | | } |
| New file |
| | |
| | | STORY_PROMPT_PARAMETERS_COMPLEX = { |
| | | "主角职业": [ |
| | | "小学老师", |
| | | "外科医生", |
| | | "离婚律师", |
| | | "矫正牙医", |
| | | "高中语文老师", |
| | | "社区保安", |
| | | "投资顾问", |
| | | "救护车司机", |
| | | "影视编剧", |
| | | "医美咨询师", |
| | | "健身教练", |
| | | "某MCN签约主播", |
| | | "心理咨询师", |
| | | "幼儿园园长", |
| | | "地产中介", |
| | | "家政公司老板", |
| | | "网约车司机", |
| | | "电台主持人", |
| | | "职业伴娘", |
| | | "剧本杀主持人", |
| | | "家教名师", |
| | | "高考状元讲师", |
| | | "私人侦探", |
| | | "理财博主", |
| | | "二手车贩", |
| | | "夜场经理", |
| | | "公关公司运营", |
| | | "占星师", |
| | | "房地产开发商千金", |
| | | "自媒体狗血写手", |
| | | "剧情短剧导演", |
| | | "法医", |
| | | "市级公务员", |
| | | "网文写手", |
| | | "动漫配音演员", |
| | | "快递员", |
| | | "安保队长", |
| | | "私立学校老师", |
| | | "裁缝", |
| | | "动物医院实习生", |
| | | "农村妇联主任", |
| | | "婚礼策划师", |
| | | "火锅店合伙人", |
| | | "医院护理部主任", |
| | | "连锁便利店老板", |
| | | "服装厂工人", |
| | | "快餐店打工人", |
| | | "软件测试工程师", |
| | | "前台接待", |
| | | "会计助理", |
| | | "房产主播", |
| | | "情感调解师", |
| | | "网络推理up主", |
| | | "盗墓题材小说作者", |
| | | "私人厨师", |
| | | "男士理发师", |
| | | "儿童早教顾问", |
| | | "留学咨询中介", |
| | | "专职保姆", |
| | | "月嫂", |
| | | "烘焙工作室合伙人", |
| | | "海归创业者", |
| | | "儿科医生", |
| | | "劳动仲裁专员", |
| | | "军人转业干部", |
| | | "精装设计师", |
| | | "宠物摄影师", |
| | | "营销讲师", |
| | | "情趣用品店店长", |
| | | "影视投资人", |
| | | "校园管理员", |
| | | "私营诊所院长", |
| | | "彩礼谈判顾问", |
| | | "中年离婚男自媒体人", |
| | | "某选秀节目的淘汰选手", |
| | | "某知名企业公关", |
| | | "豪车修理技师", |
| | | "网络女主播经纪人", |
| | | "内衣品牌代理商", |
| | | "女子健身房创始人", |
| | | "茶艺师", |
| | | "离异再婚家庭讲师", |
| | | "乡村代课老师", |
| | | "城市改造设计师", |
| | | "小区业委会主任", |
| | | "小型服装连锁老板娘", |
| | | "熟食摊摊主", |
| | | "打假维权律师", |
| | | "高端婚介所创始人", |
| | | "跨境电商卖家", |
| | | "海淘代购达人", |
| | | "离婚协商师", |
| | | "乡村旅游项目发起人", |
| | | "农村快手主播", |
| | | "三胎妈妈博主", |
| | | "情绪管理讲师", |
| | | "狗狗训练师", |
| | | "少年宫老师", |
| | | "社群裂变操盘手", |
| | | "私立学校投资人", |
| | | "资本公司秘书", |
| | | "游戏工作室老板", |
| | | "保健品销售顾问", |
| | | "情侣旅拍摄影师", |
| | | "农村创业青年", |
| | | "脱口秀演员", |
| | | "宫斗小说写手", |
| | | "营养师", |
| | | "高端育儿嫂", |
| | | "骨科主任", |
| | | "珠宝店老板", |
| | | "快手语录博主", |
| | | "本地婚恋红娘", |
| | | "白事主持人", |
| | | "私募基金顾问", |
| | | "社区电商团长", |
| | | "AI换脸视频剪辑师", |
| | | "抖音变装达人", |
| | | "情感修复教练", |
| | | "餐饮连锁品牌COO", |
| | | "街头表演艺人", |
| | | "乡村民宿老板", |
| | | "私立医院营销主任", |
| | | "伪佛系女企业家", |
| | | "离婚次的婚恋导师", |
| | | "高中心理辅导老师", |
| | | "家庭暴力干预社工", |
| | | "教培机构创始人", |
| | | "直播电商选品师", |
| | | "女团退役成员", |
| | | "情侣互撕节目嘉宾", |
| | | "酒店夜班前台", |
| | | "甜品店加盟商", |
| | | "网络追债人员", |
| | | "热点话题小编", |
| | | "二胎奶爸育儿博主", |
| | | "怪谈故事音频主播", |
| | | "报复型消费分析师", |
| | | "咖啡店独立店主", |
| | | "私人订制婚纱设计师", |
| | | "婚外情咨询顾问", |
| | | "离婚冷静期研究者", |
| | | "微信相亲群群主", |
| | | "家庭关系专家", |
| | | "网络暴力受害者讲师", |
| | | "网络PUA揭秘者", |
| | | "中年创业失败者", |
| | | "监狱狱警", |
| | | "监狱服刑归来者", |
| | | "某省台编导", |
| | | "教辅图书编辑", |
| | | "母婴平台内容运营", |
| | | "跨国婚姻服务机构顾问", |
| | | "代写情书写手", |
| | | "高铁列车员", |
| | | "女团练习生母亲", |
| | | "彩虹家庭成员", |
| | | "无业自由人", |
| | | "某寺庙居士", |
| | | "私密日记泄露者", |
| | | "儿童情绪调解志愿者", |
| | | "某村支书之子", |
| | | "债务中介公司运营", |
| | | "大龄未婚男公务员", |
| | | "国企调岗人员", |
| | | "中年离婚再娶对象", |
| | | "相亲平台金牌牵线人", |
| | | "家庭婚姻仲裁调解员", |
| | | "情侣关系危机分析师", |
| | | "长期外派的工程师", |
| | | "公司年会策划人", |
| | | "婆媳调解公司创始人", |
| | | "直播MCN品牌方对接人", |
| | | "短剧IP孵化总监", |
| | | "租房中介门店店长", |
| | | "二手奢侈品回收员", |
| | | "某知名大学食堂员工", |
| | | "异地恋专属写信写手", |
| | | "婚后财产分割顾问", |
| | | "网络婚纱摄影修图师", |
| | | "爱情合约咨询师", |
| | | "婚姻AA制倡导者", |
| | | "中年职场迷失者", |
| | | "离婚冷静期心理研究员", |
| | | "网暴举报志愿者", |
| | | "某县电视台女主持", |
| | | "网恋反诈志愿者", |
| | | "秘密情人培训讲师", |
| | | "情感电台幕后配音", |
| | | "亲子综艺策划人", |
| | | "养生直播间话术主播", |
| | | "情感故事快手男主", |
| | | "吵架王小红书爆款作者", |
| | | "狗血家庭题材短剧剪辑员", |
| | | "“媳妇战队”群主", |
| | | "夫妻财务管理师", |
| | | "同城恋爱脱单教练", |
| | | "前网红现落魄中年男", |
| | | "私奔失败情感复盘师", |
| | | "隐藏身份的豪门继承人" |
| | | ], |
| | | "主角性别": [ |
| | | "男", |
| | | "女", |
| | | "伪装成异性身份", |
| | | "跨性别者", |
| | | "性别模糊(旁人无法判断)", |
| | | "非二元性别", |
| | | "双重人格(两种性别)", |
| | | "灵魂穿越导致性别变化", |
| | | "性别互换(因某种事件或魔法)", |
| | | "原为男性现为女性(变性)", |
| | | "原为女性现为男性(变性)", |
| | | "现实中是男性,虚拟世界是女性", |
| | | "现实中是女性,虚拟世界是男性", |
| | | "夫妻灵魂互换", |
| | | "同性恋男性", |
| | | "同性恋女性", |
| | | "双性恋主角", |
| | | "性别身份隐藏(剧情后期揭晓)", |
| | | "伪装成同性恋以隐瞒真相", |
| | | "因剧情需要假装成另一个性别" |
| | | ], |
| | | "地点": [ |
| | | "婚礼现场", |
| | | "蜜月旅馆", |
| | | "老同学聚会餐厅", |
| | | "KTV 包厢", |
| | | "医院病房", |
| | | "高铁车厢", |
| | | "动车站候车室", |
| | | "飞机经济舱", |
| | | "海边民宿", |
| | | "离婚登记处", |
| | | "民政局门口", |
| | | "宾馆双人床上", |
| | | "家中厨房", |
| | | "家中浴室", |
| | | "新房装修现场", |
| | | "夜市摊位", |
| | | "深夜出租车后座", |
| | | "公司茶水间", |
| | | "单位年会现场", |
| | | "夜店 VIP 包厢", |
| | | "公园长椅", |
| | | "初中教室旧址", |
| | | "学校操场", |
| | | "高中寝室门口", |
| | | "大学图书馆", |
| | | "健身房私教室", |
| | | "私人影院", |
| | | "产房门口", |
| | | "前任婚礼现场", |
| | | "婚礼彩排现场", |
| | | "地下停车场", |
| | | "天台抽烟区", |
| | | "阳台晒衣区", |
| | | "别墅露台", |
| | | "泳池边", |
| | | "情趣酒店", |
| | | "单身公寓", |
| | | "直播间现场", |
| | | "拍戏片场", |
| | | "新闻发布会", |
| | | "车震中的车内", |
| | | "沙发上", |
| | | "地下酒吧", |
| | | "澡堂换衣间", |
| | | "整容医院", |
| | | "律师事务所", |
| | | "警察局接待厅", |
| | | "法院门口", |
| | | "看守所会见室", |
| | | "青旅多人间", |
| | | "失联三年的民宿", |
| | | "高端婚介所", |
| | | "离异群聚会", |
| | | "心理咨询室", |
| | | "墓地", |
| | | "祭祖现场", |
| | | "夜跑的小区小路", |
| | | "公司老板办公室", |
| | | "摄影工作室", |
| | | "情人租住的公寓", |
| | | "刚装修好的婚房", |
| | | "彩礼谈判桌", |
| | | "捉奸现场", |
| | | "厕所门口", |
| | | "录音棚", |
| | | "直播PK现场", |
| | | "饭局后的包房", |
| | | "温泉池中", |
| | | "被偷拍的酒店房", |
| | | "夜市烧烤摊", |
| | | "生育科诊室", |
| | | "婚检中心", |
| | | "打胎诊所", |
| | | "心理治疗室", |
| | | "催眠回忆室", |
| | | "老家祖屋", |
| | | "村口八卦地", |
| | | "麻将桌旁", |
| | | "养生馆", |
| | | "老同学婚礼", |
| | | "同事聚餐后的小巷", |
| | | "隔壁邻居家", |
| | | "前男友的家", |
| | | "闺蜜家沙发上", |
| | | "姐夫家浴缸里", |
| | | "领导家客厅", |
| | | "军训操场", |
| | | "夏令营营地", |
| | | "志愿者活动现场", |
| | | "寺庙祈福处", |
| | | "神婆庙后院", |
| | | "算命摊", |
| | | "婚纱试衣间", |
| | | "剧组化妆间", |
| | | "朋友圈刷到的定位", |
| | | "健身教练宿舍", |
| | | "直播送货途中", |
| | | "婚车上", |
| | | "产检等候区", |
| | | "高考前教室", |
| | | "跨年夜街头", |
| | | "情人节独自咖啡馆", |
| | | "深夜便利店", |
| | | "搬家现场", |
| | | "双十一购物狂欢夜", |
| | | "探亲回老家火车上", |
| | | "农村婚礼大棚", |
| | | "大学宿舍楼下", |
| | | "酒桌角落", |
| | | "情敌家门口", |
| | | "楼道转角", |
| | | "亲戚家的婚礼后台", |
| | | "天桥下", |
| | | "情感电台录音室", |
| | | "年夜饭餐桌", |
| | | "失散亲人团聚现场", |
| | | "离婚冷静期最后一天", |
| | | "婚姻咨询所", |
| | | "扫墓归来路上", |
| | | "露营帐篷", |
| | | "网红探店途中", |
| | | "夜市占卜摊", |
| | | "多年未清空的邮箱", |
| | | "打工地宿舍", |
| | | "失踪少女的房间", |
| | | "恋综拍摄地", |
| | | "民俗村体验屋", |
| | | "出租屋外的电梯里", |
| | | "楼上邻居家", |
| | | "双胞胎错认的床上", |
| | | "假扮情侣的节目组", |
| | | "自驾游车祸现场", |
| | | "救护车上", |
| | | "热搜第一的地铁口", |
| | | "多年好友婚礼抢亲", |
| | | "异地恋分手桥头", |
| | | "外派驻外地出差的公寓", |
| | | "祭祀祖先的火堆边", |
| | | "高原支教地", |
| | | "农村留守儿童家", |
| | | "婚介平台见面地点", |
| | | "海外留学寄宿家庭", |
| | | "文艺青年小书店", |
| | | "诗社聚会场所", |
| | | "打工人办公室厕所", |
| | | "前夫现任婚礼的角落", |
| | | "被偷拍后曝光的摄影棚", |
| | | "楼顶烧烤聚会", |
| | | "小区保安室", |
| | | "凌晨三点的出租屋", |
| | | "援助热线办公室", |
| | | "送外卖途中被撞的路口", |
| | | "考研自习室", |
| | | "社交APP线下见面地", |
| | | "线上脱单直播活动现场", |
| | | "电动车维修点", |
| | | "医院急诊室", |
| | | "酒店走廊", |
| | | "别人的婚房床上", |
| | | "情侣吵架的星巴克", |
| | | "分手纪念日的老地方", |
| | | "异国机场转机地", |
| | | "火车站广场", |
| | | "精神病院探访区", |
| | | "抢孩子现场", |
| | | "孩子家长会", |
| | | "教师办公室", |
| | | "打官司的法庭走廊", |
| | | "直播撕逼的茶馆", |
| | | "卖保险的会客厅", |
| | | "老年相亲角", |
| | | "废弃游乐园", |
| | | "黄昏老街小巷", |
| | | "厕所发现秘密录音笔", |
| | | "幼儿园接送口", |
| | | "孩子亲子鉴定中心", |
| | | "代孕机构", |
| | | "中介公司会议室", |
| | | "小旅馆退房口", |
| | | "古镇旅拍地", |
| | | "请命的村干部办公室", |
| | | "快递堆放的驿站", |
| | | "高考后聚餐饭店", |
| | | "离婚冷静期警示馆", |
| | | "长租公寓", |
| | | "音乐节帐篷区", |
| | | "地铁拥挤车厢", |
| | | "公司出差路上", |
| | | "机场贵宾厅", |
| | | "二胎生育计划讨论地", |
| | | "育儿讲座", |
| | | "看豪宅的售楼处", |
| | | "装修选材市场", |
| | | "老破小房子屋顶", |
| | | "探监的探访区" |
| | | ], |
| | | "前任身份": [ |
| | | "初恋", |
| | | "青梅竹马", |
| | | "大学同学", |
| | | "前夫", |
| | | "前妻", |
| | | "曾经的老板", |
| | | "前室友", |
| | | "高中暗恋对象", |
| | | "前任上司", |
| | | "离婚带娃的前任", |
| | | "军人出身的前任", |
| | | "曾救过她命的人", |
| | | "前男友的兄弟", |
| | | "前女友的闺蜜", |
| | | "婚礼上逃跑的新郎", |
| | | "婚礼上逃跑的新娘", |
| | | "未婚夫(毁约)", |
| | | "曾订婚但未结婚的对象", |
| | | "出国后音讯全无的人", |
| | | "曾经的实习导师", |
| | | "支教时认识的恋人", |
| | | "大厂程序员前任", |
| | | "文艺青年前任", |
| | | "摇滚乐队吉他手", |
| | | "主播前任", |
| | | "网红前任", |
| | | "脱口秀演员", |
| | | "健身教练", |
| | | "咖啡师", |
| | | "纹身师", |
| | | "纹身店老板", |
| | | "摄影师", |
| | | "前任是个有钱的中年人", |
| | | "渣男代表人物", |
| | | "海王", |
| | | "绿茶婊前任", |
| | | "PUA专家", |
| | | "离过三次婚的前任", |
| | | "婚托", |
| | | "高冷医生", |
| | | "温柔的心理咨询师", |
| | | "私教前任", |
| | | "艺考老师", |
| | | "表演系学长", |
| | | "警察前任", |
| | | "检察官前任", |
| | | "舞者", |
| | | "赛车手", |
| | | "飞行员", |
| | | "空姐前任", |
| | | "银行理财顾问", |
| | | "被父母嫌弃的穷小子", |
| | | "富二代前任", |
| | | "海归硕士", |
| | | "海归骗子", |
| | | "外企高管", |
| | | "酒吧驻唱", |
| | | "流浪歌手", |
| | | "追梦失败者", |
| | | "短视频创业者", |
| | | "搞微商的前任", |
| | | "以为是白马王子的人", |
| | | "精神操控大师", |
| | | "异地恋分手的前任", |
| | | "假装单身的已婚男", |
| | | "隐藏子女身份的前任", |
| | | "早恋对象", |
| | | "网恋奔现失败的前任", |
| | | "约炮认识的", |
| | | "在剧组认识的前任", |
| | | "明星助理前任", |
| | | "十八线小演员", |
| | | "恋爱节目上的前任", |
| | | "前男友的女友", |
| | | "前女友的男友", |
| | | "曾出卖主角的人", |
| | | "婚内出轨对象", |
| | | "结婚当天劈腿对象", |
| | | "诈骗犯", |
| | | "前任是负债累累的借贷人", |
| | | "欠赌债跑路的人", |
| | | "父母安排的相亲对象", |
| | | "为了移民而恋爱的人", |
| | | "异国恋失败对象", |
| | | "整容失败后消失的前任", |
| | | "抛弃孩子的前任", |
| | | "孩子的亲生父/母", |
| | | "酒鬼", |
| | | "毒品前科者", |
| | | "从监狱出来的前任", |
| | | "假和尚", |
| | | "伪装穷人的富豪", |
| | | "伪装富人的穷人", |
| | | "为复仇接近主角的人", |
| | | "替身恋人", |
| | | "因为赌约在一起的前任", |
| | | "情人身份的前任", |
| | | "被包养过的人", |
| | | "曾经包养过主角的人", |
| | | "前任是亲戚介绍的", |
| | | "名校高材生", |
| | | "书法家", |
| | | "开茶馆的前任", |
| | | "开理发店的前任", |
| | | "文玩圈的老江湖", |
| | | "主角学生时代的导师", |
| | | "曾经写情书的人", |
| | | "因为学霸而崇拜的前任", |
| | | "被渣后还念念不忘的前任", |
| | | "假装失忆回来的前任", |
| | | "回国继承家产的前任", |
| | | "创业失败跑路的前任", |
| | | "家庭暴力施害者", |
| | | "恋爱脑前任", |
| | | "双重人格者", |
| | | "在寺庙里重遇的前任", |
| | | "曾在ICU探病相识的前任", |
| | | "青少年叛逆期认识的前任", |
| | | "参加志愿活动时认识的", |
| | | "去支教乡村遇到的前任", |
| | | "曾患抑郁症的前任", |
| | | "精神病康复者", |
| | | "心理控制狂", |
| | | "拿主角当实验对象的心理学家", |
| | | "写小说取材的前任", |
| | | "偷拍主角的跟踪狂", |
| | | "曾绑架过主角的前任", |
| | | "试图合谋复仇的人", |
| | | "主角救命恩人的后代", |
| | | "主角曾抛弃过的人", |
| | | "替兄/姐追求主角的人", |
| | | "主角原本要领养的孩子的父亲", |
| | | "曾经的舞伴", |
| | | "曾经的合租室友", |
| | | "共用一个邮箱认识的", |
| | | "笔友前任", |
| | | "匿名论坛网友", |
| | | "租房被坑后认识的房东", |
| | | "隔壁邻居", |
| | | "房产纠纷对手", |
| | | "打官司结识的前任", |
| | | "前任是律师", |
| | | "曾为主角顶罪的人", |
| | | "诈骗合伙人变恋人", |
| | | "主角的心理医生", |
| | | "主角的弟弟/姐姐的好友", |
| | | "同性前任", |
| | | "变性前任", |
| | | "主角曾伤害过的前任", |
| | | "出国后再回来的人", |
| | | "高中老师的儿子", |
| | | "艺术展邂逅的前任", |
| | | "买画被骗时认识的前任", |
| | | "共同抚养宠物而认识", |
| | | "曾经网络吵架对象", |
| | | "群聊相识的前任", |
| | | "误发红包后结识的前任", |
| | | "共享充电宝认识的前任", |
| | | "打错电话结识的前任", |
| | | "车祸相遇的前任", |
| | | "失忆期间结识的前任", |
| | | "被误认为亲戚认识的前任", |
| | | "在医院同床过的病友", |
| | | "做实验误入其实验室的前任", |
| | | "体检时遇到的前任", |
| | | "招聘时面试官变恋人", |
| | | "大学导师的子女", |
| | | "文艺汇演搭档", |
| | | "支教期间被误会是夫妻", |
| | | "地铁偶遇百次的前任", |
| | | "误拿快递结识的前任", |
| | | "匿名信来往的前任", |
| | | "通过 AI 生成的前任", |
| | | "通过元宇宙相识的前任", |
| | | "程序中的虚拟角色恋人", |
| | | "因宠物医院结识的前任", |
| | | "在婚介所注册后重逢", |
| | | "失恋酒吧撞见的旧爱", |
| | | "早年被迫分手的前任", |
| | | "因车祸丧失记忆的旧爱", |
| | | "曾经的保镖", |
| | | "曾被主角救过的落魄人", |
| | | "一起穿越过来的恋人", |
| | | "平行时空回来的旧爱" |
| | | ], |
| | | "现状描述": [ |
| | | "失业三个月,事业跌入谷底", |
| | | "刚升职为部门经理,内心空虚却光鲜亮丽", |
| | | "隐婚三年,孩子已满两岁", |
| | | "即将结婚,却发现自己爱上了伴娘", |
| | | "在国外生活八年,刚刚回国探亲", |
| | | "老公出轨,却不敢离婚", |
| | | "失忆后重新遇见前任,记忆逐渐恢复", |
| | | "当了五年全职妈妈,决定重返职场", |
| | | "刚刚坐完牢,想重新做人", |
| | | "欠下高利贷,每天被催债电话轰炸", |
| | | "父母重病,自己无力承担医药费", |
| | | "假结婚骗绿卡,假戏真做动了心", |
| | | "装穷试探爱人,反被揭穿真实身份", |
| | | "二婚刚满一年,现任竟是前任兄弟", |
| | | "一夜暴富,亲戚开始上门借钱", |
| | | "流落街头,偶遇当年初恋", |
| | | "事业有成,感情一片空白", |
| | | "悄悄查出怀孕,还没告诉对方", |
| | | "住进豪门,却要装穷三年", |
| | | "家中突发火灾,一无所有", |
| | | "刚拿到离婚协议,却发现前夫车祸", |
| | | "婚礼当天,新娘突然消失", |
| | | "遭遇网络暴力,选择离开社交平台", |
| | | "刚辞职创业,合作方跑路", |
| | | "当红女星,卷入丑闻", |
| | | "孤儿出身,突然被豪门认亲", |
| | | "孩子失踪,警方怀疑是自己干的", |
| | | "父亲去世,留下债务无数", |
| | | "被家族驱逐,一无所有开始打拼", |
| | | "公司破产,拖欠员工工资", |
| | | "假装情侣骗房东,却越陷越深", |
| | | "刚整完容,被前任认出", |
| | | "大学肄业,父母一直以为毕业了", |
| | | "网恋被骗,被骗财也被骗心", |
| | | "被闺蜜抢男友,还被反咬一口", |
| | | "车祸醒来,发现穿越回十年前", |
| | | "投资失败,卖掉房子搬回老家", |
| | | "酒后失控,醒来发现怀孕", |
| | | "未婚先孕,男方消失不见", |
| | | "快递员工作中,送货送到前任家", |
| | | "直播爆火,现实却一地鸡毛", |
| | | "得了绝症,选择不告诉家人", |
| | | "抑郁症恢复中,面临新感情挑战", |
| | | "身份被冒用,欠下一屁股债", |
| | | "被公司开除,还被上司拉黑", |
| | | "连续加班猝倒,医生建议立即休养", |
| | | "父母逼婚,自己却暗恋同事", |
| | | "财产被冻结,全家只能靠老婆养", |
| | | "谎称高学历,即将被公司查验", |
| | | "曾是小三,如今被人插足", |
| | | "弟弟入狱,全家名声扫地", |
| | | "孩子不是亲生的,但自己还爱着他", |
| | | "寄人篱下,每天都要小心翼翼", |
| | | "婚姻失败,独自带娃打拼", |
| | | "自学考研,却不敢告诉家人", |
| | | "打多份工,维持基本生活", |
| | | "曾是黑帮成员,如今想做善事", |
| | | "给人做保姆,却与男主人有情愫", |
| | | "刚得知身世之谜,怀疑全家人都在骗我", |
| | | "为弟弟顶罪,出狱后发现一切变了", |
| | | "因病不能生育,丈夫却渴望孩子", |
| | | "新婚三天,婆婆提出试婚期", |
| | | "被渣男骗走所有积蓄,还要自己还信用卡", |
| | | "精英生活背后,藏着赌博成瘾", |
| | | "单亲妈妈,每天演双面人生", |
| | | "在富人家当司机,却被少奶奶勾引", |
| | | "因救人瘫痪,反被人家告上法庭", |
| | | "妹妹顶替自己上大学,如今成了风云人物", |
| | | "女强人身份,却无一人知晓她失眠抑郁", |
| | | "孩子得重病,需百万手术费", |
| | | "公司裁员,老板却想潜规则我", |
| | | "捐精时留下的孩子找上门来", |
| | | "丢失孩子多年,某天路上偶遇", |
| | | "辞职开餐厅,第一天就遭投诉", |
| | | "为救母亲借高利贷,如今被逼债", |
| | | "换肾手术成功,却爱上了供体家属", |
| | | "前任回国,突然住进我隔壁", |
| | | "独自旅行,却在异国被通缉", |
| | | "生活拮据,靠打零工养家", |
| | | "情绪失控,刚刚和老公大吵一架", |
| | | "刚搬新家,邻居是前任的朋友", |
| | | "酒精依赖,害怕被丈夫发现", |
| | | "失去工作后,开始赌博逃避现实", |
| | | "家庭暴力受害者,暗中寻求帮助", |
| | | "大学辍学,成为网红直播主", |
| | | "靠网贷维持生活,深陷债务危机", |
| | | "被丈夫冷落,暗中怀疑他有外遇", |
| | | "被公司裁员,和老公感情渐行渐远", |
| | | "新晋网红,风光背后隐藏秘密", |
| | | "刚刚离婚,独自抚养两个孩子", |
| | | "刚从戒毒所出来,想重回正轨", |
| | | "患有慢性病,经济压力巨大", |
| | | "生意失败,欠下一屁股债务", |
| | | "被迫放弃事业,成为全职主妇", |
| | | "暗恋同事多年,始终没勇气表白", |
| | | "婚姻危机,面临第三者介入", |
| | | "家庭关系紧张,父母强烈反对婚姻", |
| | | "老公出轨,秘密调查对方情史", |
| | | "刚刚晋升,面临职场排挤", |
| | | "失去父母,独自承担家庭责任", |
| | | "陷入网恋骗局,身心受创", |
| | | "被朋友背叛,财产损失惨重", |
| | | "意外怀孕,面临巨大压力", |
| | | "怀疑丈夫隐藏秘密,私下调查", |
| | | "被父母逼婚,心中另有深爱", |
| | | "感情纠葛复杂,三角关系纠缠不清", |
| | | "被公司性骚扰,苦于无处申诉", |
| | | "多次创业失败,负债累累", |
| | | "遭遇车祸,失忆多年", |
| | | "精神状态不佳,频繁发作抑郁", |
| | | "失去工作,面临家庭破裂", |
| | | "深爱的丈夫突然失踪", |
| | | "被怀疑与同事有染,陷入困境", |
| | | "刚刚产后抑郁,情绪不稳", |
| | | "父母双亡,照顾弟弟妹妹", |
| | | "被丈夫家暴,秘密逃离", |
| | | "刚刚戒赌成功,重新做人", |
| | | "遭遇网络欺凌,生活陷入阴影", |
| | | "身患绝症,选择隐瞒真相", |
| | | "被好友抢走男友,心碎难忍", |
| | | "为了孩子放弃梦想,生活平淡", |
| | | "家庭矛盾激烈,兄弟反目成仇", |
| | | "欠下巨额债务,陷入黑社会纠纷", |
| | | "隐藏过去秘密,害怕被揭穿", |
| | | "经历车祸昏迷,醒来已是五年后", |
| | | "丈夫突然变心,另结新欢", |
| | | "创业失败,妻子承担所有债务", |
| | | "孩子患病,夫妻为医药费争吵不断", |
| | | "婆媳关系紧张,家庭不和谐", |
| | | "被小三骚扰,家庭破裂边缘", |
| | | "单亲家庭长大,渴望真爱", |
| | | "工作压力大,婚姻出现裂痕", |
| | | "暗恋对象已婚,无法自拔", |
| | | "被骗财骗色,情感受创", |
| | | "事业有成,但婚姻空虚", |
| | | "为情所困,失去自我", |
| | | "刚刚怀孕,发现丈夫出轨", |
| | | "被闺蜜背叛,友情破裂", |
| | | "因误会与丈夫分居", |
| | | "刚刚出狱,寻求家庭原谅", |
| | | "孩子被绑架,家庭陷入恐慌", |
| | | "丈夫失业,家庭经济陷困境", |
| | | "婆婆介入婚姻,夫妻矛盾激化", |
| | | "被误认为小三,社会压力巨大", |
| | | "偷偷攒钱准备离婚", |
| | | "丈夫赌博成瘾,家庭破裂", |
| | | "遭遇车祸失忆,家庭生变", |
| | | "女儿留学遇险,夫妻分歧加剧", |
| | | "自己出轨,陷入道德挣扎", |
| | | "丧失生育能力,夫妻关系紧张", |
| | | "独自抚养患病丈夫", |
| | | "丈夫海外工作,婚姻异地", |
| | | "家族企业继承纠纷", |
| | | "被指责抛弃家庭", |
| | | "隐藏多年的秘密被揭开", |
| | | "家庭聚会变成大战", |
| | | "邻居举报家庭矛盾", |
| | | "网络直播曝光私生活", |
| | | "发现丈夫隐瞒债务", |
| | | "孩子成绩优异,家庭期望高", |
| | | "面临退休危机", |
| | | "收到匿名恐吓信", |
| | | "丈夫被捕,家庭声誉受损", |
| | | "亲友背叛,孤立无援", |
| | | "独立自主,拒绝家庭束缚", |
| | | "面临财产分割诉讼", |
| | | "前任突然出现,搅乱生活", |
| | | "陷入赌博纠纷", |
| | | "家庭成员患重病", |
| | | "面临房产被查封", |
| | | "家中突然出现陌生人", |
| | | "妻子怀疑丈夫有外遇", |
| | | "丈夫生意失败,负债累累", |
| | | "女儿婚事被反对", |
| | | "父母催婚压力大", |
| | | "新房装修遭遇纠纷", |
| | | "家中突然断水断电", |
| | | "孩子叛逆期,家庭紧张", |
| | | "夫妻感情淡漠,形同陌路", |
| | | "遭遇诈骗团伙", |
| | | "婚姻面临第三者挑战", |
| | | "丧失工作技能,难以谋生", |
| | | "家庭成员涉毒被捕", |
| | | "面临孩子抚养权争夺", |
| | | "家庭内部资源争夺激烈", |
| | | "丧失信任,夫妻分居", |
| | | "面对婆媳战争" |
| | | ], |
| | | "初始事件": [ |
| | | "偶遇高中同学会", |
| | | "发现丈夫手机有暧昧信息", |
| | | "无意中听到婆婆和姐妹的秘密对话", |
| | | "丈夫突然提出离婚", |
| | | "被前任意外找上门", |
| | | "闺蜜背后捅刀子", |
| | | "婆婆突然送来一堆礼物", |
| | | "孩子在学校被欺负", |
| | | "发现家里账目不对劲", |
| | | "丈夫夜不归宿", |
| | | "闺蜜结婚邀请我出席", |
| | | "被同事设计陷害", |
| | | "无意间看到丈夫和前任聊天记录", |
| | | "突然收到匿名威胁信", |
| | | "婆婆在背后说我坏话", |
| | | "丈夫送来一张陌生女人的照片", |
| | | "孩子成绩突然下滑", |
| | | "前任成为邻居", |
| | | "丈夫电话里隐瞒行踪", |
| | | "公司裁员风波波及我", |
| | | "闺蜜和丈夫有暧昧关系", |
| | | "突然被告知家产被转移", |
| | | "婆婆突发重病", |
| | | "发现丈夫开销神秘", |
| | | "闺蜜邀我去参加秘密聚会", |
| | | "孩子被老师投诉", |
| | | "丈夫夜晚消失几个小时", |
| | | "无意看到丈夫的隐藏社交账号", |
| | | "前任对我发起社交攻击", |
| | | "婆婆私自干涉家务安排", |
| | | "发现丈夫手机藏有照片", |
| | | "孩子意外闯入父母争吵现场", |
| | | "闺蜜突然搬到我家附近", |
| | | "丈夫和前妻联系频繁", |
| | | "家里收到匿名包裹", |
| | | "婆婆私下安排相亲", |
| | | "公司内部有人针对我", |
| | | "丈夫出轨证据曝光", |
| | | "孩子参加比赛失利", |
| | | "闺蜜背叛情感告白", |
| | | "丈夫突然辞职", |
| | | "婆婆暗中联系我闺蜜", |
| | | "发现丈夫双重身份", |
| | | "孩子突然说话异常", |
| | | "前任参加家庭聚会", |
| | | "闺蜜提出借钱不还", |
| | | "丈夫夜晚接电话神秘", |
| | | "婆婆与邻居合谋排挤我", |
| | | "发现孩子不属于自己", |
| | | "丈夫突然拒绝性生活", |
| | | "闺蜜揭露我的秘密", |
| | | "婆婆指责我的育儿方式", |
| | | "丈夫给我设置了监控", |
| | | "孩子成绩单被篡改", |
| | | "闺蜜背后传我坏话", |
| | | "丈夫带陌生女人回家", |
| | | "婆婆对我言语冷淡", |
| | | "孩子卷入校园风波", |
| | | "丈夫突然远赴外地", |
| | | "闺蜜邀请我参加派对", |
| | | "婆婆突然搬进我家", |
| | | "发现丈夫账户异常消费", |
| | | "孩子患上重病", |
| | | "闺蜜和我争夺同一个男人", |
| | | "丈夫与前任在外见面", |
| | | "婆婆限制我与家人联系", |
| | | "孩子意外遭遇事故", |
| | | "闺蜜和丈夫秘密通信", |
| | | "丈夫酒后失态伤害我", |
| | | "婆婆指控我家庭暴力", |
| | | "孩子被校方处分", |
| | | "闺蜜劝我离婚", |
| | | "丈夫突然隐瞒重大秘密", |
| | | "婆婆安排我参加相亲活动", |
| | | "孩子学习压力过大", |
| | | "闺蜜替我出气与丈夫争吵", |
| | | "丈夫为另一女人买房", |
| | | "婆婆干涉我工作", |
| | | "孩子说出不该说的话", |
| | | "闺蜜提出搬来同住", |
| | | "丈夫拒绝回家", |
| | | "婆婆挑拨离间", |
| | | "孩子在外面打架", |
| | | "闺蜜背后与我丈夫联手", |
| | | "丈夫拒绝与我沟通", |
| | | "婆婆向亲戚透露我隐私", |
| | | "孩子被误诊", |
| | | "闺蜜在朋友圈抹黑我", |
| | | "丈夫私藏银行卡", |
| | | "婆婆暗示我不适合做母亲", |
| | | "孩子参加兴趣班被退学", |
| | | "闺蜜发微信给前任", |
| | | "丈夫参与非法交易", |
| | | "婆婆偷偷修改遗嘱", |
| | | "孩子早恋被发现", |
| | | "闺蜜带陌生男人回家", |
| | | "丈夫辞职转行不告知", |
| | | "婆婆诋毁我的家庭背景", |
| | | "孩子意外丢失手机", |
| | | "闺蜜误会我背叛她", |
| | | "丈夫隐瞒外遇", |
| | | "婆婆威胁要断绝关系", |
| | | "孩子成绩单被公开", |
| | | "闺蜜突然提出分手", |
| | | "丈夫带病上班", |
| | | "婆婆暗中监视我", |
| | | "孩子被同学排挤", |
| | | "闺蜜制造假证据陷害我", |
| | | "丈夫突然搬走", |
| | | "婆婆在亲戚面前贬低我", |
| | | "孩子患上心理疾病", |
| | | "闺蜜和丈夫秘密约会", |
| | | "丈夫突然提出买房", |
| | | "婆婆拒绝和我沟通", |
| | | "孩子偷偷吸烟", |
| | | "闺蜜借钱不还", |
| | | "丈夫夜里神秘出门", |
| | | "婆婆暗示我离婚更好", |
| | | "孩子被老师投诉欺凌", |
| | | "闺蜜告诉丈夫我的秘密", |
| | | "丈夫因病休假", |
| | | "婆婆找借口不让我带孩子", |
| | | "孩子拒绝上学", |
| | | "闺蜜威胁我退出朋友圈", |
| | | "丈夫未告知重要决定", |
| | | "婆婆偷偷联系前任", |
| | | "孩子被父母责骂", |
| | | "闺蜜和丈夫打架", |
| | | "丈夫丢失重要文件", |
| | | "婆婆在家里制造矛盾", |
| | | "孩子交了不良朋友", |
| | | "闺蜜故意忽视我", |
| | | "丈夫带女同事回家", |
| | | "婆婆偷偷拆散我和朋友", |
| | | "孩子被老师误解", |
| | | "闺蜜抢走我的工作机会", |
| | | "丈夫夜班加班失联", |
| | | "婆婆指责我的教育方法", |
| | | "孩子成绩被老师公开批评", |
| | | "闺蜜向丈夫举报我", |
| | | "丈夫偷偷欠债", |
| | | "婆婆不让孩子和我亲近", |
| | | "孩子说谎被揭穿", |
| | | "闺蜜带人骚扰我", |
| | | "丈夫失业在家", |
| | | "婆婆突然改变态度", |
| | | "孩子在家制造矛盾", |
| | | "闺蜜被我揭穿谎言", |
| | | "丈夫承认出轨", |
| | | "婆婆要求我搬出家门", |
| | | "孩子在外面受伤", |
| | | "闺蜜告诉我丈夫的秘密", |
| | | "丈夫临时改变计划", |
| | | "婆婆突然送我礼物", |
| | | "孩子参加比赛获奖", |
| | | "闺蜜对我冷淡", |
| | | "丈夫在外留宿朋友家", |
| | | "婆婆限制我见孩子", |
| | | "孩子忽然生病", |
| | | "闺蜜带我参加聚会", |
| | | "丈夫拒绝参加家庭聚会", |
| | | "婆婆私下联系我的父母", |
| | | "孩子与我闹别扭", |
| | | "闺蜜告诉我丈夫的外遇", |
| | | "丈夫因故意隐瞒被揭穿", |
| | | "婆婆和我冷战", |
| | | "孩子想离家出走", |
| | | "闺蜜给我出难题", |
| | | "丈夫工作调动临时搬家", |
| | | "婆婆和邻居传闲话", |
| | | "孩子成绩下滑家长会受批", |
| | | "闺蜜邀请我旅行", |
| | | "丈夫无故生气冷战", |
| | | "婆婆不让孩子说我坏话", |
| | | "孩子忽然迷上网络游戏", |
| | | "闺蜜劝我放弃丈夫", |
| | | "丈夫改变手机密码", |
| | | "婆婆逼我放弃工作", |
| | | "孩子被误诊引发家长会", |
| | | "闺蜜曝光我隐私", |
| | | "丈夫被领导批评", |
| | | "婆婆偷看我手机", |
| | | "孩子被老师点名批评", |
| | | "闺蜜当众羞辱我", |
| | | "丈夫拒绝带孩子出门", |
| | | "婆婆和我冷淡相处", |
| | | "孩子在家闹情绪", |
| | | "闺蜜和我争夺家庭资源", |
| | | "丈夫忽然消失数日", |
| | | "婆婆带孩子离家出走", |
| | | "孩子学习压力大", |
| | | "闺蜜为难我", |
| | | "丈夫隐瞒家庭债务", |
| | | "婆婆破坏我的计划", |
| | | "孩子被同学孤立", |
| | | "闺蜜透露我家庭秘密", |
| | | "丈夫夜晚神秘聚会", |
| | | "婆婆说我不孝", |
| | | "孩子有暴力倾向", |
| | | "闺蜜制造矛盾", |
| | | "丈夫与朋友反目", |
| | | "婆婆拒绝帮忙", |
| | | "孩子考试作弊被抓", |
| | | "闺蜜抢走我的男友" |
| | | ], |
| | | "冲突描述": [ |
| | | "丈夫发现我和前任联系,大发雷霆", |
| | | "婆婆公开指责我不孝顺,家庭气氛紧张", |
| | | "闺蜜背后捅刀,挑拨离间导致夫妻争吵", |
| | | "孩子被校方误解,家长会上爆发激烈争执", |
| | | "丈夫偷偷检查我的手机,引发信任危机", |
| | | "婆婆私下散播我的隐私,邻里议论纷纷", |
| | | "前任突然出现,挑起旧情纠纷", |
| | | "闺蜜和丈夫的暧昧被我发现,关系破裂", |
| | | "孩子与父亲争吵后躲进房间拒绝说话", |
| | | "丈夫因工作压力大,对我态度冷淡", |
| | | "婆婆干涉家庭决策,导致矛盾升级", |
| | | "闺蜜暗中抢走我朋友的好感,关系紧张", |
| | | "丈夫与前妻秘密会面,欺骗我多时", |
| | | "孩子学习成绩下降,父母争吵激烈", |
| | | "婆婆与我为孩子教育问题争执不断", |
| | | "丈夫酒后失态,言语伤害我", |
| | | "闺蜜在朋友圈公开嘲笑我,激起冲突", |
| | | "孩子犯错被老师罚站,家长会上吵翻天", |
| | | "丈夫因误会怀疑我出轨,闹得不可开交", |
| | | "婆婆逼迫我放弃工作,引发激烈争执", |
| | | "前任在家门口吵闹,邻居围观场面尴尬", |
| | | "闺蜜趁我不在家偷走重要物品", |
| | | "丈夫与同事关系暧昧,被我当场撞见", |
| | | "孩子不听话,与父母大声争吵", |
| | | "婆婆辱骂我出身低微,家庭气氛冰冷", |
| | | "闺蜜向丈夫泼脏水,试图破坏婚姻", |
| | | "丈夫拒绝承担家务,家里矛盾升级", |
| | | "孩子被学校开除,父母争论激烈", |
| | | "婆婆无故挑拨我和丈夫的关系", |
| | | "前任打电话骚扰,丈夫大怒", |
| | | "闺蜜背叛我,带走我重要客户", |
| | | "丈夫忽略家庭责任,引发婆媳不满", |
| | | "孩子叛逆期爆发,家庭陷入混乱", |
| | | "婆婆私自带孩子出门,未告知我", |
| | | "闺蜜当众揭我的短,引发尴尬", |
| | | "丈夫与朋友起争执,我被牵连其中", |
| | | "孩子撒谎被揭穿,夫妻责备升级", |
| | | "婆婆阻挠我带孩子参加活动", |
| | | "前任公开羞辱我,丈夫无动于衷", |
| | | "闺蜜散布假消息,损害我的名誉", |
| | | "丈夫忘记重要纪念日,婆婆冷嘲热讽", |
| | | "孩子在外打架,被校方通知家长", |
| | | "婆婆私自做主,改变孩子教育计划", |
| | | "闺蜜抢走我心仪的工作岗位", |
| | | "丈夫拒绝和我沟通,关系恶化", |
| | | "孩子沉迷游戏,父母意见不合", |
| | | "婆婆对我冷眼相待,家庭气氛紧张", |
| | | "前任频频骚扰,扰乱我生活", |
| | | "闺蜜与我争吵,关系破裂", |
| | | "丈夫出轨被发现,激烈冲突爆发", |
| | | "孩子成绩被老师点名批评,父母争吵", |
| | | "婆婆嘲笑我的穿着打扮,激起不满", |
| | | "闺蜜背后散布我的秘密", |
| | | "丈夫因工作压力大发脾气", |
| | | "孩子不满家庭管教,与父母争吵", |
| | | "婆婆坚持传统观念,和我理念冲突", |
| | | "前任在社交媒体挑衅,丈夫愤怒", |
| | | "闺蜜带来陌生男人,引发争吵", |
| | | "丈夫忽视家庭,导致妻子情绪崩溃", |
| | | "孩子逃学被老师找上门", |
| | | "婆婆挑拨夫妻感情,制造矛盾", |
| | | "闺蜜在聚会上羞辱我", |
| | | "丈夫冷战数日,家中气氛僵硬", |
| | | "孩子叛逆与父母顶嘴", |
| | | "婆婆干涉家务分配,矛盾激化", |
| | | "前任私下联络,撬动感情裂缝", |
| | | "闺蜜嘲笑我的梦想,激起争吵", |
| | | "丈夫对我冷漠疏远", |
| | | "孩子被同学欺负,父母意见不合", |
| | | "婆婆对我的育儿方式指手画脚", |
| | | "闺蜜破坏我和丈夫的约会", |
| | | "丈夫对我撒谎被揭穿", |
| | | "孩子考试失利,夫妻互相指责", |
| | | "婆婆限制我与孩子接触", |
| | | "前任再次出现,挑拨夫妻感情", |
| | | "闺蜜私下和丈夫联系", |
| | | "丈夫隐瞒重大秘密,被我发现", |
| | | "孩子不愿回家,家庭矛盾加剧", |
| | | "婆婆强迫我参加家族聚会", |
| | | "闺蜜公开讽刺我失败的婚姻", |
| | | "丈夫酗酒闹事,妻子忍无可忍", |
| | | "孩子被老师批评后反抗父母", |
| | | "婆婆私自安排孩子的未来", |
| | | "前任威胁揭露过去秘密", |
| | | "闺蜜在朋友圈公开我的隐私", |
| | | "丈夫拒绝参加家庭活动", |
| | | "孩子沉迷手机,父母争吵不断", |
| | | "婆婆和我在家中争夺权力", |
| | | "闺蜜揭露我和丈夫的矛盾", |
| | | "丈夫冷落我,感情渐行渐远", |
| | | "孩子在外被同学孤立", |
| | | "婆婆对我冷言冷语", |
| | | "前任参加家庭聚会,气氛尴尬", |
| | | "闺蜜挑拨我和丈夫的关系", |
| | | "丈夫和前任有秘密联系", |
| | | "孩子出现行为问题,父母争吵", |
| | | "婆婆阻止我带孩子外出", |
| | | "闺蜜抢走我的资源和机会", |
| | | "丈夫拒绝与我沟通", |
| | | "孩子成绩下滑引发家庭争执", |
| | | "婆婆对我有偏见,家中气氛紧张", |
| | | "前任频繁联系,挑拨家庭矛盾", |
| | | "闺蜜故意忽视我", |
| | | "丈夫对我说谎,信任破裂", |
| | | "孩子叛逆期,家庭不和", |
| | | "婆婆对我不满,常制造矛盾", |
| | | "闺蜜背后说我的坏话", |
| | | "丈夫隐瞒家中财务问题", |
| | | "孩子被老师点名批评", |
| | | "婆婆不认可我的教育方式", |
| | | "前任在朋友圈炫耀新生活", |
| | | "闺蜜带陌生人来家里", |
| | | "丈夫夜不归宿,被我质问", |
| | | "孩子对我冷漠疏远", |
| | | "婆婆不断挑剔我的缺点", |
| | | "闺蜜和丈夫产生误会", |
| | | "丈夫因工作压力大发脾气", |
| | | "孩子逃课被校方惩罚", |
| | | "婆婆私下对我进行嘲讽", |
| | | "前任威胁要破坏我的家庭", |
| | | "闺蜜挑起家庭争吵", |
| | | "丈夫拒绝承担家务", |
| | | "孩子在学校被欺负", |
| | | "婆婆和我意见相左,争吵不休", |
| | | "闺蜜和丈夫有秘密联系", |
| | | "丈夫忽略家庭,冷落妻子", |
| | | "孩子沉迷游戏,父母争执", |
| | | "婆婆经常无理取闹", |
| | | "前任突然出现,挑起家庭矛盾", |
| | | "闺蜜嘲笑我生活困境", |
| | | "丈夫工作忙碌忽略家庭", |
| | | "孩子对我充满敌意", |
| | | "婆婆对我指责不断", |
| | | "闺蜜背叛我信任", |
| | | "丈夫出轨被发现", |
| | | "孩子考试失利,家庭紧张", |
| | | "婆婆对我冷漠无情", |
| | | "前任频繁骚扰", |
| | | "闺蜜在背后陷害我", |
| | | "丈夫对我撒谎", |
| | | "孩子逃学家中闹剧", |
| | | "婆婆制造家庭不和", |
| | | "闺蜜夺走我心爱的人", |
| | | "丈夫拒绝沟通", |
| | | "孩子表现异常", |
| | | "婆婆对我态度恶劣", |
| | | "前任带来麻烦", |
| | | "闺蜜嘲讽我失败", |
| | | "丈夫忽视家庭", |
| | | "孩子反抗父母", |
| | | "婆婆制造矛盾", |
| | | "闺蜜挑拨离间", |
| | | "丈夫冷战无视", |
| | | "孩子厌学逃家", |
| | | "婆婆诋毁我名誉", |
| | | "前任挑拨夫妻感情", |
| | | "闺蜜背后说坏话", |
| | | "丈夫隐瞒事实", |
| | | "孩子遭遇校园欺凌", |
| | | "婆婆强迫我让步", |
| | | "闺蜜夺走资源", |
| | | "丈夫忽略妻子", |
| | | "孩子情绪失控", |
| | | "婆婆挑起争吵", |
| | | "前任试图复合", |
| | | "闺蜜制造误会", |
| | | "丈夫出轨被揭", |
| | | "孩子成绩下降", |
| | | "婆婆指责我", |
| | | "闺蜜背叛友情", |
| | | "丈夫冷漠相待", |
| | | "孩子逃课", |
| | | "婆婆与我争执", |
| | | "前任频繁出现", |
| | | "闺蜜破坏婚姻", |
| | | "丈夫说谎", |
| | | "孩子行为异常", |
| | | "婆婆挑拨夫妻", |
| | | "闺蜜嘲笑我", |
| | | "丈夫忽视家庭", |
| | | "孩子叛逆", |
| | | "婆婆冷淡我" |
| | | ], |
| | | "狗血要素": [ |
| | | "误会引发的家庭纷争", |
| | | "前任突然出现搅局", |
| | | "秘密的双重生活曝光", |
| | | "婆媳间的无休止争吵", |
| | | "闺蜜背叛引发信任危机", |
| | | "丈夫出轨隐藏多年", |
| | | "孩子被误诊引发家庭风波", |
| | | "遗产争夺战暗潮涌动", |
| | | "意外怀孕引发三角关系", |
| | | "深夜神秘电话牵出秘密", |
| | | "误会导致亲人反目成仇", |
| | | "隐藏的过去被挖掘出来", |
| | | "突如其来的家庭变故", |
| | | "秘密孩子身份曝光", |
| | | "假离婚真复合的戏码", |
| | | "闺蜜抢走心爱男人", |
| | | "丈夫事业失败家庭矛盾爆发", |
| | | "婆婆暗中拆散夫妻感情", |
| | | "孩子陷入校园欺凌", |
| | | "被误会偷情引发风波", |
| | | "前任成邻居引发摩擦", |
| | | "隐藏的财产秘密被揭开", |
| | | "误会导致好友反目", |
| | | "秘密恋情被家人发现", |
| | | "离婚协议背后的暗战", |
| | | "家庭成员隐藏的黑历史", |
| | | "婆婆设计嫁祸儿媳", |
| | | "闺蜜成为情敌", |
| | | "丈夫私藏的秘密账户", |
| | | "孩子误入歧途的警示", |
| | | "情敌突然出现挑战婚姻", |
| | | "误会导致家庭聚会变战场", |
| | | "假装和谐实则暗流涌动", |
| | | "秘密证据被人偷走", |
| | | "丈夫被黑暗势力控制", |
| | | "家庭信任的崩塌", |
| | | "误会导致家族断裂", |
| | | "隐藏的遗嘱引发纷争", |
| | | "闺蜜和丈夫的秘密往来", |
| | | "孩子被卷入法律纠纷", |
| | | "丈夫被迫选择家庭或事业", |
| | | "婆婆暗中破坏婚姻", |
| | | "误会导致夫妻分居", |
| | | "家庭财富被抢夺", |
| | | "秘密手机记录曝光", |
| | | "假装和好实则算计", |
| | | "闺蜜背后做交易", |
| | | "孩子突然失踪引发恐慌", |
| | | "丈夫隐藏的病情", |
| | | "婆婆与情敌联手", |
| | | "误会导致家族撕裂", |
| | | "秘密信件成为证据", |
| | | "家庭成员互相猜忌", |
| | | "假离婚真分手", |
| | | "闺蜜抢夺家庭资源", |
| | | "丈夫的隐秘身份曝光", |
| | | "孩子被误导走上歧途", |
| | | "婆婆逼迫儿子离婚", |
| | | "误会导致兄弟反目", |
| | | "隐藏的旧账被翻出", |
| | | "闺蜜设计陷害", |
| | | "丈夫和前任私下联系", |
| | | "家庭成员背叛的真相", |
| | | "秘密监控录像曝光", |
| | | "误会引发的街头争吵", |
| | | "婆媳战争升级", |
| | | "假装和解背后的阴谋", |
| | | "闺蜜泄露家庭秘密", |
| | | "孩子被送进特殊学校", |
| | | "丈夫被威胁离开家庭", |
| | | "婆婆故意制造矛盾", |
| | | "误会导致好友决裂", |
| | | "秘密情书曝光", |
| | | "家庭成员争夺财产", |
| | | "假离婚换取利益", |
| | | "闺蜜当众揭发秘密", |
| | | "丈夫隐藏的过去", |
| | | "孩子误信谎言", |
| | | "婆婆私下操作家庭决策", |
| | | "误会导致家庭聚会爆发冲突", |
| | | "秘密通话录音被泄露", |
| | | "家庭成员互相算计", |
| | | "假装幸福实则破碎", |
| | | "闺蜜挑拨离间", |
| | | "丈夫背叛的证据", |
| | | "孩子被误诊引发家庭危机", |
| | | "婆婆逼迫儿子复婚", |
| | | "误会导致家庭成员分裂", |
| | | "隐藏的财产秘密争夺", |
| | | "闺蜜暗地里和情敌合作", |
| | | "丈夫秘密账户被发现", |
| | | "孩子误入不良圈子", |
| | | "婆婆设计拆散夫妻", |
| | | "误会引发街头争执", |
| | | "秘密录音成家庭炸弹", |
| | | "家庭成员互相背叛", |
| | | "假离婚的真相曝光", |
| | | "闺蜜争夺家庭地位", |
| | | "丈夫隐藏的秘密生活", |
| | | "孩子误信假消息", |
| | | "婆婆暗中控制家庭", |
| | | "误会导致亲人反目", |
| | | "秘密交易被曝光", |
| | | "家庭成员暗中较劲", |
| | | "假装和好实则算计", |
| | | "闺蜜泄露重要信息", |
| | | "丈夫背叛婚姻", |
| | | "孩子陷入校园风波", |
| | | "婆婆逼迫家庭成员做选择", |
| | | "误会导致家庭破裂", |
| | | "隐藏的遗嘱引发争端", |
| | | "闺蜜暗中搞破坏", |
| | | "丈夫和前任私通", |
| | | "孩子被误导行为异常", |
| | | "婆婆设计陷害儿媳", |
| | | "误会引发激烈争吵", |
| | | "秘密证据被人偷走", |
| | | "家庭成员猜疑升级", |
| | | "假离婚真复合", |
| | | "闺蜜抢夺重要资源", |
| | | "丈夫隐藏的疾病", |
| | | "孩子误入歧途", |
| | | "婆婆破坏家庭和谐", |
| | | "误会导致夫妻分居", |
| | | "秘密信件曝光", |
| | | "家庭成员互相算计", |
| | | "假装和谐背后的秘密", |
| | | "闺蜜当众羞辱", |
| | | "丈夫被揭穿谎言", |
| | | "孩子考试作弊被发现", |
| | | "婆婆限制儿媳自由", |
| | | "误会导致家庭撕裂", |
| | | "隐藏的旧账曝光", |
| | | "闺蜜背后捅刀", |
| | | "丈夫秘密出轨", |
| | | "孩子行为异常", |
| | | "婆婆挑拨夫妻关系", |
| | | "误会导致亲人反目成仇", |
| | | "秘密通话录音曝光", |
| | | "家庭成员互相算计", |
| | | "假装和好实则破裂", |
| | | "闺蜜抢走重要男人", |
| | | "丈夫隐藏的秘密身份", |
| | | "孩子被误诊引发风波", |
| | | "婆婆逼迫儿子离婚", |
| | | "误会导致家庭纷争", |
| | | "隐藏的遗产秘密", |
| | | "闺蜜设计陷害", |
| | | "丈夫和前任见面被撞见", |
| | | "孩子误信谎言走上歧途", |
| | | "婆婆私下搞鬼", |
| | | "误会引发激烈争吵", |
| | | "秘密录音成为家庭炸弹", |
| | | "家庭成员互相猜疑", |
| | | "假离婚真分手", |
| | | "闺蜜争夺家庭地位", |
| | | "丈夫隐藏秘密生活", |
| | | "孩子沉迷游戏", |
| | | "婆婆挑拨离间", |
| | | "误会导致家庭破裂", |
| | | "隐藏的财产秘密曝光", |
| | | "闺蜜背后搞破坏", |
| | | "丈夫出轨被发现", |
| | | "孩子被同学欺负", |
| | | "婆婆对儿媳冷眼相待", |
| | | "误会引发亲人决裂", |
| | | "秘密情书曝光", |
| | | "家庭成员互相背叛", |
| | | "假装幸福实则破碎", |
| | | "闺蜜泄露家庭秘密", |
| | | "丈夫冷落妻子", |
| | | "孩子叛逆期爆发", |
| | | "婆婆制造矛盾", |
| | | "误会导致夫妻争吵", |
| | | "隐藏的旧账曝光", |
| | | "闺蜜抢夺重要客户", |
| | | "丈夫拒绝沟通", |
| | | "孩子成绩下滑", |
| | | "婆婆限制儿媳见孩子", |
| | | "误会引发激烈冲突", |
| | | "秘密证据曝光", |
| | | "家庭成员互相算计", |
| | | "假装和好背后算计", |
| | | "闺蜜当众羞辱", |
| | | "丈夫隐瞒真相", |
| | | "孩子行为异常", |
| | | "婆婆干涉家庭决策", |
| | | "误会导致家庭撕裂" |
| | | ], |
| | | "家庭结构": [ |
| | | "三代同堂,祖孙三代挤一屋", |
| | | "单亲妈妈带着两个孩子生活", |
| | | "夫妻二人,独生子女", |
| | | "四口之家,有个叛逆的青少年", |
| | | "三口之家,婆婆同住", |
| | | "三口之家,公婆远居", |
| | | "重组家庭,带着前夫的孩子", |
| | | "夫妻俩与父母同住,矛盾频发", |
| | | "两对夫妻住在一起,互相掣肘", |
| | | "单身父亲抚养两个孩子", |
| | | "三代同堂,婆婆主导一切", |
| | | "夫妻俩带着宠物,宠物成家庭中心", |
| | | "离异后共同抚养孩子的家庭", |
| | | "夫妻二人无子女,婆婆天天唠叨", |
| | | "家庭中有精神疾病患者", |
| | | "夫妻带着父母和孩子的大家庭", |
| | | "三代同堂,孙子被溺爱", |
| | | "夫妻俩与大姑小姑住一起", |
| | | "单身女性带着年迈父母", |
| | | "重组家庭,继子继女相互敌视", |
| | | "婆媳关系紧张的三口之家", |
| | | "夫妻二人,公婆住隔壁", |
| | | "三代同堂,家务分配不均", |
| | | "夫妻带着双胞胎孩子", |
| | | "单亲父亲带着一女一男", |
| | | "家庭中有残障成员", |
| | | "两代同住,父母依赖儿女", |
| | | "三代同堂,家庭矛盾不断升级", |
| | | "单亲妈妈与父母同住", |
| | | "夫妻带着外婆同住", |
| | | "重组家庭,前妻偶尔来访", |
| | | "夫妻二人带着侄子侄女", |
| | | "婆婆与媳妇争夺家庭话语权", |
| | | "三代同堂,孩子被溺爱惯坏", |
| | | "夫妻俩无孩子,亲戚逼婚", |
| | | "单身父亲带着病弱母亲", |
| | | "家庭成员中有赌徒", |
| | | "夫妻带着父母和公婆两边住", |
| | | "三代同堂,隔阂加深", |
| | | "单亲妈妈独立支撑家庭", |
| | | "夫妻俩带着继子", |
| | | "婆媳关系冷淡的三口之家", |
| | | "夫妻二人,祖辈住远方", |
| | | "家庭成员中有酗酒者", |
| | | "三代同堂,家族长辈权威显著", |
| | | "夫妻带着女儿和外孙", |
| | | "单亲父亲带着幼儿", |
| | | "重组家庭,继母与孩子矛盾", |
| | | "夫妻与父母同住但互不干涉", |
| | | "三代同堂,孙辈受祖辈宠爱", |
| | | "夫妻二人,邻居干涉家庭生活", |
| | | "单身女性带着弟弟妹妹", |
| | | "家庭中有创业失败成员", |
| | | "夫妻带着祖父母", |
| | | "三代同堂,父母偏心现象明显", |
| | | "单亲妈妈带着两个女儿", |
| | | "夫妻俩与姑姑同住", |
| | | "婆媳争执不断的四口之家", |
| | | "夫妻二人带着侄子", |
| | | "三代同堂,家庭内部矛盾频发", |
| | | "单亲父亲带着儿子", |
| | | "家庭成员中有失业者", |
| | | "夫妻带着公婆", |
| | | "重组家庭,亲生子女与继子女冲突", |
| | | "夫妻二人,独居无子女", |
| | | "三代同堂,爷爷奶奶掌控家务", |
| | | "单身母亲抚养儿子", |
| | | "夫妻俩与亲戚合住", |
| | | "婆媳关系复杂的四口之家", |
| | | "夫妻二人带着孙辈", |
| | | "家庭成员中有长期病患", |
| | | "三代同堂,家族传统影响深刻", |
| | | "夫妻带着独生女", |
| | | "单亲父亲带着女儿", |
| | | "重组家庭,双方子女互不认同", |
| | | "夫妻二人,与父母隔街相望", |
| | | "三代同堂,祖辈严格管教孙辈", |
| | | "单亲妈妈带着儿子和女儿", |
| | | "夫妻俩带着父母", |
| | | "婆媳争斗激烈的大家庭", |
| | | "夫妻二人,无孩子宠物当家", |
| | | "三代同堂,孙子孙女抢夺宠爱", |
| | | "单身父亲独自抚养家庭", |
| | | "家庭成员有赌博成瘾者", |
| | | "夫妻带着祖父母同住", |
| | | "重组家庭,继母与继子感情淡薄", |
| | | "夫妻二人,婆婆远在外地", |
| | | "三代同堂,家务分工不均", |
| | | "单亲妈妈与爷爷奶奶同住", |
| | | "夫妻俩带着幼儿", |
| | | "婆媳矛盾突出,家庭氛围紧张", |
| | | "夫妻二人带着侄女", |
| | | "三代同堂,孙辈受祖辈溺爱", |
| | | "单亲父亲抚养女儿", |
| | | "家庭成员有酗酒问题", |
| | | "夫妻带着公婆两边", |
| | | "重组家庭,子女不接受继父母", |
| | | "夫妻二人,无亲属同住", |
| | | "三代同堂,家族权力斗争激烈", |
| | | "单身女性抚养弟弟", |
| | | "夫妻俩与父母分开居住", |
| | | "婆媳争吵不断,影响家庭和谐", |
| | | "夫妻二人带着外孙", |
| | | "三代同堂,孙辈被祖辈严格管教", |
| | | "单亲妈妈带着两个孩子", |
| | | "夫妻带着年迈父母", |
| | | "家庭成员中有精神病患者", |
| | | "夫妻二人,与亲戚共同生活", |
| | | "三代同堂,家族传统习俗浓厚", |
| | | "单亲父亲抚养两个孩子", |
| | | "夫妻俩与姑姑同住", |
| | | "婆媳矛盾不断升级", |
| | | "夫妻二人带着侄子侄女", |
| | | "三代同堂,家庭矛盾多发", |
| | | "单身母亲抚养女儿", |
| | | "家庭成员有失业者", |
| | | "夫妻带着祖父母同住", |
| | | "重组家庭,继子继女关系紧张", |
| | | "夫妻二人,独自生活无子女", |
| | | "三代同堂,祖辈权威强势", |
| | | "单亲妈妈带着儿女", |
| | | "夫妻俩与父母同住但不亲近", |
| | | "婆媳关系复杂,家务争执频繁", |
| | | "夫妻二人带着孙辈", |
| | | "三代同堂,家族冲突不断", |
| | | "单亲父亲带着儿子", |
| | | "家庭成员有赌博问题", |
| | | "夫妻带着公婆双方", |
| | | "重组家庭,亲生子女与继子女不和", |
| | | "夫妻二人,无亲属干扰", |
| | | "三代同堂,家庭权力斗争激烈", |
| | | "单身女性带着弟弟妹妹", |
| | | "夫妻俩与父母隔街相望", |
| | | "婆媳争执频繁影响家庭气氛" |
| | | ], |
| | | "第三人设定": [ |
| | | "丈夫的闺蜜", |
| | | "邻居大妈", |
| | | "单位同事", |
| | | "高中同学", |
| | | "前任情人", |
| | | "私家侦探", |
| | | "家庭医生", |
| | | "婚姻咨询师", |
| | | "儿子的老师", |
| | | "女儿的好友", |
| | | "前妻", |
| | | "前夫", |
| | | "小姑子", |
| | | "大姑姐", |
| | | "公公的朋友", |
| | | "婆婆的同事", |
| | | "亲戚中的舅舅", |
| | | "隔壁家的小孩", |
| | | "远房亲戚", |
| | | "街坊邻居", |
| | | "公司领导", |
| | | "老板助理", |
| | | "酒吧老板", |
| | | "KTV经理", |
| | | "饭店厨师", |
| | | "健身教练", |
| | | "美发师", |
| | | "司机", |
| | | "快递员", |
| | | "保姆", |
| | | "家政服务员", |
| | | "朋友的朋友", |
| | | "远房堂兄", |
| | | "学校心理辅导老师", |
| | | "孩子的补习老师", |
| | | "家长会代表", |
| | | "社区志愿者", |
| | | "教会牧师", |
| | | "和尚", |
| | | "街头卖艺者", |
| | | "理发店老板", |
| | | "夜店DJ", |
| | | "出租车司机", |
| | | "公交车司机", |
| | | "快餐店店员", |
| | | "超市收银员", |
| | | "咖啡店老板", |
| | | "外卖小哥", |
| | | "网吧老板", |
| | | "剧团演员", |
| | | "画家", |
| | | "音乐老师", |
| | | "体操教练", |
| | | "摄影师", |
| | | "网络红人", |
| | | "直播主播", |
| | | "微信朋友圈里的匿名爆料者", |
| | | "小区保安", |
| | | "物业经理", |
| | | "房地产中介", |
| | | "银行职员", |
| | | "税务官员", |
| | | "保险推销员", |
| | | "婚庆策划师", |
| | | "花店老板", |
| | | "摄影棚工作人员", |
| | | "文案策划", |
| | | "新闻记者", |
| | | "公众号编辑", |
| | | "微博大V", |
| | | "论坛版主", |
| | | "网友", |
| | | "粉丝团团长", |
| | | "娱乐圈明星", |
| | | "模特", |
| | | "作家", |
| | | "编剧", |
| | | "导演助理", |
| | | "婚礼主持人", |
| | | "心理医生", |
| | | "瑜伽教练", |
| | | "按摩师", |
| | | "足疗师", |
| | | "理疗师", |
| | | "旅游导游", |
| | | "司机兼保镖", |
| | | "健身房会员", |
| | | "游泳教练", |
| | | "武术教练", |
| | | "跆拳道教练", |
| | | "保安队长", |
| | | "社区书记", |
| | | "街道办事处工作人员", |
| | | "文化局职员", |
| | | "文艺团体负责人", |
| | | "志愿者组织负责人", |
| | | "兼职家教", |
| | | "送餐员", |
| | | "宠物美容师", |
| | | "幼儿园老师", |
| | | "小学老师", |
| | | "中学班主任", |
| | | "大学教授", |
| | | "研究生导师", |
| | | "校长", |
| | | "学生会主席", |
| | | "毕业典礼主持人", |
| | | "文化活动主持人" |
| | | ], |
| | | "心理动机": [ |
| | | "渴望被认可和尊重", |
| | | "想要复仇和报复", |
| | | "追求经济利益", |
| | | "渴望爱情和被爱", |
| | | "害怕失去亲人", |
| | | "嫉妒别人的幸福", |
| | | "渴望掌控和权力", |
| | | "想要保护家人", |
| | | "逃避现实压力", |
| | | "追求自由和独立", |
| | | "想要证明自己价值", |
| | | "被过去的伤痛驱使", |
| | | "渴望安全感", |
| | | "追求名誉和地位", |
| | | "害怕孤独和被遗弃", |
| | | "想要寻求公平正义", |
| | | "渴望被关注和宠爱", |
| | | "害怕失败和被嘲笑", |
| | | "追求刺激和冒险", |
| | | "想要弥补过去的错误", |
| | | "渴望被理解和接纳", |
| | | "想要掌控局面", |
| | | "害怕被背叛", |
| | | "想要重建自信", |
| | | "追求幸福生活", |
| | | "害怕面对真相", |
| | | "渴望和平与安宁", |
| | | "想要摆脱困境", |
| | | "追求权利和地位", |
| | | "想要获得宽恕", |
| | | "害怕失去控制", |
| | | "渴望实现梦想", |
| | | "想要维护家庭荣誉", |
| | | "追求个人成长", |
| | | "害怕被排斥", |
| | | "渴望获得机会", |
| | | "想要报答恩情", |
| | | "害怕面对责任", |
| | | "追求物质享受", |
| | | "想要逃避责任", |
| | | "渴望自我实现", |
| | | "害怕失败", |
| | | "想要改变命运", |
| | | "追求精神满足", |
| | | "渴望安全保障", |
| | | "想要获得支持", |
| | | "害怕孤立无援", |
| | | "追求权力平衡", |
| | | "想要报复伤害", |
| | | "渴望获得认可", |
| | | "害怕失去地位", |
| | | "想要重新开始", |
| | | "追求理想生活", |
| | | "渴望幸福家庭", |
| | | "想要证明清白", |
| | | "害怕被误解", |
| | | "追求公平竞争", |
| | | "想要获得尊重", |
| | | "渴望内心平静", |
| | | "害怕被控制", |
| | | "想要获得自由", |
| | | "追求心灵慰藉", |
| | | "渴望被关注", |
| | | "想要获得利益", |
| | | "害怕孤独终老", |
| | | "追求社会认可", |
| | | "想要实现自我价值", |
| | | "渴望和谐关系", |
| | | "害怕失去亲情", |
| | | "想要保全面子", |
| | | "追求精神独立", |
| | | "渴望被爱护", |
| | | "想要挑战权威", |
| | | "害怕被欺骗", |
| | | "追求财富积累", |
| | | "想要摆脱束缚", |
| | | "渴望获得幸福", |
| | | "害怕被忽视", |
| | | "追求家庭和睦", |
| | | "想要建立影响力", |
| | | "渴望自我认同", |
| | | "害怕失败打击", |
| | | "想要追求梦想", |
| | | "追求安稳生活", |
| | | "渴望获得信任", |
| | | "害怕被遗忘", |
| | | "想要保持秘密", |
| | | "追求心理平衡", |
| | | "渴望被重视", |
| | | "想要修复关系", |
| | | "害怕孤独感", |
| | | "追求自我完善", |
| | | "想要实现目标", |
| | | "渴望心灵自由", |
| | | "害怕失控", |
| | | "想要获得幸福感", |
| | | "追求安全感", |
| | | "渴望得到帮助", |
| | | "害怕被伤害", |
| | | "想要获得权力", |
| | | "追求生活品质", |
| | | "渴望家庭温暖", |
| | | "害怕被孤立", |
| | | "想要创造奇迹", |
| | | "追求成功认可", |
| | | "渴望改变现状", |
| | | "害怕被抛弃", |
| | | "想要获得自由支配", |
| | | "追求自我成长", |
| | | "渴望被理解支持", |
| | | "害怕失败后果", |
| | | "想要获得幸福生活", |
| | | "追求心理安慰", |
| | | "渴望家庭团圆", |
| | | "害怕被背叛", |
| | | "想要获得财富", |
| | | "追求内心平静" |
| | | ], |
| | | "张力设定": [ |
| | | "突如其来的秘密曝光", |
| | | "背叛被当事人发现", |
| | | "亲密关系中的谎言揭穿", |
| | | "隐秘财产被意外发现", |
| | | "亲人之间的误会升级", |
| | | "关键证据被篡改", |
| | | "意外怀孕导致家庭动荡", |
| | | "假离婚真复合的真相", |
| | | "隐藏的过去被揭露", |
| | | "竞争中的暗中破坏", |
| | | "情敌突然出现挑衅", |
| | | "亲友的背后捅刀", |
| | | "意外车祸引发风波", |
| | | "误会导致朋友反目", |
| | | "子女叛逆加剧家庭矛盾", |
| | | "秘密录音被公开", |
| | | "财产争夺战白热化", |
| | | "谎言连环被拆穿", |
| | | "秘密情书曝光", |
| | | "重要人物突然失踪", |
| | | "家庭聚会变成战场", |
| | | "亲人突然揭露丑闻", |
| | | "失控的情绪爆发", |
| | | "婚外情被撞见", |
| | | "亲子关系的重大裂痕", |
| | | "法律纠纷将家庭撕裂", |
| | | "秘密交易被曝光", |
| | | "家庭成员的心理崩溃", |
| | | "被误解的行为引发连锁反应", |
| | | "重要决定引发全家争论", |
| | | "被遗忘的旧账被揭露", |
| | | "双重身份曝光", |
| | | "亲人意外揭露隐私", |
| | | "突发疾病导致家庭矛盾", |
| | | "秘密手机信息被发现", |
| | | "精神压力引发疯狂行为", |
| | | "家庭成员意外相遇尴尬场面", |
| | | "不可告人的交易曝光", |
| | | "好友的谎言暴露", |
| | | "意外发现亲人秘密恋情", |
| | | "情感纠葛引发连锁反应", |
| | | "亲人背叛导致信任崩塌", |
| | | "亲情与利益的激烈冲突", |
| | | "秘密拍摄的视频流出", |
| | | "虚假证据陷害", |
| | | "家庭成员之间的心理战争", |
| | | "关键时刻的背叛", |
| | | "感情的极限考验", |
| | | "深藏的仇恨爆发" |
| | | ], |
| | | "结局方向": [ |
| | | "破镜重圆,携手面对未来", |
| | | "彻底分离,各自安好", |
| | | "意外怀孕,迎来新生命", |
| | | "家庭成员和解,重建信任", |
| | | "事业成功,家庭变迁", |
| | | "婆媳反目成仇,家族分裂", |
| | | "秘密曝光,导致家庭破裂", |
| | | "意外事故引发反思与改变", |
| | | "旧情复燃,却注定无果", |
| | | "感情升温,婚姻得到修复", |
| | | "子女成家立业,家庭和谐", |
| | | "家庭财富重组,分配纠纷", |
| | | "亲情被利益冲淡,疏远加深", |
| | | "秘密双重身份揭露,震惊全家", |
| | | "新成员加入,带来希望与挑战", |
| | | "误会解开,重新建立感情", |
| | | "突发疾病,家庭团结一致", |
| | | "感情破裂,走向离婚边缘", |
| | | "和解后的新开始", |
| | | "不可调和的矛盾,彻底分道扬镳", |
| | | "牺牲自我,成全他人幸福", |
| | | "子女反叛,家庭关系紧张", |
| | | "意外遗产引发争夺战", |
| | | "旧账重提,恩怨未了", |
| | | "秘密被揭露,家庭洗牌", |
| | | "历经风雨,最终幸福美满", |
| | | "感情淡化,选择和平分手", |
| | | "家庭聚会重拾温情", |
| | | "离婚后仍保持朋友关系", |
| | | "突如其来的死亡事件", |
| | | "事业挫折导致家庭危机", |
| | | "情敌败露,夫妻关系巩固", |
| | | "家庭成员移居海外,重新开始", |
| | | "感情渐行渐远,淡出彼此生活", |
| | | "婆媳矛盾解决,和睦相处", |
| | | "秘密孩子身份曝光,引发波澜", |
| | | "失去亲人后重拾生活勇气", |
| | | "婚姻走向破裂,单亲生活开始", |
| | | "共同面对困难,感情更坚固", |
| | | "秘密被原谅,迎来新生活", |
| | | "事业成功,家庭稳定", |
| | | "误会导致决裂,难以修复", |
| | | "旧爱回归,引发新纷争", |
| | | "感情渐淡,选择放手", |
| | | "亲情与爱情的抉择", |
| | | "家庭成员分居异地", |
| | | "和好如初,旧情复燃", |
| | | "意外事件改变命运轨迹", |
| | | "秘密孩子被接纳", |
| | | "家庭财富被重新分配", |
| | | "深刻反省,重建家庭秩序", |
| | | "感情破裂,选择独自生活", |
| | | "家庭成员意外和解", |
| | | "亲人重聚,温情满满", |
| | | "事业转型,带来新希望", |
| | | "感情纠葛未解,继续纠缠", |
| | | "选择离开,开始新生活", |
| | | "家庭成员意外去世", |
| | | "旧恨难解,家庭关系紧张", |
| | | "秘密被掩盖,继续隐藏", |
| | | "家庭关系改善,氛围和谐", |
| | | "感情渐浓,步入婚姻殿堂", |
| | | "事业失败,家庭陷入困境", |
| | | "情敌败退,夫妻情深", |
| | | "亲情疏远,关系渐远", |
| | | "重组家庭成员和解", |
| | | "秘密孩子身份隐藏", |
| | | "家庭成员出走,带来变故", |
| | | "婆媳矛盾加剧", |
| | | "感情升温,迎接新生命", |
| | | "事业成功,家庭富裕", |
| | | "秘密被揭发,家庭瓦解", |
| | | "选择宽恕,重新开始", |
| | | "家庭成员移居国外", |
| | | "感情渐淡,选择分开", |
| | | "亲情破裂,难以修复", |
| | | "感情复合,迎来新希望", |
| | | "事业转型,家庭支持", |
| | | "意外怀孕,家庭新成员", |
| | | "秘密曝光,感情破裂", |
| | | "家庭成员团结一致", |
| | | "选择离婚,重新寻找幸福", |
| | | "旧情复燃,矛盾加剧", |
| | | "亲人意外去世,家庭反思", |
| | | "感情渐行渐远", |
| | | "事业成功,家庭美满", |
| | | "秘密被掩盖,继续生活", |
| | | "选择原谅,重建信任", |
| | | "家庭成员和解,迎接未来", |
| | | "感情破裂,独自坚强", |
| | | "事业陷入低谷,家庭支持", |
| | | "意外事件改变人生", |
| | | "选择宽容,家庭幸福", |
| | | "秘密揭露,感情考验", |
| | | "家庭成员分裂", |
| | | "感情升温,婚姻稳固", |
| | | "事业成功,生活美好", |
| | | "秘密孩子被接纳", |
| | | "家庭重组,迎接挑战", |
| | | "感情淡化,选择放手", |
| | | "亲情破裂,难以修复" |
| | | ], |
| | | "反转类型": [ |
| | | "意想不到的身份揭露", |
| | | "关键证据被伪造", |
| | | "最亲密的人背叛", |
| | | "昔日仇敌变成盟友", |
| | | "误会化解成为真相", |
| | | "假死真生的惊人反转", |
| | | "财富秘密被隐藏", |
| | | "真相被误导成谎言", |
| | | "秘密恋情公开", |
| | | "双重身份曝光", |
| | | "仇恨变成了深情", |
| | | "敌人突然变成救星", |
| | | "过去的恩怨反被救赎", |
| | | "亲人竟是幕后黑手", |
| | | "意外怀孕带来新希望", |
| | | "家族秘密影响整个家庭", |
| | | "表面和平下暗潮涌动", |
| | | "关键人物失踪真相", |
| | | "遗产分配引发惨烈反转", |
| | | "真相隐藏在最不可能的人身上", |
| | | "离奇事故揭开秘密", |
| | | "误会升级成和解", |
| | | "时间倒流式的记忆反转", |
| | | "伪装者身份被揭穿", |
| | | "表面幸福实则暗藏危机", |
| | | "失忆导致身份错乱", |
| | | "秘密日记揭露真相", |
| | | "婚姻中的隐秘联盟", |
| | | "敌人变成朋友的反转", |
| | | "关键证据突然消失", |
| | | "谎言被揭穿后的大逆转", |
| | | "意外的遗嘱内容改变局势", |
| | | "昔日恋人现身掀波澜", |
| | | "背叛者自我救赎", |
| | | "被误解的人证明清白", |
| | | "关键线索意外出现", |
| | | "秘密录音曝光", |
| | | "被隐藏的亲情爆发", |
| | | "不可能的合作", |
| | | "陷害者遭遇反击", |
| | | "意外怀孕成为家庭纽带", |
| | | "被遗忘的承诺重新兑现", |
| | | "误会导致的悲剧转机", |
| | | "暗藏的继承权之争", |
| | | "真相大白,误会冰释", |
| | | "隐藏身份的惊人反转", |
| | | "被遗弃者逆袭成功", |
| | | "误判引发的情感波动", |
| | | "家族秘密改变命运", |
| | | "陷阱反转成救赎", |
| | | "失踪人员的惊人身份", |
| | | "谎言背后的真情流露", |
| | | "原本对立者携手共进", |
| | | "爱情与仇恨的戏剧转换", |
| | | "秘密孩子身份曝光", |
| | | "仇人变成保护者", |
| | | "被误解的英雄形象", |
| | | "时间错乱引发的真相反转", |
| | | "身份互换引发混乱", |
| | | "意外发现的亲情纽带", |
| | | "被背叛者的复仇计划", |
| | | "敌人之间的和解", |
| | | "误会解除后的幸福生活", |
| | | "隐藏的财富线索出现", |
| | | "被遗忘的亲情再现", |
| | | "关键时刻的英雄救美", |
| | | "秘密日记带来的真相", |
| | | "失忆者恢复记忆后的反转", |
| | | "家族成员的身份互换", |
| | | "秘密会议暴露真相", |
| | | "误导性的证据揭露", |
| | | "亲人之间的意外和解", |
| | | "秘密信件带来的反转", |
| | | "身份暴露引发的冲突", |
| | | "被陷害者成功洗清冤屈", |
| | | "被遗弃者的归来", |
| | | "误会转化为感情升温", |
| | | "秘密录像曝光", |
| | | "对立家族的联姻", |
| | | "关键人物的双重生活", |
| | | "意外怀孕成救赎契机", |
| | | "身份错乱引发的爱情悲剧", |
| | | "秘密交易的曝光", |
| | | "敌人反被利用", |
| | | "家庭成员身份重叠", |
| | | "遗产纷争的惊人结局", |
| | | "被误解的亲情爆发", |
| | | "误会成为家庭纽带", |
| | | "昔日恩怨变成合作", |
| | | "隐藏的真相逐渐浮出水面", |
| | | "关键证据意外消失", |
| | | "谎言背后的真相揭秘", |
| | | "身份揭露后的情感转折", |
| | | "秘密计划被识破", |
| | | "意外的英雄出现", |
| | | "亲人之间的误会消除", |
| | | "失踪者归来带来震惊", |
| | | "秘密恋情的公开", |
| | | "误判导致的情感和解" |
| | | ], |
| | | "风格": [ |
| | | "像小红书热帖一样,狗血又欲罢不能", |
| | | "像豆瓣日记一样细腻讽刺,层层递进", |
| | | "像情感主播口播剧本,3分钟一个反转", |
| | | "像综艺吐槽大会,语速快、爆点多", |
| | | "像短视频第一人称碎碎念,代入感强", |
| | | "像微博超话爆料贴,带点真实和狗带感", |
| | | "像公众号爆款情感文,温柔中藏利刃", |
| | | "像知乎热帖“我嫁进了一个奇葩家庭”,内容真实又极限拉扯", |
| | | "假装是“当事人匿名投稿”,引发评论狂潮", |
| | | "写得像剧本分镜头,直接可拍短剧", |
| | | "像老北京胡同大妈闲聊,幽默接地气", |
| | | "像90年代都市爱情小说,细腻温情", |
| | | "像新浪微博热点评论,尖锐犀利", |
| | | "像抖音剧情短视频,节奏明快", |
| | | "像女性杂志访谈录,感性丰富", |
| | | "像脱口秀单口相声,幽默夸张", |
| | | "像电影解说,剧情紧凑", |
| | | "像悬疑小说,层层设伏笔", |
| | | "像法庭辩论,逻辑严密", |
| | | "像乡村故事,朴实真切", |
| | | "像时尚达人日记,个性鲜明", |
| | | "像心理咨询师讲述,深入剖析", |
| | | "像漫画对白,简洁生动", |
| | | "像浪漫言情小说,细腻感人", |
| | | "像网红直播间吐槽,直接犀利", |
| | | "像职场小说,冲突激烈", |
| | | "像历史小说,情节跌宕", |
| | | "像校园小说,青春洋溢", |
| | | "像旅行游记,风景描写丰富", |
| | | "像生活感悟随笔,哲理深刻", |
| | | "像科技评论,理性分析", |
| | | "像家庭伦理剧本,戏剧张力强", |
| | | "像动漫解说,轻松幽默", |
| | | "像都市侦探小说,紧张刺激", |
| | | "像情绪化日记,真情流露", |
| | | "像诗歌散文,语言优美", |
| | | "像综艺真人秀旁白,活泼生动", |
| | | "像儿童故事,简单明快", |
| | | "像纪录片旁白,真实客观", |
| | | "像朋友圈长文,情感浓烈", |
| | | "像新闻报道,事实准确", |
| | | "像心理学论文,理论丰富", |
| | | "像美食评论,细节丰富", |
| | | "像摇滚歌词,激情四溢", |
| | | "像游戏剧情,环环相扣", |
| | | "像广告文案,吸引眼球", |
| | | "像情绪化脱口秀,直击人心", |
| | | "像散文随笔,感性自然", |
| | | "像微博段子手,幽默诙谐", |
| | | "像快节奏网剧,剧情紧凑", |
| | | "像爱情小说,甜中带虐", |
| | | "像都市传说,神秘诡异", |
| | | "像推理小说,悬念迭起", |
| | | "像浪漫喜剧,轻松搞笑", |
| | | "像心理悬疑,紧张压抑", |
| | | "像现实主义小说,真实反映", |
| | | "像幻想小说,想象丰富", |
| | | "像励志故事,积极向上", |
| | | "像幽默短文,笑点频出", |
| | | "像博客日记,个人视角鲜明", |
| | | "像网络小说,剧情丰富", |
| | | "像情感论坛发帖,真情吐露", |
| | | "像旅途日志,生动细腻", |
| | | "像哲学散文,发人深省", |
| | | "像社交媒体短文,言简意赅", |
| | | "像街头采访录,真实接地气", |
| | | "像经典文学,语言优雅", |
| | | "像演讲稿,激励人心", |
| | | "像职场八卦,热辣刺激", |
| | | "像历史纪实,资料详实", |
| | | "像悬疑推理剧本,环环相扣", |
| | | "像科幻小说,奇幻色彩", |
| | | "像自传,情感真挚", |
| | | "像访谈录,人物鲜活", |
| | | "像民间故事,通俗易懂", |
| | | "像心理剧,情绪丰富", |
| | | "像反乌托邦小说,黑暗未来", |
| | | "像新闻特写,细节生动", |
| | | "像纪实文学,真实感人", |
| | | "像生活小品,幽默风趣", |
| | | "像网络吐槽帖,直白辛辣", |
| | | "像哲理故事,引人深思", |
| | | "像社会调查报告,数据详实", |
| | | "像自我剖析文,情感细腻", |
| | | "像影视剧解说,节奏感强", |
| | | "像网络小说章节,高潮迭起", |
| | | "像职场秘闻,内幕曝光", |
| | | "像反转悬念小说,扣人心弦", |
| | | "像历史传奇,波澜壮阔", |
| | | "像情感爆料帖,劲爆吸睛", |
| | | "像传统戏曲,唱念做打", |
| | | "像网络综艺,互动感强", |
| | | "像直播互动,现场感十足", |
| | | "像散文诗,抒情唯美", |
| | | "像街头小说,接地气", |
| | | "像科幻短篇,思维跳跃", |
| | | "像心理分析报告,专业深入", |
| | | "像反思日志,自省真诚", |
| | | "像校园日记,纯真自然", |
| | | "像商战小说,计谋纷呈", |
| | | "像情感短视频文案,简洁有力", |
| | | "像微博热评,犀利点评", |
| | | "像个人成长故事,励志感人", |
| | | "像科技快讯,信息丰富" |
| | | ], |
| | | "字数": [ |
| | | 2000, |
| | | 2500, |
| | | 3000 |
| | | ] |
| | | } |
| | |
| | | GOOGLE_API_KEY='AIzaSyAfJkDNUSZrGbJ6AmpQ1_RHX-0IjUegJOU' |
| | | GOOGLE_MODEL= "gemini-2.5-flash" #gemini-1.5-flash-latest |
| | | GOOGLE_CHAT_MIN_INTERVAL = 3.5 |
| | | GOOGLE_GEMINI_TEMPERATURE_MIN = 0.9 |
| | | GOOGLE_GEMINI_TEMPERATURE_MAX = 1.2 |
| | | GOOGLE_GEMINI_TEMPERATURE_MIN = 0.8 |
| | | GOOGLE_GEMINI_TEMPERATURE_MAX = 1.4 |
| | | |
| | | GOOGLE_GEMINI_TOPN_MIN = 0.7 |
| | | GOOGLE_GEMINI_TOPN_MAX = 0.9 |
| | | |
| | | |
| | | TRANSLATE_API_TEMPLATE = ( |
| | | "https://api.mymemory.translated.net/get?q={prompt}&langpair=zh-CN|en" |
| | |
| | | GEMINI_PROMPT_TAG = ''' |
| | | 请根据以上对话内容,生成 3 到 5 个相关 TAG,总字数不超过 30 个。TAG 需简短、精准且有吸引力,能增强传播性并吸引用户关注。可结合热门话题、流行趋势或内容核心关键词,使其更具互动性和点击欲望,最终以顿号(、)隔开。 |
| | | ''' |
| | | |
| | | #1、真实自然、富有感染力、扩写型的改写风格 |
| | | GEMINI_PROMPT_INIT_DEFAULT = ''' |
| | | 请将接下来提供的文章内容进行全面自然的改写,要求如下: |
| | | -语言风格真实自然:避免生硬、机械或套话式表达,改写应像真实的人在写作,具有口语化、节奏感强的语言风格。 |
| | | -表达富有感染力:通过讲故事、设问、比喻、情绪化语言等方式增强吸引力,让读者产生共鸣,避免信息堆砌或冷冰冰的陈述。 |
| | | -内容完整、表达多样:在不改变原文核心信息的前提下,尽可能脱离原始句式结构,适当加入补充视角、案例、数据、对比分析等,丰富内容深度。 |
| | | -扩展到3000字以上(如原文较短):扩写时需自然增加内容层次,拒绝重复堆字或无效扩展。 |
| | | -如原文较短,扩展到3000字以上。扩写时需自然增加内容层次,拒绝重复堆字或无效扩展。 |
| | | -保持原始时间、数字准确不变。 |
| | | -结构清晰、段落衔接自然:整体文章应具备良好的阅读节奏和逻辑流畅度,适合年轻读者与普通大众阅读。 |
| | | -输出内容请按逻辑拆分为多段短小段落(每段 2~4 句),不要合并为一整段; |
| | | -如遇长句,请适当断句,提高可读性; |
| | | -每段内容应适合手机端阅读,便于视觉停顿和滑动浏览; |
| | | |
| | | 输出要求: |
| | | - 逐段输出改写后的内容(我将逐段发送原文) |
| | |
| | | - 避免使用感性、煽情的语言,强调客观表达; |
| | | - 结构清晰、重点突出,在不改变原文核心信息的前提下,尽可能脱离原始句式结构; |
| | | - 保持原文的事实、时间、数据准确不变; |
| | | - 如原文较短,扩展到3000字以上。扩写时需自然增加内容层次,拒绝重复堆字或无效扩展。 |
| | | - 结构清晰、段落衔接自然:整体文章应具备良好的阅读节奏和逻辑流畅度,适合年轻读者与普通大众阅读。 |
| | | - 输出内容请按逻辑拆分为多段短小段落(每段 2~4 句),不要合并为一整段; |
| | | - 如遇长句,请适当断句,提高可读性; |
| | | - 每段内容应适合手机端阅读,便于视觉停顿和滑动浏览; |
| | | 输出要求: |
| | | - 逐段输出改写后的内容(我将逐段发送原文) |
| | | - 回复中不要出现“好的”、“这是第几段改写”、“请继续发送下一段”等内容。 |
| | |
| | | - 可适度加入金句、对比、夸张语气、热门话题、网络流行语; |
| | | - 引导读者点赞、转发、评论,但不影响原文主旨; |
| | | - 保持原始时间、数字准确不变; |
| | | - 如原文较短,扩展到3000字以上。扩写时需自然增加内容层次,拒绝重复堆字或无效扩展。 |
| | | - 结构清晰、段落衔接自然:整体文章应具备良好的阅读节奏和逻辑流畅度,适合年轻读者与普通大众阅读。 |
| | | - 输出内容请按逻辑拆分为多段短小段落(每段 2~4 句),不要合并为一整段; |
| | | - 如遇长句,请适当断句,提高可读性; |
| | | - 每段内容应适合手机端阅读,便于视觉停顿和滑动浏览; |
| | | 输出格式: |
| | | - 逐段输出改写后的内容(我将逐段发送原文) |
| | | - 回复中不要出现“好的”、“这是第几段改写”、“请继续发送下一段”等内容。 |
| | |
| | | - 注重知识传递、逻辑通顺,适合用作科普公众号或知乎文章; |
| | | - 适当增加背景知识、历史脉络或生活关联; |
| | | - 保持事实和数据准确不变; |
| | | - 如原文较短,扩展到3000字以上。扩写时需自然增加内容层次,拒绝重复堆字或无效扩展。 |
| | | - 结构清晰、段落衔接自然:整体文章应具备良好的阅读节奏和逻辑流畅度,适合年轻读者与普通大众阅读。 |
| | | - 输出内容请按逻辑拆分为多段短小段落(每段 2~4 句),不要合并为一整段; |
| | | - 如遇长句,请适当断句,提高可读性; |
| | | - 每段内容应适合手机端阅读,便于视觉停顿和滑动浏览; |
| | | 输出方式: |
| | | - 逐段输出改写后的内容(我将逐段发送原文) |
| | | - 回复中不要出现“好的”、“这是第几段改写”、“请继续发送下一段”等内容。 |
| | |
| | | - 可以加入场景描述、心理描写、对话等方式增强代入感; |
| | | - 逻辑合理、内容完整,适当改写原文结构; |
| | | - 保留原有时间、数字等准确内容; |
| | | - 如原文较短,扩展到3000字以上。扩写时需自然增加内容层次,拒绝重复堆字或无效扩展。 |
| | | - 结构清晰、段落衔接自然:整体文章应具备良好的阅读节奏和逻辑流畅度,适合年轻读者与普通大众阅读。 |
| | | - 输出内容请按逻辑拆分为多段短小段落(每段 2~4 句),不要合并为一整段; |
| | | - 如遇长句,请适当断句,提高可读性; |
| | | - 每段内容应适合手机端阅读,便于视觉停顿和滑动浏览; |
| | | 输出方式: |
| | | - 逐段输出改写后的内容(我将逐段发送原文) |
| | | - 回复中不要出现“好的”、“这是第几段改写”、“请继续发送下一段”等内容。 |
| | |
| | | "storytelling": GEMINI_PROMPT_INIT_STORYTELLING |
| | | } |
| | | |
| | | DEFAULT_PREFIX_MAP = [ |
| | | "在这片温柔的文字世界里,我愿与你一同感受读者们的喜怒哀乐、悲欢离合,让每一份情绪都被认真倾听。", |
| | | "这一页,记录的不只是故事,更是成千上万读者的心事,我愿把这份真挚与感动与你分享。", |
| | | "每一次动笔,都是想把读者心中最柔软的那部分传递给你。愿你在这里读懂他们,也读懂自己。", |
| | | "情感从不孤单,在这里,我们共同走近读者的内心世界,也许其中一段话,就藏着你的影子。", |
| | | "与你分享的不只是文字,而是千百个读者经历过的爱与失落、成长与重逢,这一切,都值得被听见。", |
| | | "我们收集每一个温柔真实的情感片段,拼凑成一幅幅有血有肉的图景,邀你一同聆听与感受。", |
| | | "这不只是一篇文章,更像是一封写给每个愿意驻足倾听的你们的心灵信笺。", |
| | | "希望你能在这里,看到读者的情绪,也找到自己的一丝共鸣,让这份连结不止于文字。", |
| | | "这段文字承载了太多真情实感,它们来自一双双真实的眼睛、一颗颗跳动的心,与你共享。", |
| | | "愿你在接下来的文字中,不只是读故事,更能感受到那些被认真对待的情绪和深刻的人性。" |
| | | ] |
| | | |
| | | DEFAULT_SURFIX_MAP = [ |
| | | "感谢你愿意花时间读完这些文字,这世上最温柔的回馈,莫过于你的一个点赞、关注或留言,我们在这里等你。", |
| | | "如果你也曾有类似的心情,希望今天的内容能带给你一点温暖和力量。欢迎点赞、分享,让更多人听见这份情绪。", |
| | | "每一次写作,都是与未知的你们的一次心灵对话。若你读到了这里,真诚地感谢你,也邀请你一起传播这份共鸣。", |
| | | "感谢你的阅读,这些文字的意义,因为有你在读,才变得更完整。如果喜欢,别忘了点赞和关注,愿我们常相见。", |
| | | "愿你在这篇文章里找到一丝慰藉,哪怕只是片刻的共鸣。谢谢你读到最后,你的点赞与关注是我继续分享的动力。", |
| | | "读者的每一份情绪都是独一无二的,感谢你愿意陪我一起感受与记录。如果喜欢,请点赞、关注、分享这份心意。", |
| | | "能与你在文字中相遇,是一件幸运的事。若你觉得今天的内容触动了你,就请用一个点赞、一条评论与我对话。", |
| | | "文字写完了,但共鸣不会结束。感谢你认真读到最后,你的每一次互动,都是我继续写下去的勇气。", |
| | | "如果你在这些文字中看到自己的影子,或感受到他人的心跳,那我就不曾孤独。谢谢你,愿你常来。", |
| | | "真心感谢你陪我读完这段故事,如果这篇文章让你有所触动,那请给它一点小小回应吧。点赞、关注、分享,都是最好的支持。" |
| | | ] |
| | | |
| | | |
| | | |
| | | ''' |
| | | 最终优化后的提示词: |
| | | 请重写这篇文章,使其更加自然、流畅,并具有真实的人工写作风格。避免任何生硬、刻板、机械化的表达,尤其是那种一看就像 AI 生成的生硬句式。请使用更加口语化、富有表现力的语言,像真正的人在交流,而不是生硬地堆砌信息。句子结构要多样化,避免过度重复固定模式,使内容更具节奏感和层次感。文章应具有亲和力,并能引发读者的情感共鸣。 |
| | | 请尽可能去重原文的表述,但确保核心信息不变,适当添加新的视角和信息,使文章的内容更加完整和引人入胜。文章需要融合幽默感、故事化的叙述方式、专业性表达以及生活化的语气,使其既生动有趣,又富有权威性和亲和力。可以适当加入隐喻、比喻、互动式提问或小故事,让读者更容易代入,而不是像在读一篇冷冰冰的报告。 |
| | | 文章中的所有时间和数字必须保持不变,不能修改。对于篇幅较短的文章,请扩写内容,使最终文章字数不少于 3000 字。扩写时要通过丰富的信息、具体的场景描述、案例分析、用户故事、对比观点、数据分析等方式自然地增加文章深度,而不是简单重复或堆砌词汇。避免“刻意凑字”的感觉,确保文章内容充实且流畅。 |
| | | 此外,请确保文章结构清晰,段落之间过渡自然,读者阅读时感到轻松且连贯。目标读者是[普通大众”,“年轻人”],文章需符合发布标准,激发读者点击、思考或行动。最终的文章应展现真实感、可信度和情感深度,而非看起来像机械化生成的内容。 |
| | | |
| | | |
| | | 提示词 1:生成吸引人的 Post 标题 |
| | | 要求: |
| | | |
| | | 简短有力,总字数少于 64 个。 |
| | | 引发好奇,让人想点进去了解更多。 |
| | | 可以使用悬念、对比、数字、问题等技巧,例如:“你绝对想不到,这件事居然是真的!” |
| | | 如果适用,可结合情感、争议、热门话题等元素,增强吸引力。 |
| | | 不必完全照搬内容,可适当创造性概括,只要能吸引点击即可。 |
| | | 提示词: |
| | | "请根据以下文字,总结一个引人入胜的 Post 标题,确保总字数不超过 64 个。标题需要简短有力,引发好奇心,让人忍不住想点进去阅读。可以使用悬念、对比、数字、问题等技巧,使其更具吸引力。无需严格复述原文,只要让人感兴趣即可。无需解释或分析,直接输出标题即可。以下是原文:" |
| | | |
| | | |
| | | 提示词 2:生成吸引人的描述文本(不超过 100 字) |
| | | 要求: |
| | | |
| | | 短小精悍(≤100 字),但能快速吸引用户注意力。 |
| | | 可以不完全基于内容,只要能让人感兴趣就行。 |
| | | 可使用“制造悬念”“引发情绪”“提出问题”“强调惊喜/冲突”等技巧。 |
| | | 语气可灵活,幽默、震惊、神秘、专业等均可。 |
| | | 避免普通无聊的描述,力求独特、新颖、勾人。 |
| | | 提示词: |
| | | "请根据以下文字,生成一段吸引人的描述(不超过 100 字)。这段描述不需要严格复述原文,但必须能让读者产生好奇心,想要点进去阅读。可以制造悬念、引发情绪、提出问题、强调惊喜或冲突,使其更具吸引力。语气可以幽默、震惊、神秘或专业化。以下是原文:" |
| | | |
| | | **提示词 3:生成吸引人的 TAG** |
| | | |
| | | **要求:** |
| | | 1. **生成 3 到 5 个相关 TAG**,总字数不超过 30 个。 |
| | | 2. **TAG 要简短、精准、具有吸引力**,避免过长或过于普通的词汇。 |
| | | 3. **可以结合热门话题、流行趋势或内容核心关键词**,增强传播性。 |
| | | 4. **适当使用情绪化、悬念化、互动性强的词汇**,例如 #震惊发现、#这也太酷了、#必看干货。 |
| | | |
| | | **提示词:** |
| | | *"请根据以下文字,生成 3 到 5 个相关 TAG,总字数不超过 30 个。TAG 需简短、精准且有吸引力,能增强传播性并吸引用户关注。可结合热门话题、流行趋势或内容核心关键词,使其更具互动性和点击欲望。以下是原文:"* |
| | | |
| | | |
| | | **提示词 4:生成高精度图片的 Stable Diffusion Prompt** |
| | | |
| | | **要求:** |
| | | 1. **基于文稿核心内容生成一张高质量图片**,确保主题匹配。 |
| | | 2. **使用详细的视觉描述**,包括环境、光照、氛围、人物/物体细节等,增强画面感。 |
| | | 3. **确保画面风格符合内容需求**,如写实、赛博朋克、油画风、动漫风等。 |
| | | 4. **可以结合艺术构图原则**,如黄金比例、动态构图,使画面更具视觉冲击力。 |
| | | 5. **适当加入情感元素**,让图片更具故事性或情绪感染力。 |
| | | 6. **如果涉及特定历史/文化/科技背景,需要准确体现**,避免通用性过强导致的模糊表达。 |
| | | |
| | | **提示词:** |
| | | *"请基于以下文稿内容,生成一段高精度的 Stable Diffusion 图片描述。描述应包括环境、人物/物体、光照、氛围等细节,使画面生动且符合主题。请使用具体的视觉词汇,如‘柔和的晨光洒在古老的木桌上’或‘霓虹灯映照着潮湿的赛博朋克街道’。确保风格明确(如写实、幻想、未来主义),并优化构图,使图片具有强烈的视觉冲击力。以下是文稿:"* |
| | | |
| | | |
| | | 参数 推荐值 说明 |
| | | 模型(Checkpoint) 根据需求选择,如SDXL, RealisticVision, DreamShaper 影响画风,写实可选 RealisticVision,二次元可选 Anything V5/V6 |
| | | 采样方法(Sampler) DPM++ 2M Karras 推荐 DPM++ 系列,平衡速度和质量 |
| | | 采样步数(Steps) 30~50 低步数生成速度快,高步数细节更丰富 |
| | | 分辨率(Resolution) 768x768 或 1024x1024 方形适合通用,宽幅 1024x576 适合电影感 |
| | | 提示词引导系数(CFG Scale) 7~10 控制 Prompt 影响力,过高会使画面过度锐化 |
| | | 种子(Seed) -1(随机)或固定种子 随机生成不同图,固定种子复现相同图 |
| | | 批量生成 1~4 一次生成多张,方便对比选择 |
| | | Hires. Fix(高清修复) 开启(Upscale 1.5x~2x) 用于提升细节,避免模糊 |
| | | ✅ 2. 通用负面提示词(Negative Prompt) |
| | | 负面提示词可以固定使用,避免常见问题,如畸形、低质量、奇怪的姿势等。 |
| | | |
| | | 固定负面提示词(推荐): |
| | | |
| | | arduino |
| | | 复制 |
| | | 编辑 |
| | | (worst quality, low quality, blurry, bad anatomy, deformed, extra limbs, missing fingers, disfigured, lowres, overexposed, watermark, nsfw, text, cropped, distorted face, jpeg artifacts, poorly drawn hands, malformed fingers, unnatural body, bad proportions) |
| | | 如果你的图片要求超写实(如人物照片),可以再加上: |
| | | |
| | | scss |
| | | 复制 |
| | | 编辑 |
| | | (cartoon, anime, 3d render, cgi, sketch, painting) |
| | | ✅ 3. 其他优化选项(可选) |
| | | Refiner(精细化模型,SDXL 推荐):使用 SDXL 时,可开启 Refiner 以优化细节。 |
| | | ControlNet(可选):如果你想要更精准控制画面(如手势、姿势),可以使用 ControlNet + OpenPose / Depth。 |
| | | Lora/Embeddings(可选):可以添加特定风格的 Lora 模型,如人物、材质增强等。 |
| | | ✅ 4. 最终固定的通用参数格式(每次只替换 Prompt) |
| | | 你最终可以这样调用 Stable Diffusion,每次只修改 Prompt,其他参数保持固定: |
| | | |
| | | yaml |
| | | 复制 |
| | | 编辑 |
| | | Prompt: "(这里填入 LLM 生成的描述)" |
| | | Negative Prompt: "(worst quality, low quality, blurry, bad anatomy, extra limbs, missing fingers, disfigured, lowres, overexposed, watermark, nsfw, text, cropped, distorted face, jpeg artifacts, poorly drawn hands, malformed fingers, unnatural body, bad proportions)" |
| | | Sampler: "DPM++ 2M Karras" |
| | | Steps: 40 |
| | | CFG Scale: 8 |
| | | Resolution: 1024x1024 |
| | | Seed: -1 |
| | | Hires Fix: True |
| | | Upscale: 1.5 |
| | | Batch Size: 2 |
| | | GOOGLE_STORY_GENERATE_PROMPT = ''' |
| | | 帮我写一篇的狗血故事,要求: |
| | | -以{who}的角色视角,讲述一段围绕{what}展开的狗血家庭故事; |
| | | -写作风格参考{style},狗血程度{level}; |
| | | -采用“第一人称”讲述,像是一个真实的人在吐槽自己的经历; |
| | | -以故事情节完整,情感抓人; |
| | | -有反转,有冲突,可以是搞笑的、虐的、荒谬的,也可以是真情流露; |
| | | -风格可以自由变化,比如幽默吐槽、狗血夸张、细腻感人、冷面讽刺; |
| | | -不必千篇一律,不必都是“婆媳大战”,只要精彩、有看头; |
| | | -内容不要重复之前写过的故事套路,尽量新颖、脑洞大开,像不同人亲身讲述的真实经历。 |
| | | -要让人觉得“这也能发生!?” |
| | | -让人看了就忍不住分享或评论。 |
| | | -回复中不要出现“好的,我知道了”、“以下是写的内容”等内容,直接就输出编写的故事本身。 |
| | | -回复中不需要故事的总结或下一步的任务推荐等,不需要任何引导、解释或寒暄。 |
| | | ''' |
| | | |
| | | |
| | | GOOGLE_STORY_GENERATE_PROMPT_COMPLEX = ''' |
| | | 请基于以下故事设定创作故事: |
| | | [故事设定] |
| | | 以{主角职业}的{主角性别}主角视角,讲述一段发生在{地点}的狗血家庭故事: |
| | | - 主角与过去的{前任身份}意外重逢,对方现为{现状描述}; |
| | | - 起因事件为:{初始事件}; |
| | | - 情节冲突核心:{冲突描述}; |
| | | - 故事中请融合以下狗血要素:{狗血要素}; |
| | | - 家庭结构设定:{家庭结构}; |
| | | - 第三人设定(若有):{第三人设定}; |
| | | - 角色心理动机:{心理动机}; |
| | | - 情感张力场设定:{张力设定}; |
| | | - 结局建议为{结局方向},可包含{反转类型}; |
| | | |
| | | [情节要求] |
| | | 如情节设定冲突或不合理,请灵活调整或舍弃部分内容,确保故事自然流畅且逻辑自洽。 |
| | | 1. 优先保证故事情节逻辑清晰,角色行为合理。 |
| | | 2. 故事需包含因果关系,情感真切,冲突有动机且铺垫合理。 |
| | | 3. 重点突出主要冲突和主题,辅助情节作为点缀,不做硬塞。 |
| | | 4. 故事应具备真实感和人性化,避免无厘头反转或硬凑剧情。 |
| | | |
| | | [写作要求] |
| | | - 写作风格要求为:{风格},字数建议为{字数}字左右。 |
| | | - 采用“第一人称”讲述,像是一个真实的人在吐槽自己的经历; |
| | | - 以故事情节完整、情感抓人为目标,有冲突和反转,风格多样,可幽默吐槽、狗血夸张、细腻感人或冷面讽刺等。 |
| | | - 故事内容应新颖多样,避免常见套路,展现丰富多彩的人物视角和情感冲突。 |
| | | - 请直接输出故事正文,避免任何开场白、总结或额外解释。 |
| | | - 有反转,有冲突,可以是搞笑的、虐的、荒谬的,也可以是真情流露; |
| | | - 风格可以自由变化,比如幽默吐槽、狗血夸张、细腻感人、冷面讽刺; |
| | | - 内容不要重复之前写过的故事套路,尽量新颖、脑洞大开,像不同人亲身讲述的真实经历。 |
| | | - 回复中不要出现“好的,我知道了”、“以下是写的内容”等内容,直接就输出编写的故事本身。 |
| | | - 回复中不需要故事的总结或下一步的任务推荐等,不需要任何引导、解释或寒暄。 |
| | | ''' |
| | |
| | | |
| | | DEFAULT_CDP_ENDPOINT = "http://localhost:9222" |
| | | |
| | | GONGZHONGHAO_CHECK_URL = "https://mp.weixin.qq.com/" |
| | | GONGZHONGHAO_LOGIN_ELEMENT = "div.weui-desktop_name" |
| | | |
| | | |
| | | PLATFORM_LOGIN_MAP= { |
| | | "bilibili":{ |
| | | "login_url":BILIBILI_CHECK_URL, |
| | |
| | | "login_url":XCOM_CHECK_URL, |
| | | "login_element":XCOM_LOGIN_ELEMENT, |
| | | "cdp_endpoint":DEFAULT_CDP_ENDPOINT |
| | | }, |
| | | "gongzhonghao":{ |
| | | "login_url":GONGZHONGHAO_CHECK_URL, |
| | | "login_element":GONGZHONGHAO_LOGIN_ELEMENT |
| | | } |
| | | } |
| | |
| | | |
| | | PROJECT_ROOT = "./" # 最终 程序是通过 cmd 启动的, 也就是最终是在 python main.py 或者 python app_flask.py 因此路径都是从 那个路径开始 |
| | | |
| | | VIDEO_DIR_DRAFT = PROJECT_ROOT + "data/video_draft" |
| | | VIDEO_DIR_DRAFT = PROJECT_ROOT + "data/media_draft" |
| | | |
| | | |
| | | |
| | | VIDEO_DIR = PROJECT_ROOT + "data/video_draft" |
| | | VIDEO_DIR = PROJECT_ROOT + "data/media_draft" |
| | | |
| | | FINAL_VIDEO_DIR = PROJECT_ROOT +"data/video_final" |
| | | FINAL_MEDIA_DIR = PROJECT_ROOT +"data/media_final" |
| | | |
| | | VIDEO_LOGO_PATH = PROJECT_ROOT +"data/video_draft/logo.png" |
| | | VIDEO_LOGO_PATH = PROJECT_ROOT +"data/media_draft/logo.png" |
| | | |
| | | VIDEO_FONT_PATH = PROJECT_ROOT + "data/fonts/HelloFont_ID_JiangHuTi.ttf" |
| | | |
| | |
| | | |
| | | TAIJINIAO_DIR_TEXT = PROJECT_ROOT + "data/taijiniao/texts" |
| | | TAIJINIAO_DIR_VIDEO_SRC = PROJECT_ROOT +"data/taijiniao/videos/竖屏" |
| | | TAIJINIAO_DIR_VIDEO_DST = PROJECT_ROOT +"data/video_final" |
| | | TAIJINIAO_DIR_VIDEO_DST = PROJECT_ROOT +"data/media_final" |
| | | TAIJINIAO_DIR_AUDIO = PROJECT_ROOT + "data/taijiniao/musics/children_happy_split" |
| | | TAIJINIAO_VIDEO_LOGO_PATH = PROJECT_ROOT + "data/taijiniao/logo.png" |
| | | TAIJINIAO_VIDEO_FONT_PATH = PROJECT_ROOT + "data/fonts/HelloFont_ID_JiangHuTi.ttf" |
| | |
| | | try: |
| | | proxy = {"server": f"http://{proxy_raw}"} |
| | | browser = await playwright.chromium.launch(headless=False, channel= "chrome",args=["--blink-settings=imagesEnabled=false"]) |
| | | context = await browser.new_context(proxy=proxy,user_agent=DEFAULT_USER_AGENT) |
| | | context = await browser.new_context(proxy=proxy,user_agent=DEFAULT_USER_AGENT,viewport={"width": 1920, "height": 1080}) |
| | | if os.path.exists(PLAYWRIGHT_STEALTH_JS_PATH): |
| | | await context.add_init_script(path=Path(PLAYWRIGHT_STEALTH_JS_PATH)) |
| | | page = await context.new_page() |
| New file |
| | |
| | | # -*- coding: utf-8 -*- |
| | | import os |
| | | import random |
| | | import subprocess |
| | | from pathlib import Path |
| | | from typing import List, Tuple |
| | | from concurrent.futures import ThreadPoolExecutor |
| | | from pydub import AudioSegment |
| | | import tempfile |
| | | import time |
| | | from datetime import datetime |
| | | import re |
| | | import json |
| | | import re |
| | | from glob import glob |
| | | |
| | | from auto_media_publisher.utils.logger import get_logger |
| | | from auto_media_publisher.config.conf_video_mashup import FINAL_MEDIA_DIR |
| | | |
| | | from auto_media_publisher.generators.media_generator_base import MediaGenerator |
| | | from auto_media_publisher.generators.docx_generator_gemini import DocxGeneratorGemini |
| | | |
| | | |
| | | class DocxGeneratorCreator(MediaGenerator): |
| | | """ |
| | | docx生成器类,用于AI生成docx,发布微信公众号。 |
| | | Attributes: |
| | | **kwargs : 其中包括 user_id,platform,proxy_full 和其他用得着addon 参数。 |
| | | 本类中,addon 参数是 docx_type 具体参考 conf_docx_random.py |
| | | """ |
| | | required_keys = ['user_id', 'scheduled_time','proxy_full'] |
| | | def __init__(self, *args, **kwargs): |
| | | if args: |
| | | raise TypeError("不支持位置参数,请全部使用关键字参数") |
| | | |
| | | for key in self.required_keys: |
| | | if key not in kwargs: |
| | | raise ValueError(f"缺少必要参数:{key}") |
| | | setattr(self, key, kwargs[key]) |
| | | |
| | | # 允许设置额外字段 |
| | | for key, value in kwargs.items(): |
| | | if key not in self.required_keys: |
| | | setattr(self, key, value) |
| | | |
| | | self.logger = get_logger(self.__class__.__name__,"admin") |
| | | |
| | | |
| | | def generate(self): |
| | | """ |
| | | 被外部调用。 |
| | | 生成一个docx ; |
| | | 生成一个png封面; |
| | | 生成一个docx的配置json文件; |
| | | 三个文件都 保存到 media_final / user_id / 下面 |
| | | |
| | | """ |
| | | try: |
| | | tmp_datetime = datetime.strptime(self.scheduled_time, "%Y-%m-%d %H:%M:%S") |
| | | scheduled_time_str = tmp_datetime.strftime("%Y%m%d%H%M%S") |
| | | self.logger.info(f"DocxGeneratorCreator 正在生成 media:{self.user_id},{self.scheduled_time} .docx") |
| | | |
| | | os.makedirs(os.path.join(FINAL_MEDIA_DIR,self.user_id),exist_ok=True) |
| | | output_docx_path =f"{FINAL_MEDIA_DIR}/{self.user_id}/{scheduled_time_str}.docx" |
| | | output_json_path = f"{FINAL_MEDIA_DIR}/{self.user_id}/{scheduled_time_str}.json" |
| | | |
| | | # 针对不同的平台,如果配置了相同的发布时间,默认是使用同一个视频。 |
| | | # 如果某个用户在不同的平台上,需要展示不同的内容,要 人为 地 设置最终发布时间是不同的时间。 |
| | | |
| | | if os.path.exists(output_json_path): |
| | | self.logger.info(f"DocxGeneratorCreator 文件已存在,不再执行生成任务 media:{output_json_path}") |
| | | return True |
| | | |
| | | generater = DocxGeneratorGemini(self.docx_author,complex=True) |
| | | generater.generate(output_docx_path) |
| | | |
| | | summary_json = generater.summary_info |
| | | summary_json["user"] = self.user_id |
| | | summary_json["scheduled_time"] = self.scheduled_time |
| | | summary_json["proxy_full"] = self.proxy_full |
| | | summary_json["path_media"] = output_docx_path |
| | | summary_json["author"] = self.docx_author |
| | | |
| | | |
| | | # 3. 写入磁盘 |
| | | with open(output_json_path.replace(".docx",".json"), "w", encoding="utf-8") as f: |
| | | json.dump(summary_json, f, ensure_ascii=False, indent=4) |
| | | |
| | | time.sleep(5) |
| | | return True |
| | | except Exception as e: |
| | | self.logger.error(f"DocxGeneratorCreator error: {e}") |
| | | return False |
| | | |
| New file |
| | |
| | | from docx import Document |
| | | from docx.shared import Pt, Inches |
| | | from docx.oxml.ns import qn |
| | | from io import BytesIO |
| | | from docx.enum.text import WD_ALIGN_PARAGRAPH |
| | | import random |
| | | import threading |
| | | import re |
| | | import time |
| | | from io import BytesIO |
| | | import google.generativeai as genai |
| | | from auto_media_publisher.config.conf_base import GOOGLE_API_KEY,GOOGLE_MODEL,GOOGLE_CHAT_MIN_INTERVAL,DEFAULT_PREFIX_MAP,DEFAULT_SURFIX_MAP |
| | | from auto_media_publisher.config.conf_base import GOOGLE_GEMINI_TEMPERATURE_MIN,GOOGLE_GEMINI_TEMPERATURE_MAX,GOOGLE_GEMINI_TOPN_MIN,GOOGLE_GEMINI_TOPN_MAX |
| | | from auto_media_publisher.config.conf_base import GEMINI_PROMPT_TITLE,GEMINI_PROMPT_DESCRIPTION,GEMINI_PROMPT_TAG,GOOGLE_STORY_GENERATE_PROMPT,GOOGLE_STORY_GENERATE_PROMPT_COMPLEX |
| | | from auto_media_publisher.config.conf_docx_generate import STORY_PROMPT_PARAMETERS |
| | | from auto_media_publisher.config.conf_docx_generate_complex import STORY_PROMPT_PARAMETERS_COMPLEX |
| | | |
| | | from auto_media_publisher.utils.logger import get_logger |
| | | from auto_media_publisher.utils.utils_text2image_pollinations import Text2ImageGenerator |
| | | |
| | | |
| | | class DocxGeneratorGemini: |
| | | def __init__(self,docx_author="我",complex=False): |
| | | genai.configure(api_key=GOOGLE_API_KEY) |
| | | self.temperature = round(random.uniform(GOOGLE_GEMINI_TEMPERATURE_MIN, GOOGLE_GEMINI_TEMPERATURE_MAX), 2) |
| | | self.top_n = round(random.uniform(GOOGLE_GEMINI_TOPN_MIN, GOOGLE_GEMINI_TOPN_MAX), 2) |
| | | self.model = genai.GenerativeModel(GOOGLE_MODEL, |
| | | generation_config=genai.types.GenerationConfig( |
| | | temperature=self.temperature, |
| | | top_p=self.top_n, |
| | | top_k=random.choice([40, 50, 80, 100]) |
| | | ) |
| | | ) |
| | | self.prefix_text = f"我是{docx_author},{random.choice(DEFAULT_PREFIX_MAP)}" |
| | | self.surfix_text = random.choice(DEFAULT_SURFIX_MAP) |
| | | |
| | | |
| | | self.last_call_time = 0 |
| | | self.min_interval = GOOGLE_CHAT_MIN_INTERVAL # 限制最短请求间隔(秒) |
| | | self.lock = threading.Lock() # 多线程并发时也安全 |
| | | self.logger = get_logger(self.__class__.__name__,"admin") |
| | | self.text2imager = Text2ImageGenerator(width=900,height=383) |
| | | |
| | | self.summary_info = {} |
| | | |
| | | if complex : |
| | | self.prompt = self.get_story_prompt_complex() |
| | | else: |
| | | self.prompt = self.get_story_prompt() |
| | | |
| | | def safe_send_message(self, content: str): |
| | | with self.lock: |
| | | now = time.time() |
| | | wait_time = self.min_interval - (now - self.last_call_time) |
| | | if wait_time > 0: |
| | | time.sleep(wait_time) |
| | | self.last_call_time = time.time() |
| | | |
| | | return self.chat.send_message(content) |
| | | |
| | | def get_story_prompt(self) -> str: |
| | | who = random.choice(STORY_PROMPT_PARAMETERS["who"]) |
| | | what = random.choice(STORY_PROMPT_PARAMETERS["what"]) |
| | | style = ",".join(random.sample(STORY_PROMPT_PARAMETERS["style"], 2)) |
| | | level = random.choice(STORY_PROMPT_PARAMETERS["level"]) |
| | | |
| | | return GOOGLE_STORY_GENERATE_PROMPT.format(who=who,what=what,style=style,level=level) |
| | | |
| | | def get_story_prompt_complex(self) -> str: |
| | | |
| | | params = {key: random.choice(values) for key, values in STORY_PROMPT_PARAMETERS_COMPLEX.items()} |
| | | |
| | | return GOOGLE_STORY_GENERATE_PROMPT_COMPLEX.format(**params) |
| | | |
| | | |
| | | def generate(self, output_path: str): |
| | | self.logger.info(f"start to rewriting docx using gemini,using temperature:{self.temperature}. with prompt {self.prompt}.") |
| | | self.chat = self.model.start_chat(history=[]) |
| | | response = self.safe_send_message(self.prompt) |
| | | story_text = response.text.strip() |
| | | self.logger.info(f"google gemini story end...") |
| | | paragraphs = [p.strip() for p in story_text.split('\n') if p.strip()] |
| | | |
| | | doc = Document() |
| | | # 设置默认样式 |
| | | style = doc.styles['Normal'] |
| | | font = style.font |
| | | font.name = '楷体' # 西文字体设置为楷体 |
| | | font.size = Pt(10.5) # 小四字体 |
| | | style._element.rPr.rFonts.set(qn('w:eastAsia'), '楷体') # 中文字体设定 |
| | | |
| | | self._add_content_to_doc(doc,"text",f"{self.prefix_text}\n") |
| | | |
| | | for para in paragraphs : |
| | | self._add_content_to_doc(doc,"text",para) |
| | | if random.random() > 0.5: |
| | | try: |
| | | img_stream = self.text2imager.generate_image_to_stream(para) |
| | | self._add_content_to_doc(doc,"image",img_stream) |
| | | except: |
| | | pass |
| | | |
| | | self._add_content_to_doc(doc,"text",f"\n\n{self.surfix_text}") |
| | | |
| | | doc.save(output_path) |
| | | |
| | | self.summary_info = self._summarize_title_intro_keywords() |
| | | print(self.summary_info) |
| | | self.text2imager.generate_image(self.summary_info["description"],output_path.replace(".docx",".png")) |
| | | self.summary_info["path_cover"] = output_path.replace(".docx",".png") |
| | | |
| | | |
| | | def _add_content_to_doc(self,doc,type,block_content): |
| | | if type =="text": |
| | | for line in block_content.split("\n"): |
| | | para = doc.add_paragraph(line.strip()) |
| | | para.paragraph_format.line_spacing = 1.5 # 行距1.5倍 |
| | | para.paragraph_format.space_before = Pt(5) # 段前0磅 |
| | | para.paragraph_format.space_after = Pt(5) # 段后0磅 |
| | | elif type == "image": |
| | | paragraph = doc.add_paragraph() |
| | | run = paragraph.add_run() |
| | | run.add_picture(block_content, width=Inches(5.5)) |
| | | paragraph.paragraph_format.space_before = Pt(12) # 段前 12pt |
| | | paragraph.paragraph_format.space_after = Pt(12) # 段后 12pt |
| | | paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER |
| | | |
| | | return doc |
| | | |
| | | |
| | | |
| | | def _save_to_new_docx(self, blocks, output_path): |
| | | doc = Document() |
| | | # 设置默认样式 |
| | | style = doc.styles['Normal'] |
| | | font = style.font |
| | | font.name = '楷体' # 西文字体设置为楷体 |
| | | font.size = Pt(10.5) # 小四字体 |
| | | style._element.rPr.rFonts.set(qn('w:eastAsia'), '楷体') # 中文字体设定 |
| | | |
| | | # 前言 |
| | | para = doc.add_paragraph(self.prefix_text) |
| | | para.paragraph_format.line_spacing = 1.5 |
| | | para.paragraph_format.space_before = Pt(0) |
| | | para.paragraph_format.space_after = Pt(0) |
| | | |
| | | |
| | | for block in blocks: |
| | | if block["type"] == "text": |
| | | for line in block["content"].split("\n"): |
| | | para = doc.add_paragraph(line.strip()) |
| | | para.paragraph_format.line_spacing = 1.5 # 行距1.5倍 |
| | | para.paragraph_format.space_before = Pt(0) # 段前0磅 |
| | | para.paragraph_format.space_after = Pt(0) # 段后0磅 |
| | | elif block["type"] == "image": |
| | | image_data = block["content"] |
| | | image_stream = BytesIO(image_data) |
| | | paragraph = doc.add_paragraph() |
| | | run = paragraph.add_run() |
| | | run.add_picture(image_stream, width=Inches(5.5)) |
| | | paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER |
| | | |
| | | |
| | | # 结语 |
| | | para2 = doc.add_paragraph(self.surfix_text) |
| | | para2.paragraph_format.line_spacing = 1.5 |
| | | para2.paragraph_format.space_before = Pt(12) |
| | | para2.paragraph_format.space_after = Pt(0) |
| | | |
| | | doc.save(output_path) |
| | | |
| | | |
| | | def _summarize_title_intro_keywords(self) -> dict: |
| | | title = self.safe_send_message(GEMINI_PROMPT_TITLE).text.strip() |
| | | description = self.safe_send_message(GEMINI_PROMPT_DESCRIPTION).text.strip() |
| | | keywords = self.safe_send_message(GEMINI_PROMPT_TAG).text.strip() |
| | | |
| | | return { |
| | | "title": title.splitlines()[0].strip()[:64], |
| | | "description": description[:120], |
| | | "tags": re.split(r'[、,\s]+', keywords.strip("。")) |
| | | } |
| | | |
| New file |
| | |
| | | # -*- coding: utf-8 -*- |
| | | import os |
| | | import random |
| | | import subprocess |
| | | from pathlib import Path |
| | | from typing import List, Tuple |
| | | from concurrent.futures import ThreadPoolExecutor |
| | | from pydub import AudioSegment |
| | | import tempfile |
| | | import time |
| | | from datetime import datetime |
| | | import re |
| | | import json |
| | | import re |
| | | from glob import glob |
| | | |
| | | from auto_media_publisher.utils.logger import get_logger |
| | | from auto_media_publisher.config.conf_video_mashup import FINAL_MEDIA_DIR |
| | | |
| | | from auto_media_publisher.generators.media_generator_base import MediaGenerator |
| | | from auto_media_publisher.modifiers.rewriter.docx_rewriter_gemini import DocxRewriterGemini |
| | | |
| | | |
| | | class DocxGeneratorRewriter(MediaGenerator): |
| | | """ |
| | | docx生成器类,用于根据参数改写并创建docx,发布微信公众号。 |
| | | Attributes: |
| | | **kwargs : 其中包括 user_id,platform,proxy_full 和其他用得着addon 参数。 |
| | | 本类中,addon 参数是 docx_type 具体参考 conf_docx_random.py |
| | | """ |
| | | required_keys = ['user_id', 'scheduled_time','proxy_full'] |
| | | def __init__(self, *args, **kwargs): |
| | | if args: |
| | | raise TypeError("不支持位置参数,请全部使用关键字参数") |
| | | |
| | | for key in self.required_keys: |
| | | if key not in kwargs: |
| | | raise ValueError(f"缺少必要参数:{key}") |
| | | setattr(self, key, kwargs[key]) |
| | | |
| | | # 允许设置额外字段 |
| | | for key, value in kwargs.items(): |
| | | if key not in self.required_keys: |
| | | setattr(self, key, value) |
| | | |
| | | self.logger = get_logger(self.__class__.__name__,"admin") |
| | | |
| | | |
| | | def get_random_docx_file(self) -> str: |
| | | """ |
| | | 递归 获取目录下所有的*.docx 文件, 随机选取一个 |
| | | Attributes: |
| | | docx_dir : 顶级目录 |
| | | """ |
| | | all_docx = glob(f"{self.docx_dir}/**/*.docx", recursive=True) |
| | | return random.choice(all_docx) |
| | | |
| | | |
| | | def generate(self): |
| | | """ |
| | | 被外部调用。 |
| | | 生成一个docx ; |
| | | 生成一个png封面; |
| | | 生成一个docx的配置json文件; |
| | | 三个文件都 保存到 media_final / user_id / 下面 |
| | | |
| | | """ # from 2025-07-19 08:00:00 to 2025-07-19 08:00 |
| | | try: |
| | | tmp_datetime = datetime.strptime(self.scheduled_time, "%Y-%m-%d %H:%M:%S") |
| | | scheduled_time_str = tmp_datetime.strftime("%Y%m%d%H%M%S") |
| | | self.logger.info(f"DocxGeneratorRewriter 正在改写 media:{self.user_id},{self.scheduled_time} .docx") |
| | | |
| | | os.makedirs(os.path.join(FINAL_MEDIA_DIR,self.user_id),exist_ok=True) |
| | | output_docx_path =f"{FINAL_MEDIA_DIR}/{self.user_id}/{scheduled_time_str}.docx" |
| | | output_json_path = f"{FINAL_MEDIA_DIR}/{self.user_id}/{scheduled_time_str}.json" |
| | | |
| | | # 针对不同的平台,如果配置了相同的发布时间,默认是使用同一个视频。 |
| | | # 如果某个用户在不同的平台上,需要展示不同的内容,要 人为 地 设置最终发布时间是不同的时间。 |
| | | |
| | | if os.path.exists(output_json_path): |
| | | return True |
| | | |
| | | input_docx = self.get_random_docx_file() |
| | | |
| | | rewritor = DocxRewriterGemini("random",self.docx_author) |
| | | rewritor.rewrite(input_docx,output_docx_path) |
| | | |
| | | summary_json = rewritor.summary_info |
| | | summary_json["user"] = self.user_id |
| | | summary_json["scheduled_time"] = self.scheduled_time |
| | | summary_json["proxy_full"] = self.proxy_full |
| | | summary_json["path_media"] = output_docx_path |
| | | summary_json["author"] = self.docx_author |
| | | |
| | | |
| | | # 3. 写入磁盘 |
| | | with open(output_json_path.replace(".docx",".json"), "w", encoding="utf-8") as f: |
| | | json.dump(summary_json, f, ensure_ascii=False, indent=4) |
| | | |
| | | time.sleep(5) |
| | | return True |
| | | except Exception as e: |
| | | self.logger.error(f"DocxGeneratorRewriter error: {e}") |
| | | return False |
| | | |
| | |
| | | 生成一个短视频mp4; |
| | | 生成一个png封面; |
| | | 生成一个视频的配置json文件; |
| | | 三个文件都 保存到 video_final / user_id / 下面 |
| | | 三个文件都 保存到 media_final / user_id / 下面 |
| | | |
| | | """ # from 2025-07-19 08:00:00 to 2025-07-19 08:00 |
| | | try: |
| | |
| | | "user": self.user_id, |
| | | "title": "", |
| | | "description": text_line, |
| | | "path_video": output_mp4_path, |
| | | "path_media": output_mp4_path, |
| | | "tags": ["感恩相遇","再来一个","太好看了"], |
| | | "publish_datetime": scheduled_time_pub, |
| | | "scheduled_time": scheduled_time_pub, |
| | | "location": "", |
| | | "category": "", |
| | | "path_cover": output_png_path, |
| | |
| | | |
| | | class VideoGeneratorManual(MediaGenerator): |
| | | """ |
| | | 手动地生成短视频,拷贝到 video_final / user_id / 目录下 之后。 |
| | | 手动地生成短视频,拷贝到 media_final / user_id / 目录下 之后。 |
| | | 要求: |
| | | 1、每个视频要有三个文件: |
| | | mp4 文件、 png封面文件和json配置文件(可参考其他json)。 |
| | |
| | | import re |
| | | |
| | | from auto_media_publisher.utils.logger import get_logger |
| | | from auto_media_publisher.config.conf_video_mashup import VIDEO_DIR,FINAL_VIDEO_DIR,VIDEO_LOGO_PATH,VIDEO_SEGMENT_COUNT,VIDEO_SEGMENT_DURATION,VIDEO_RESOLUTION_DEFAULT_WIDTH,VIDEO_RESOLUTION_DEFAULT_HEIGHT,VIDEO_FONT_PATH,VIDEO_FONT_SIZE,VIDEO_FONT_COLOR |
| | | from auto_media_publisher.config.conf_video_mashup import VIDEO_DIR,FINAL_MEDIA_DIR,VIDEO_LOGO_PATH,VIDEO_SEGMENT_COUNT,VIDEO_SEGMENT_DURATION,VIDEO_RESOLUTION_DEFAULT_WIDTH,VIDEO_RESOLUTION_DEFAULT_HEIGHT,VIDEO_FONT_PATH,VIDEO_FONT_SIZE,VIDEO_FONT_COLOR |
| | | |
| | | from auto_media_publisher.generators.media_generator_base import MediaGenerator |
| | | |
| | |
| | | 生成一个短视频mp4; |
| | | 生成一个png封面; |
| | | 生成一个视频的配置json文件; |
| | | 三个文件都 保存到 video_final / user_id / 下面 |
| | | 三个文件都 保存到 media_final / user_id / 下面 |
| | | |
| | | """ # from 2025-07-19 08:00:00 to 2025-07-19 08:00 |
| | | try: |
| | |
| | | scheduled_time_pub = tmp_datetime.strftime("%Y-%m-%d %H:%M") |
| | | self.logger.info(f"VideoGeneratorMashup 正在生成 media:{self.user_id},{self.scheduled_time} .mp4") |
| | | |
| | | os.makedirs(os.path.join(FINAL_VIDEO_DIR,self.user_id),exist_ok=True) |
| | | output_mp4_path =f"{FINAL_VIDEO_DIR}/{self.user_id}/{scheduled_time_str}.mp4" |
| | | output_png_path =f"{FINAL_VIDEO_DIR}/{self.user_id}/{scheduled_time_str}.png" |
| | | output_json_path = f"{FINAL_VIDEO_DIR}/{self.user_id}/{scheduled_time_str}.json" |
| | | os.makedirs(os.path.join(FINAL_MEDIA_DIR,self.user_id),exist_ok=True) |
| | | output_mp4_path =f"{FINAL_MEDIA_DIR}/{self.user_id}/{scheduled_time_str}.mp4" |
| | | output_png_path =f"{FINAL_MEDIA_DIR}/{self.user_id}/{scheduled_time_str}.png" |
| | | output_json_path = f"{FINAL_MEDIA_DIR}/{self.user_id}/{scheduled_time_str}.json" |
| | | |
| | | # 针对不同的平台,如果配置了相同的发布时间,默认是使用同一个视频。 |
| | | # 如果某个用户在不同的平台上,需要展示不同的内容,要 人为 地 设置最终发布时间是不同的时间。 |
| | |
| | | "user": self.user_id, |
| | | "title": "", |
| | | "description": text_line, |
| | | "path_video": output_mp4_path, |
| | | "path_media": output_mp4_path, |
| | | "tags": ["感恩相遇","再来一个","太好看了"], |
| | | "publish_datetime": scheduled_time_pub, |
| | | "scheduled_time": scheduled_time_pub, |
| | | "location": "", |
| | | "category": "", |
| | | "path_cover": output_png_path, |
| | |
| | | "user": self.user_id, |
| | | "title": "太极鸟体适能", |
| | | "description": text_line, |
| | | "path_video": output_mp4_path, |
| | | "path_media": output_mp4_path, |
| | | "tags": ["太极鸟","太极鸟体适能","基础运动技能"], |
| | | "publish_datetime": scheduled_time_pub, |
| | | "scheduled_time": scheduled_time_pub, |
| | | "location": "上海城创金融科技国际产业园", |
| | | "category": "健身", |
| | | "path_cover": output_png_path, |
| | |
| | | from docx import Document |
| | | from docx.shared import Inches |
| | | from docx.enum.text import WD_ALIGN_PARAGRAPH |
| | | from docx.shared import Pt, Inches |
| | | from docx.oxml.ns import qn |
| | | from io import BytesIO |
| | | from docx.enum.text import WD_ALIGN_PARAGRAPH |
| | | import random |
| | | import threading |
| | | import re |
| | |
| | | from io import BytesIO |
| | | from PIL import Image |
| | | import google.generativeai as genai |
| | | from auto_media_publisher.config.conf_base import GOOGLE_API_KEY,GOOGLE_MODEL,GOOGLE_CHAT_MIN_INTERVAL |
| | | from auto_media_publisher.config.conf_base import GOOGLE_GEMINI_TEMPERATURE_MIN,GOOGLE_GEMINI_TEMPERATURE_MAX,GOOGLE_REWRITE_STYLE_MAP,GEMINI_PROMPT_INIT_DEFAULT |
| | | from auto_media_publisher.config.conf_base import GOOGLE_API_KEY,GOOGLE_MODEL,GOOGLE_CHAT_MIN_INTERVAL,DEFAULT_PREFIX_MAP,DEFAULT_SURFIX_MAP |
| | | from auto_media_publisher.config.conf_base import GOOGLE_GEMINI_TEMPERATURE_MIN,GOOGLE_GEMINI_TEMPERATURE_MAX,GOOGLE_GEMINI_TOPN_MIN,GOOGLE_GEMINI_TOPN_MAX,GOOGLE_REWRITE_STYLE_MAP,GEMINI_PROMPT_INIT_DEFAULT |
| | | from auto_media_publisher.config.conf_base import GEMINI_PROMPT_TITLE,GEMINI_PROMPT_DESCRIPTION,GEMINI_PROMPT_TAG |
| | | from auto_media_publisher.utils.logger import get_logger |
| | | from auto_media_publisher.utils.utils_text2image_pollinations import Text2ImageGenerator |
| | | |
| | | class GeminiDocxRewriter: |
| | | def __init__(self,rewrite_style="default" ): |
| | | |
| | | class DocxRewriterGemini: |
| | | def __init__(self,rewrite_style="default" ,docx_author="我"): |
| | | genai.configure(api_key=GOOGLE_API_KEY) |
| | | self.temperature = round(random.uniform(GOOGLE_GEMINI_TEMPERATURE_MIN, GOOGLE_GEMINI_TEMPERATURE_MAX), 2) |
| | | self.top_n = round(random.uniform(GOOGLE_GEMINI_TOPN_MIN, GOOGLE_GEMINI_TOPN_MAX), 2) |
| | | self.model = genai.GenerativeModel(GOOGLE_MODEL, |
| | | generation_config=genai.types.GenerationConfig( |
| | | temperature=self.temperature, |
| | | top_p=1.0 |
| | | top_p=self.top_n, |
| | | top_k=random.choice([40, 50, 80, 100]) |
| | | ) |
| | | ) |
| | | if rewrite_style =="random": |
| | |
| | | else: |
| | | self.rewrite_style = rewrite_style |
| | | |
| | | self.prefix_text = f"我是{docx_author},{random.choice(DEFAULT_PREFIX_MAP)}" |
| | | self.surfix_text = random.choice(DEFAULT_SURFIX_MAP) |
| | | |
| | | self.last_call_time = 0 |
| | | self.min_interval = GOOGLE_CHAT_MIN_INTERVAL # 限制最短请求间隔(秒) |
| | | self.lock = threading.Lock() # 多线程并发时也安全 |
| | | self.logger = get_logger(self.__class__.__name__,"admin") |
| | | self.text2imager = Text2ImageGenerator() |
| | | self.text2imager = Text2ImageGenerator(width=900,height=383) |
| | | |
| | | self.summary_info = {} |
| | | |
| | | #@retry(stop=stop_after_attempt(3), wait=wait_fixed(2)) # 自动重试机制 |
| | | def safe_send_message(self, content: str): |
| | |
| | | rewritten = self._rewrite_blocks(blocks) |
| | | self._save_to_new_docx(rewritten, output_path) |
| | | |
| | | summary_info = self.summarize_title_intro_keywords() |
| | | print(summary_info) |
| | | self.text2imager.generate_image(summary_info["summary"],output_path.replace(".docx",".jpg")) |
| | | summary_info["cover_image"] = output_path.replace(".docx",".jpg") |
| | | self.summary_info = self._summarize_title_intro_keywords() |
| | | print(self.summary_info) |
| | | self.text2imager.generate_image(self.summary_info["description"],output_path.replace(".docx",".png")) |
| | | self.summary_info["path_cover"] = output_path.replace(".docx",".png") |
| | | |
| | | # 3. 写入磁盘 |
| | | with open(output_path.replace(".docx",".json"), "w", encoding="utf-8") as f: |
| | | json.dump(summary_info, f, ensure_ascii=False, indent=4) |
| | | |
| | | return summary_info |
| | | |
| | | def extract_docx_blocks_by_order(self,docx_path): |
| | | doc = Document(docx_path) |
| | |
| | | |
| | | def _save_to_new_docx(self, blocks, output_path): |
| | | doc = Document() |
| | | # 设置默认样式 |
| | | style = doc.styles['Normal'] |
| | | font = style.font |
| | | font.name = '楷体' # 西文字体设置为楷体 |
| | | font.size = Pt(10.5) # 小四字体 |
| | | style._element.rPr.rFonts.set(qn('w:eastAsia'), '楷体') # 中文字体设定 |
| | | |
| | | # 前言 |
| | | para = doc.add_paragraph(self.prefix_text) |
| | | para.paragraph_format.line_spacing = 1.5 |
| | | para.paragraph_format.space_before = Pt(0) |
| | | para.paragraph_format.space_after = Pt(0) |
| | | |
| | | |
| | | for block in blocks: |
| | | if block["type"]=="text": |
| | | if block["type"] == "text": |
| | | for line in block["content"].split("\n"): |
| | | doc.add_paragraph(line.strip()) |
| | | para = doc.add_paragraph(line.strip()) |
| | | para.paragraph_format.line_spacing = 1.5 # 行距1.5倍 |
| | | para.paragraph_format.space_before = Pt(0) # 段前0磅 |
| | | para.paragraph_format.space_after = Pt(0) # 段后0磅 |
| | | elif block["type"] == "image": |
| | | image_data = block["content"] |
| | | image_stream = BytesIO(image_data) |
| | | paragraph = doc.add_paragraph() |
| | | run = paragraph.add_run() |
| | | run.add_picture(image_stream, width=Inches(5.5)) # 适当调整宽度 |
| | | run.add_picture(image_stream, width=Inches(5.5)) |
| | | paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER |
| | | |
| | | doc.save(output_path) |
| | | |
| | | # 结语 |
| | | para2 = doc.add_paragraph(self.surfix_text) |
| | | para2.paragraph_format.line_spacing = 1.5 |
| | | para2.paragraph_format.space_before = Pt(12) |
| | | para2.paragraph_format.space_after = Pt(0) |
| | | |
| | | def summarize_title_intro_keywords(self) -> dict: |
| | | doc.save(output_path) |
| | | |
| | | |
| | | def _summarize_title_intro_keywords(self) -> dict: |
| | | title = self.safe_send_message(GEMINI_PROMPT_TITLE).text.strip() |
| | | summary = self.safe_send_message(GEMINI_PROMPT_DESCRIPTION).text.strip() |
| | | description = self.safe_send_message(GEMINI_PROMPT_DESCRIPTION).text.strip() |
| | | keywords = self.safe_send_message(GEMINI_PROMPT_TAG).text.strip() |
| | | |
| | | return { |
| | | "title": title, |
| | | "summary": summary, |
| | | "keywords": re.split(r'[、,\s]+', keywords.strip("。")) |
| | | "title": title.splitlines()[0].strip()[:64], |
| | | "description": description[:120], |
| | | "tags": re.split(r'[、,\s]+', keywords.strip("。")) |
| | | } |
| | | |
| | |
| | | browser_args["proxy"] = {"server": self.proxy} |
| | | self.browser = await playwright.chromium.launch(**browser_args) |
| | | if os.path.exists(self.cookie_path): |
| | | self.context = await self.browser.new_context(storage_state=f"{self.cookie_path}", user_agent=DEFAULT_USER_AGENT) |
| | | self.context = await self.browser.new_context(storage_state=f"{self.cookie_path}", user_agent=DEFAULT_USER_AGENT,viewport={"width": 1920, "height": 1080}) |
| | | else: |
| | | self.context = await self.browser.new_context(user_agent=DEFAULT_USER_AGENT) |
| | | self.context = await self.browser.new_context(user_agent=DEFAULT_USER_AGENT,viewport={"width": 1920, "height": 1080}) |
| | | if os.path.exists(PLAYWRIGHT_STEALTH_JS_PATH): |
| | | await self.context.add_init_script(path=Path(PLAYWRIGHT_STEALTH_JS_PATH)) |
| | | await self.context.grant_permissions(['geolocation']) |
| | |
| | | # -*- coding: utf-8 -*- |
| | | from playwright.async_api import Playwright, Page |
| | | import asyncio |
| | | import random |
| | | import datetime |
| | | |
| | | from auto_media_publisher.uploaders.uploader_base import UploaderBase |
| | | |
| | |
| | | |
| | | |
| | | class UploaderBaijiahao(UploaderBase): |
| | | |
| | | |
| | | |
| | | async def virtual_scroll_select(self,page,text, wrapper_index = 0,panel_selector="div.rc-virtual-list-holder-inner", |
| | | item_selector_template='div.cheetah-select-item-option-content:has-text("{text}")', |
| | | step=200, # 每次滚动像素 |
| | | max_attempts=15, |
| | | direction="down" # "down" 或 "up" |
| | | ): |
| | | await page.locator('div.select-wrap').nth(wrapper_index).click() |
| | | await asyncio.sleep(1) |
| | | |
| | | panel = page.locator(panel_selector).nth(wrapper_index) |
| | | item_selector = item_selector_template.format(text=text) |
| | | |
| | | |
| | | for i in range(max_attempts): |
| | | # 尝试查找 |
| | | items = page.locator(item_selector) |
| | | if await items.count() > 0: |
| | | # 找到了,滚下去保证可见,再点击 |
| | | await items.first.scroll_into_view_if_needed() |
| | | await items.first.click() |
| | | return |
| | | |
| | | # 没找到就滚一轮 |
| | | delta = step if direction == "down" else -step |
| | | await panel.evaluate(f"(el) => el.scrollTop += {delta}") |
| | | await asyncio.sleep(0.2) |
| | | await asyncio.sleep(1) |
| | | |
| | | |
| | | async def set_schedule_time(self, page): |
| | | """ |
| | | TODO 时间选择,日后在处理 百家号的时间选择不准确,目前是随机 |
| | | """ |
| | | publish_datetime_day = f"{self.publish_datetime.month}月{self.publish_datetime.day}日" if self.publish_datetime.day >9 else f"{self.publish_datetime.month}月0{self.publish_datetime.day}日" |
| | | publish_datetime_hour = f"{self.publish_datetime.hour}点" |
| | | publish_datetime_min = f"{self.publish_datetime.minute}分" |
| | | scheduled_time_day = f"{self.scheduled_time.month}月{self.scheduled_time.day}日" if self.scheduled_time.day >9 else f"{self.scheduled_time.month}月0{self.scheduled_time.day}日" |
| | | scheduled_time_hour = f"{self.scheduled_time.hour}点" |
| | | scheduled_time_min = f"{self.scheduled_time.minute}分" |
| | | await page.locator("div.cheetah-modal-confirm-body-wrapper").wait_for(state='visible',timeout=30000) |
| | | |
| | | current_hour = datetime.datetime.now().hour |
| | | current_min = datetime.datetime.now().minute |
| | | direction_hour = "down" if self.scheduled_time.hour > current_hour else "up" |
| | | direction_minute = "down" if self.scheduled_time.minute > current_min else "up" |
| | | |
| | | print(direction_hour) |
| | | print(dir) |
| | | |
| | | |
| | | try: |
| | | await page.locator('div.select-wrap').nth(0).click() |
| | | await asyncio.sleep(1) |
| | | target = page.locator(f'div[title="{publish_datetime_day}"]') |
| | | await target.wait_for(state='visible') |
| | | target = page.locator(f'div[title="{scheduled_time_day}"]') |
| | | #await target.wait_for(state='visible') |
| | | await target.click() |
| | | await asyncio.sleep(1) |
| | | await page.locator('div.select-wrap').nth(1).click() |
| | | await asyncio.sleep(1) |
| | | target = page.locator(f'div.cheetah-select-item-option-content:has-text("{publish_datetime_hour}")') |
| | | await target.wait_for(state='visible') |
| | | await target.click() |
| | | await asyncio.sleep(1) |
| | | await page.locator('div.select-wrap').nth(2).click() |
| | | await asyncio.sleep(1) |
| | | target = page.locator(f'div.cheetah-select-item-option-content:has-text("{publish_datetime_min}")') |
| | | await target.wait_for(state='visible') |
| | | await target.click() |
| | | await asyncio.sleep(1) |
| | | await self.virtual_scroll_select(page,scheduled_time_hour,wrapper_index=1,direction=direction_hour) |
| | | await self.virtual_scroll_select(page,scheduled_time_min,wrapper_index=2,direction=direction_minute) |
| | | #await page.locator('div.select-wrap').nth(2).click() |
| | | #await asyncio.sleep(1) |
| | | #target = page.locator(f'div.cheetah-select-item-option-content:has-text("{scheduled_time_min}")') |
| | | #await target.wait_for(state='visible') |
| | | #await target.scroll_into_view_if_needed() |
| | | #await target.click() |
| | | #await asyncio.sleep(1) |
| | | |
| | | except Exception as e: |
| | | self.logger.error(f"[Baidu BaiJiaHao] 设置时间发生错误.{e}") |
| | | |
| | | await page.locator("div.cheetah-modal-confirm-btns > button").nth(1).click() |
| | | #await page.locator("div.cheetah-modal-confirm-btns > button").nth(1).click() |
| | | |
| | | async def handle_upload_error(self, page): |
| | | # 日后实现,目前没遇到 |
| | |
| | | raise # 重新抛出异常,让重试装饰器捕获 |
| | | |
| | | async def publish_video(self, page: Page): |
| | | if self.publish_datetime != 0: |
| | | if self.scheduled_time != 0: |
| | | # 定时发布 |
| | | await self.set_schedule_publish(page) |
| | | else: |
| | |
| | | |
| | | page = await self.context.new_page() |
| | | await page.goto(CONTENT_UPLOAD_URL, timeout=120000) |
| | | self.logger.info(f"正在上传-------{self.path_video}") |
| | | self.logger.info(f"正在上传-------{self.path_media}") |
| | | await page.wait_for_url(CONTENT_UPLOAD_URL, timeout=120000) |
| | | |
| | | # 点击 "上传视频" 按钮 |
| | | await page.locator("div[class^='video-main-page'] input").set_input_files(self.path_video) |
| | | upload_div = page.locator(".PL3VsCg3MxIPY5UYiCS_") |
| | | await upload_div.wait_for(state="visible", timeout=10000) |
| | | async with page.expect_file_chooser() as fc_info: |
| | | await upload_div.click() |
| | | file_chooser = await fc_info.value |
| | | await file_chooser.set_files(self.path_media) |
| | | await asyncio.sleep(2) |
| | | |
| | | # 等待页面跳转到指定的 URL |
| | | while True: |
| | | # 判断是是否进入视频发布页面,没进入,则自动等待到超时 |
| | | for i in range(10): |
| | | try: |
| | | await page.locator("div#formMain:visible").wait_for(timeout=30000) |
| | | break |
| | | except: |
| | | self.logger.info("正在等待进入视频发布页面...") |
| | | self.logger.info(f"第 {i+1} 次尝试:正在等待进入视频发布页面...") |
| | | await asyncio.sleep(0.1) |
| | | else: |
| | | self.logger.warning("超过最大尝试次数,仍未进入视频发布页面。") |
| | | |
| | | # 填充标题和话题 |
| | | # 这里为了避免页面变化,故使用相对位置定位:作品标题父级右侧第一个元素的input子元素 |
| | |
| | | |
| | | upload_status = await self.uploading_video(page) |
| | | if not upload_status: |
| | | self.logger.error(f"发现上传出错了... 文件:{self.path_video}") |
| | | self.logger.error(f"发现上传出错了... 文件:{self.path_media}") |
| | | raise |
| | | |
| | | # 判断视频封面图是否生成成功 |
| | | while True: |
| | | self.logger.info("正在确认封面完成, 准备去点击定时/发布...") |
| | | if await page.locator("div.cheetah-spin-page img").count(): |
| | | if await page.locator("div.erVanTLKMOvnU7OgFaoD img").count(): |
| | | self.logger.info("封面已完成,点击定时/发布...") |
| | | break |
| | | else: |
| | |
| | | |
| | | return True |
| | | except Exception as e: |
| | | self.logger.error(f"{self.user} upload video {self.path_video} fails, error is :{e}") |
| | | self.logger.error(f"{self.user} upload video {self.path_media} fails, error is :{e}") |
| | | return False |
| | |
| | | if not os.path.exists(self.cookie_path): |
| | | self.logger.info(f"{ self.cookie_path} DOES NOT exist. Please Try login first.") |
| | | return |
| | | self.context = await self.browser.new_context(storage_state=f"{self.cookie_path}", user_agent=DEFAULT_USER_AGENT) |
| | | self.context = await self.browser.new_context(storage_state=f"{self.cookie_path}", user_agent=DEFAULT_USER_AGENT,viewport={"width": 1920, "height": 1080}) |
| | | if os.path.exists(PLAYWRIGHT_STEALTH_JS_PATH): |
| | | await self.context.add_init_script(path=Path(PLAYWRIGHT_STEALTH_JS_PATH)) |
| | | await self.context.grant_permissions(['geolocation']) |
| | |
| | | await self._init_broswer_context() |
| | | for key, value in task_info.items(): |
| | | setattr(self, key, value) |
| | | # 尝试转换 publish_datetime 为 datetime 对象 |
| | | if hasattr(self, 'publish_datetime') and isinstance(self.publish_datetime, str): |
| | | # 尝试转换 scheduled_time 为 datetime 对象 |
| | | if hasattr(self, 'scheduled_time') and isinstance(self.scheduled_time, str): |
| | | try: |
| | | self.publish_datetime = datetime.strptime(self.publish_datetime, "%Y-%m-%d %H:%M") |
| | | self.scheduled_time = datetime.strptime(self.scheduled_time, "%Y-%m-%d %H:%M:%S") |
| | | except Exception as e: |
| | | self.logger.error(f"{self.user},{self.platform}发生错误,日期转换 {self.publish_datetime},{e}") |
| | | self.logger.error(f"{self.user},{self.platform}发生错误,日期转换 {self.scheduled_time},{e}") |
| | | try: |
| | | return await self._upload_core() |
| | | except Exception as e: |
| | |
| | | await page.locator(".switch-roll").first.click() |
| | | await asyncio.sleep(1) |
| | | |
| | | publish_date = self.publish_datetime.strftime("%Y-%m-%d") |
| | | publish_month = self.publish_datetime.strftime("%Y年%m月") |
| | | exact_day = str(self.publish_datetime.day) |
| | | scheduled_date = self.scheduled_time.strftime("%Y-%m-%d") |
| | | scheduled_month = self.scheduled_time.strftime("%Y年%m月") |
| | | exact_day = str(self.scheduled_time.day) |
| | | |
| | | await page.locator(".date-show-icon").first.click() |
| | | await asyncio.sleep(1) |
| | | if publish_month != await page.locator("p.date-picker-nav-title").text_content(): |
| | | if scheduled_month != await page.locator("p.date-picker-nav-title").text_content(): |
| | | await page.locator(".next-btn-day.icon-sprite.icon-sprite-ic_into").click() |
| | | await asyncio.sleep(1) |
| | | await page.get_by_text(exact_day, exact=True).click() |
| | | await asyncio.sleep(1) |
| | | |
| | | exact_hour = f"{self.publish_datetime.hour:02d}" |
| | | exact_min = f"{self.publish_datetime.minute:02d}" |
| | | exact_hour = f"{self.scheduled_time.hour:02d}" |
| | | exact_min = f"{self.scheduled_time.minute:02d}" |
| | | await page.locator(".date-picker-timer > .date-show-icon").click() |
| | | await asyncio.sleep(0.5) |
| | | await page.locator('div.time-picker-panel-select-wrp').nth(0).locator(f'span:nth-child({self.publish_datetime.hour + 1})').click() |
| | | minute_index = ((self.publish_datetime.minute // 5) * 5 // 5) + 1 # 序号从1开始 |
| | | await page.locator('div.time-picker-panel-select-wrp').nth(0).locator(f'span:nth-child({self.scheduled_time.hour + 1})').click() |
| | | minute_index = ((self.scheduled_time.minute // 5) * 5 // 5) + 1 # 序号从1开始 |
| | | await page.locator('div.time-picker-panel-select-wrp').nth(1).locator(f'span:nth-child({minute_index})').click() |
| | | |
| | | await asyncio.sleep(1) |
| | |
| | | async with page.expect_file_chooser() as fc_info: |
| | | await upload_div.click() |
| | | file_chooser = await fc_info.value |
| | | await file_chooser.set_files(self.path_video) |
| | | await file_chooser.set_files(self.path_media) |
| | | await asyncio.sleep(2) |
| | | |
| | | max_retries = 60 # 设置最大重试次数,最大等待时间为 2 分钟 |
| | |
| | | await page.get_by_title(self.category).click() |
| | | |
| | | # 定时发布 |
| | | if self.publish_datetime != 0: |
| | | if self.scheduled_time != 0: |
| | | await self.set_schedule_time(page) |
| | | |
| | | # 判断视频是否发布成功 |
| | |
| | | |
| | | return True |
| | | except Exception as e: |
| | | self.logger.error(f"{self.user} upload video {self.path_video} fails, error is :{e}") |
| | | self.logger.error(f"{self.user} upload video {self.path_media} fails, error is :{e}") |
| | | return False |
| | |
| | | # 在选中的 label 元素下点击 checkbox |
| | | await label_element.click() |
| | | await asyncio.sleep(1) |
| | | publish_datetime_hour = self.publish_datetime.strftime("%Y-%m-%d %H:%M") |
| | | scheduled_time_hour = self.scheduled_time.strftime("%Y-%m-%d %H:%M") |
| | | await asyncio.sleep(1) |
| | | await page.locator('.semi-input[placeholder="日期和时间"]').click() |
| | | await page.keyboard.press("Control+KeyA") |
| | | await page.keyboard.type(str(publish_datetime_hour)) |
| | | await page.keyboard.type(str(scheduled_time_hour)) |
| | | await page.keyboard.press("Enter") |
| | | await asyncio.sleep(1) |
| | | except Exception as e: |
| | |
| | | |
| | | async def handle_upload_error(self, page): |
| | | self.logger.info('视频出错了,重新上传中') |
| | | await page.locator('div.progress-div [class^="upload-btn-input"]').set_input_files(self.path_video) |
| | | await page.locator('div.progress-div [class^="upload-btn-input"]').set_input_files(self.path_media) |
| | | |
| | | async def _try_upload_mp4_and_wait(self,page): |
| | | try: |
| | | await page.locator("div[class^='container'] input").set_input_files(self.path_video) |
| | | await page.locator("div[class^='container'] input").set_input_files(self.path_media) |
| | | while True: |
| | | # 判断重新上传按钮是否存在,如果不存在,代表视频正在上传,则等待 |
| | | try: |
| | |
| | | await asyncio.sleep(2) |
| | | return True |
| | | except Exception as e: |
| | | self.logger.error(f"{self.user} upload video {self.path_video} fails, error is :{e}") |
| | | self.logger.error(f"{self.user} upload video {self.path_media} fails, error is :{e}") |
| | | return False |
| | | |
| | | async def _try_set_tilte_and_description(self,page): |
| | |
| | | await page.locator(third_part_element).locator('input.semi-switch-native-control').click() |
| | | |
| | | # 5、设置定时发布 |
| | | if self.publish_datetime != 0: |
| | | if self.scheduled_time != 0: |
| | | await self.set_schedule_time_douyin(page) |
| | | |
| | | |
| | |
| | | |
| | | return True |
| | | except Exception as e: |
| | | self.logger.error(f"{self.user} upload video {self.path_video} fails, error is :{e}") |
| | | self.logger.error(f"{self.user} upload video {self.path_media} fails, error is :{e}") |
| | | return False |
| New file |
| | |
| | | # -*- coding: utf-8 -*- |
| | | from playwright.async_api import Page |
| | | import asyncio |
| | | from auto_media_publisher.uploaders.uploader_base import UploaderBase |
| | | from datetime import datetime,date |
| | | import re |
| | | |
| | | CONTENT_UPLOAD_URL="https://mp.weixin.qq.com/" |
| | | PUBLISH_SECCESSFULL_URL = "https://mp.weixin.qq.com/cgi-bin/home?t=home/index" |
| | | |
| | | |
| | | class UploaderGongzhonghao(UploaderBase): |
| | | |
| | | async def wai_for_upload(self,new_page,selector): |
| | | await new_page.evaluate(f'''() => {{ |
| | | const container = document.querySelector('{selector}'); |
| | | if (container) {{ |
| | | const input = container.querySelector('input[type="file"]'); // 从父元素开始查找 |
| | | if (input) {{ |
| | | input.style.display = 'block'; // 改变 display 为 block,使其可见 |
| | | input.style.visibility = 'visible'; // 使其可见 |
| | | input.style.opacity = '1'; // 确保它完全透明 |
| | | }} |
| | | }} |
| | | }}''') |
| | | |
| | | async def set_schedule_time(self, new_page): |
| | | try: |
| | | save_publish= await new_page.wait_for_selector("#js_send button", timeout=60000) |
| | | await save_publish.click(force=True) |
| | | await asyncio.sleep(2) |
| | | send_option_div = await new_page.wait_for_selector(".weui-desktop-dialog__ft", timeout=60000) |
| | | |
| | | if self.scheduled_time > datetime.now() : |
| | | await new_page.locator(".mass-send__td-setting > .publish_container > .weui-desktop-form__controls > .mass-send__timer-wrp > .weui-desktop-switch > .weui-desktop-switch__box").click() |
| | | |
| | | delta_days = (self.scheduled_time.date() - date.today()).days |
| | | if delta_days > 0: |
| | | await new_page.locator("dt").filter(has_text="今天 今天").click() |
| | | option_text = "明天" if delta_days==1 else f"月{self.scheduled_time.day}日" |
| | | #day_selector = new_page.locator(f"li.weui-desktop-dropdown__list-ele_text").nth(delta_days) |
| | | #await day_selector.click() |
| | | await new_page.get_by_text(option_text).first.click() |
| | | |
| | | await new_page.get_by_role("textbox", name="请选择时间").click() |
| | | await new_page.get_by_role("textbox", name="请选择时间").press("ControlOrMeta+a") |
| | | await new_page.get_by_role("textbox", name="请选择时间").fill(self.scheduled_time.strftime("%H:%M")) |
| | | await new_page.get_by_role("heading",name="发表").click() |
| | | |
| | | send_option_send = await send_option_div.wait_for_selector('text="发表"',state="attached", timeout=600000) |
| | | await send_option_send.click(force=True) |
| | | await asyncio.sleep(3) |
| | | |
| | | |
| | | except Exception as e: |
| | | self.logger.error(f'[ERROR ] {self.user} , {self.platform} ,设置 发布时间 发生错误:{e}') |
| | | |
| | | async def set_cover_image(self,new_page): |
| | | try: |
| | | # 等待并定位到 #js_cover_area 元素 |
| | | cover_area = await new_page.wait_for_selector('#js_cover_area') |
| | | |
| | | # 悬停鼠标在 #js_cover_area 上 |
| | | await cover_area.hover() |
| | | await new_page.get_by_role("link", name="从图片库选择").click() |
| | | |
| | | image_upload_container = await new_page.wait_for_selector(".weui-desktop-dialog__bd", timeout=60000) |
| | | await self.wai_for_upload(new_page,".weui-desktop-dialog__bd") |
| | | |
| | | image_input = await image_upload_container.wait_for_selector('input[type="file"]', timeout=60000) |
| | | await image_input.set_input_files(self.path_cover) |
| | | |
| | | |
| | | library_next_div = await new_page.wait_for_selector(".weui-desktop-dialog__ft", timeout=60000) |
| | | await library_next_div.evaluate('''(div) => { |
| | | return new Promise(resolve => { |
| | | const btn = Array.from(div.querySelectorAll('button')).find(el => el.innerText.trim() === '下一步'); |
| | | if (!btn) return; |
| | | // 创建 MutationObserver 监听 class 变化 |
| | | const observer = new MutationObserver(() => { |
| | | if (!btn.classList.contains('weui-desktop-btn_disabled')) { |
| | | observer.disconnect(); // 停止监听 |
| | | resolve(true); |
| | | } |
| | | }); |
| | | observer.observe(btn, { attributes: true, attributeFilter: ['class'] }); |
| | | |
| | | // 如果初始状态就满足条件,直接 resolve |
| | | if (!btn.classList.contains('weui-desktop-btn_disabled')) { |
| | | observer.disconnect(); |
| | | resolve(true); |
| | | } |
| | | }); |
| | | }''') |
| | | |
| | | # 找到按钮并点击 |
| | | next_btn = await library_next_div.wait_for_selector('text="下一步"', state="attached", timeout=60000) |
| | | await next_btn.click(force=True) |
| | | # whole div has been changed |
| | | library_next_div = await new_page.wait_for_selector(".weui-desktop-dialog__ft", timeout=60000) |
| | | confirm_btn = await library_next_div.wait_for_selector('text="确认"',state="attached", timeout=600000) |
| | | await confirm_btn.scroll_into_view_if_needed() # 确保按钮滚动到视图 |
| | | await confirm_btn.click(force=True) |
| | | |
| | | #wait for setting cover image: |
| | | preview_div_selector = 'div.js_cover_preview_new.select-cover__preview.first_appmsg_cover' |
| | | while True: |
| | | # 使用 evaluate 来检查 background-image 样式属性 |
| | | has_background_image = await new_page.evaluate('''(selector) => { |
| | | const div = document.querySelector(selector); |
| | | if (div) { |
| | | const bgImage = window.getComputedStyle(div).getPropertyValue('background-image'); |
| | | return bgImage.includes('https'); |
| | | } |
| | | return false; |
| | | }''', preview_div_selector) |
| | | |
| | | if has_background_image: |
| | | print("背景图已加载,继续执行操作") |
| | | break # 背景图片已加载,跳出循环 |
| | | else: |
| | | print("背景图未加载,继续等待") |
| | | await asyncio.sleep(1) # 每秒检查一次 |
| | | await asyncio.sleep(1) |
| | | except Exception as e: |
| | | self.logger.error(f'[ERROR ] {self.user} , {self.platform} ,设置 封面 发生错误:{e}') |
| | | |
| | | async def upload_media_and_wait(self,new_page): |
| | | try: |
| | | await new_page.get_by_role("listitem", name="文档导入").click() |
| | | |
| | | import_container = await new_page.wait_for_selector("#js_import_file_container", timeout=60000) |
| | | |
| | | await self.wai_for_upload(new_page,"#js_import_file_container") |
| | | |
| | | file_input = await import_container.wait_for_selector('input[type="file"]', timeout=60000) |
| | | await file_input.set_input_files(self.path_media) # 替换为你的文件路径 |
| | | |
| | | await new_page.wait_for_selector("#js_import_file_container", state="hidden", timeout=60000) |
| | | |
| | | self.logger.info(f"{self.user},{self.path_media} 文件导入完成!") |
| | | await asyncio.sleep(1) |
| | | |
| | | except Exception as e: |
| | | self.logger.error(f'[ERROR ] {self.user} , {self.platform} ,设置 封面 发生错误:{e}') |
| | | |
| | | async def set_title_and_description(self,new_page): |
| | | try: |
| | | # 设置标题和作者,要在导入之后,否则会被修改掉 |
| | | if self.title and len(self.title) >1: |
| | | title_textarea = await new_page.wait_for_selector("#title", timeout=60000) |
| | | await title_textarea.scroll_into_view_if_needed() |
| | | await title_textarea.click() |
| | | await new_page.keyboard.press('Control+A') # 对于 Mac,可以使用 'Meta+A' |
| | | await new_page.keyboard.press('Backspace') |
| | | await title_textarea.type(self.title, delay=50) # delay 可以控制输入的速度 |
| | | |
| | | author_input = await new_page.wait_for_selector("#author", timeout=60000) |
| | | await author_input.fill(self.author) |
| | | |
| | | description_input = await new_page.wait_for_selector("#js_description", timeout=60000) |
| | | await description_input.fill(self.description) |
| | | |
| | | await asyncio.sleep(1) |
| | | |
| | | except Exception as e: |
| | | self.logger.error(f'[ERROR ] {self.user} , {self.platform} ,设置 标题和描述 发生错误:{e}') |
| | | |
| | | async def set_tags(self,new_page): |
| | | try: |
| | | await new_page.locator("#js_article_tags_area").get_by_text("未添加").click() |
| | | await new_page.locator('input[placeholder="请选择合集"]').click() |
| | | await asyncio.sleep(2) |
| | | # 只选第一个 |
| | | await new_page.locator('li.select-opt-li').nth(0).click() |
| | | ''' |
| | | for tag in self.tags: |
| | | try: |
| | | await new_page.get_by_placeholder("输入后按回车分割").fill(tag) |
| | | await new_page.get_by_placeholder("输入后按回车分割").press("Enter") |
| | | except Exception as e: |
| | | print(f"添加标签 '{tag}' 失败: {str(e)}") |
| | | ''' |
| | | await new_page.get_by_role("button", name="确认").click() |
| | | await asyncio.sleep(3) |
| | | except Exception as e: |
| | | self.logger.error(f'[ERROR ] {self.user} , {self.platform} ,设置 tag 发生错误:{e}') |
| | | |
| | | async def _upload_core(self) -> bool: |
| | | try: |
| | | # 创建一个新的页面 |
| | | page = await self.context.new_page() |
| | | # 访问指定的 URL |
| | | await page.goto(CONTENT_UPLOAD_URL, timeout=120000) |
| | | self.logger.info(f'[ gongzhognhao ] {self.user} , {self.scheduled_time} 正在打开-文章上传页面') |
| | | # 点击“文章” |
| | | await page.locator(".new-creation__menu-content").first.click() |
| | | |
| | | # 等待新窗口出现并切换 |
| | | new_page = await page.context.wait_for_event("page") |
| | | await new_page.wait_for_load_state() |
| | | |
| | | await self.upload_media_and_wait(new_page) |
| | | |
| | | await self.set_title_and_description(new_page) |
| | | await self.set_cover_image(new_page) |
| | | |
| | | if self.tags: |
| | | await self.set_tags(new_page) |
| | | |
| | | # 定时发布 |
| | | if self.scheduled_time: |
| | | await self.set_schedule_time(new_page) |
| | | |
| | | # 判断文章是否发布成功 |
| | | await self.context.storage_state(path=self.cookie_path) # 保存cookie |
| | | self.logger.info(f'{self.user},{self.platform} cookie更新完毕!') |
| | | await asyncio.sleep(1) # 这里延迟是为了方便眼睛直观的观看 |
| | | |
| | | await new_page.get_by_role("button", name="继续发表").click() |
| | | await asyncio.sleep(3) |
| | | |
| | | max_attempts = 10 |
| | | for attempt in range(max_attempts): |
| | | try: |
| | | await new_page.wait_for_url(lambda url: url.startswith(PUBLISH_SECCESSFULL_URL), timeout=50000) |
| | | self.logger.info(f"{self.user},{self.path_media}文章发布成功,页面已跳转到首页!(尝试次数: {attempt + 1})") |
| | | return True |
| | | except TimeoutError: |
| | | print(f"尝试 {attempt + 1}/{max_attempts}:未跳转到目标页面,继续等待...") |
| | | if attempt == max_attempts - 1: |
| | | print("达到最大尝试次数,文章发布失败!") |
| | | return False |
| | | except Exception as e: |
| | | self.logger.error(f"{self.user} upload docx {self.path_media} fails, error is :{e}") |
| | | return False |
| | |
| | | async def set_schedule_time(self, page): |
| | | try: |
| | | self.logger.info("{self.user}, {self.platform} click schedule time......") |
| | | publish_date_hour = self.publish_datetime.strftime("%Y-%m-%d %H:%M:%S") |
| | | scheduled_date_hour = self.scheduled_time.strftime("%Y-%m-%d %H:%M:%S") |
| | | await page.locator("label:text('发布时间')").locator('xpath=following-sibling::div').locator( |
| | | '.ant-radio-input').nth(1).click() |
| | | await asyncio.sleep(1) |
| | |
| | | await asyncio.sleep(1) |
| | | |
| | | await page.keyboard.press("Control+KeyA") |
| | | await page.keyboard.type(str(publish_date_hour)) |
| | | await page.keyboard.type(str(scheduled_date_hour)) |
| | | await page.keyboard.press("Enter") |
| | | await asyncio.sleep(1) |
| | | except Exception as e: |
| | |
| | | async with page.expect_file_chooser() as fc_info: |
| | | await upload_button.click() |
| | | file_chooser = await fc_info.value |
| | | await file_chooser.set_files(self.path_video) |
| | | await file_chooser.set_files(self.path_media) |
| | | await asyncio.sleep(3) |
| | | |
| | | # 等待按钮可交互 |
| | |
| | | # 2、 设置标题和描述 |
| | | await self.set_title_and_description(page) |
| | | # 定时任务 |
| | | if self.publish_datetime != 0: |
| | | if self.scheduled_time != 0: |
| | | await self.set_schedule_time(page) |
| | | |
| | | # 判断视频是否发布成功 |
| | |
| | | |
| | | return True |
| | | except Exception as e: |
| | | self.logger.error(f"{self.user} upload video {self.path_video} fails, error is :{e}") |
| | | self.logger.error(f"{self.user} upload video {self.path_media} fails, error is :{e}") |
| | | return False |
| | | |
| | | |
| | |
| | | |
| | | await page.click('input[placeholder="请选择发表时间"]') |
| | | |
| | | str_month = str(self.publish_datetime.month) if self.publish_datetime.month > 9 else "0" + str(self.publish_datetime.month) |
| | | str_month = str(self.scheduled_time.month) if self.scheduled_time.month > 9 else "0" + str(self.scheduled_time.month) |
| | | current_month = str_month + "月" |
| | | # 获取当前的月份 |
| | | page_month = await page.inner_text('span.weui-desktop-picker__panel__label:has-text("月")') |
| | |
| | | if 'weui-desktop-picker__disabled' in await element.evaluate('el => el.className'): |
| | | continue |
| | | text = await element.inner_text() |
| | | if text.strip() == str(self.publish_datetime.day): |
| | | if text.strip() == str(self.scheduled_time.day): |
| | | await element.click() |
| | | break |
| | | |
| | | # 输入小时部分(假设选择11小时) |
| | | await page.click('input[placeholder="请选择时间"]') |
| | | await page.keyboard.press("Control+KeyA") |
| | | await page.keyboard.type(str(self.publish_datetime.hour)) |
| | | await page.keyboard.type(str(self.scheduled_time.hour)) |
| | | |
| | | # 选择标题栏(令定时时间生效) |
| | | await page.locator("div.input-editor").click() |
| | |
| | | await page.locator('div.media-status-content div.tag-inner:has-text("删除")').click() |
| | | await page.get_by_role('button', name="删除", exact=True).click() |
| | | file_input = page.locator('input[type="file"]') |
| | | await file_input.set_input_files(self.path_video) |
| | | await file_input.set_input_files(self.path_media) |
| | | |
| | | async def add_short_title(self, page): |
| | | short_title_element = page.get_by_text("短标题", exact=True).locator("..").locator( |
| | |
| | | self.logger.info(f'[+]正在上传-------{self.title}.mp4') |
| | | await page.wait_for_url(CONTENT_UPLOAD_URL, timeout=120000) |
| | | file_input = page.locator('input[type="file"]') |
| | | await file_input.set_input_files(self.path_video) |
| | | await file_input.set_input_files(self.path_media) |
| | | # 填充标题和话题 |
| | | await self.add_title_tags(page) |
| | | # 添加商品 |
| | |
| | | await self.add_original(page) |
| | | # 检测上传状态 |
| | | await self.detect_upload_status(page) |
| | | if self.publish_datetime != 0: |
| | | if self.scheduled_time != 0: |
| | | await self.set_schedule_time_tencent(page) |
| | | # 添加短标题 |
| | | await self.add_short_title(page) |
| | |
| | | |
| | | return True |
| | | except Exception as e: |
| | | self.logger.error(f"{self.user} upload video {self.path_video} fails, error is :{e}") |
| | | self.logger.error(f"{self.user} upload video {self.path_media} fails, error is :{e}") |
| | | return False |
| | |
| | | |
| | | n_calendar_month = datetime.strptime(calendar_month, '%B').month |
| | | |
| | | schedule_month = self.publish_datetime.month |
| | | schedule_month = self.scheduled_time.month |
| | | |
| | | if n_calendar_month != schedule_month: |
| | | if n_calendar_month < schedule_month: |
| | |
| | | for i in range(valid_days): |
| | | day_element = valid_days_locator.nth(i) |
| | | text = await day_element.inner_text() |
| | | if text.strip() == str(self.publish_datetime.day): |
| | | if text.strip() == str(self.scheduled_time.day): |
| | | await day_element.click() |
| | | break |
| | | # time set |
| | | await scheduled_picker.locator('div.TUXInputBox').nth(0).click() |
| | | |
| | | hour_str = self.publish_datetime.strftime("%H") |
| | | correct_minute = int(self.publish_datetime.minute / 5) |
| | | hour_str = self.scheduled_time.strftime("%H") |
| | | correct_minute = int(self.scheduled_time.minute / 5) |
| | | minute_str = f"{correct_minute:02d}" |
| | | |
| | | hour_selector = f"span.tiktok-timepicker-left:has-text('{hour_str}')" |
| | |
| | | async with page.expect_file_chooser() as fc_info: |
| | | await select_file_button.click() |
| | | file_chooser = await fc_info.value |
| | | await file_chooser.set_files(self.path_video) |
| | | await file_chooser.set_files(self.path_media) |
| | | |
| | | async def add_title_tags(self, page): |
| | | |
| | |
| | | async with page.expect_file_chooser() as fc_info: |
| | | await upload_button.click() |
| | | file_chooser = await fc_info.value |
| | | await file_chooser.set_files(self.path_video) |
| | | await file_chooser.set_files(self.path_media) |
| | | |
| | | await self.add_title_tags(page) |
| | | # detect upload status |
| | |
| | | self.logger.info(f'[+] Uploading thumbnail file {self.title}.png') |
| | | await self.upload_thumbnails(page) |
| | | |
| | | if self.publish_datetime != 0: |
| | | if self.scheduled_time != 0: |
| | | await self.set_schedule_time(page) |
| | | |
| | | await self.click_publish(page) |
| | |
| | | |
| | | return True |
| | | except Exception as e: |
| | | self.logger.error(f"{self.user} upload video {self.path_video} fails, error is :{e}") |
| | | self.logger.error(f"{self.user} upload video {self.path_media} fails, error is :{e}") |
| | | return False |
| | |
| | | |
| | | async def setPostScheduleDateTime(self, page): |
| | | self.logger.info(f"start to set publish date time ...{datetime}") |
| | | await self.set_single_option(page,'#SELECTOR_3',self.publish_datetime.year) # year |
| | | await self.set_single_option(page,'#SELECTOR_1', self.publish_datetime.month) # month |
| | | await self.set_single_option(page,'#SELECTOR_2', self.publish_datetime.day) # day |
| | | await self.set_single_option(page,'#SELECTOR_4', self.publish_datetime.hour) # hour |
| | | await self.set_single_option(page,'#SELECTOR_5', self.publish_datetime.minute) # min |
| | | await self.set_single_option(page,'#SELECTOR_3',self.scheduled_time.year) # year |
| | | await self.set_single_option(page,'#SELECTOR_1', self.scheduled_time.month) # month |
| | | await self.set_single_option(page,'#SELECTOR_2', self.scheduled_time.day) # day |
| | | await self.set_single_option(page,'#SELECTOR_4', self.scheduled_time.hour) # hour |
| | | await self.set_single_option(page,'#SELECTOR_5', self.scheduled_time.minute) # min |
| | | # 确认按钮 |
| | | await page.click('span:text("确认")') |
| | | await asyncio.sleep(1) |
| | |
| | | |
| | | # 等待文件选择器出现并上传视频 |
| | | file_input = await page.wait_for_selector('input[type="file"]', timeout=10000) |
| | | await file_input.set_input_files(self.path_video) |
| | | await file_input.set_input_files(self.path_media) |
| | | except Exception as e: |
| | | self.logger.info("发布视频失败,可能网页加载失败了\n", e) |
| | | self.logger.info("发布视频失败,可能网页加载失败了") |
| | |
| | | async def set_schedule_time(self, page): |
| | | try: |
| | | |
| | | publish_date_hour = self.publish_datetime.strftime("%Y-%m-%d %H:%M") |
| | | scheduled_date_hour = self.scheduled_time.strftime("%Y-%m-%d %H:%M") |
| | | await page.locator("label").filter(has_text="定时发布").locator("span").nth(1).click() |
| | | await asyncio.sleep(1) |
| | | await page.get_by_placeholder("选择日期和时间").click() |
| | | await asyncio.sleep(1) |
| | | await page.keyboard.press("Control+KeyA") |
| | | await page.keyboard.type(str(publish_date_hour)) |
| | | await page.keyboard.type(str(scheduled_date_hour)) |
| | | await page.keyboard.press("Enter") |
| | | await asyncio.sleep(1) |
| | | except Exception as e: |
| | |
| | | async with page.expect_file_chooser() as fc_info: |
| | | await upload_button.click() |
| | | file_chooser = await fc_info.value |
| | | await file_chooser.set_files(self.path_video) |
| | | await file_chooser.set_files(self.path_media) |
| | | await asyncio.sleep(2) |
| | | |
| | | # wait for video upload finish |
| | |
| | | await self.set_cover_image(page) |
| | | |
| | | # 定时任务 |
| | | if self.publish_datetime != 0: |
| | | if self.scheduled_time != 0: |
| | | self.logger.info("正在设置 定时发布 时间...") |
| | | await self.set_schedule_time(page) |
| | | |
| | |
| | | await asyncio.sleep(3) |
| | | return True |
| | | except Exception as e: |
| | | self.logger.error(f"{self.user} upload video {self.path_video} fails, error is :{e}") |
| | | self.logger.error(f"{self.user} upload video {self.path_media} fails, error is :{e}") |
| | | return False |
| | |
| | | from auto_media_publisher.uploaders.uploader_baijiahao import UploaderBaijiahao |
| | | from auto_media_publisher.uploaders.uploader_xiaohongshu import UploaderXiaohongshu |
| | | from auto_media_publisher.uploaders.uploader_twitterX import UploaderTwitterX |
| | | |
| | | from auto_media_publisher.uploaders.uploader_gongzhonghao import UploaderGongzhonghao |
| | | platform_map = { |
| | | "douyin": UploaderDouyin, |
| | | "kuaishou": UploaderKuaishou, |
| | |
| | | "baijiahao": UploaderBaijiahao, |
| | | "tiktok": UploaderTiktok, |
| | | "twitterX": UploaderTwitterX, |
| | | "gongzhonghao":UploaderGongzhonghao |
| | | } |
| | | |
| | | |
| | |
| | | import datetime |
| | | import random |
| | | import os |
| | | from io import BytesIO |
| | | |
| | | from auto_media_publisher.config.conf_base import ( |
| | | TRANSLATE_API_TEMPLATE, |
| | | POLLINATIONS_API_TEMPLATE, |
| | |
| | | |
| | | if not filename: |
| | | now = datetime.datetime.now() |
| | | filename = now.strftime("%Y%m%d%H%M%S") + ".jpg" |
| | | if not filename.lower().endswith(".jpg"): |
| | | filename += ".jpg" |
| | | filename = now.strftime("%Y%m%d%H%M%S") + ".png" |
| | | if not filename.lower().endswith(".png"): |
| | | filename += ".png" |
| | | |
| | | with open(filename, "wb") as f: |
| | | f.write(content) |
| | |
| | | abs_path = os.path.abspath(filename) |
| | | print(f"[✓] 图片已保存:{abs_path}") |
| | | return abs_path |
| | | |
| | | def generate_image_to_stream(self, prompt: str) -> BytesIO: |
| | | if not prompt.strip(): |
| | | raise ValueError("提示词不能为空") |
| | | |
| | | translated_prompt = self.translate_prompt(prompt) |
| | | url = self.build_url(translated_prompt) |
| | | |
| | | content = self._fetch_with_retry(url) |
| | | if content is None: |
| | | return None |
| | | |
| | | image_stream = BytesIO(content) |
| | | return image_stream |
| | |
| | | "username": "施教练", |
| | | "city": "上海", |
| | | "proxy": "http://proxy.parkprofile.com:4753", |
| | | "enabled": true, |
| | | "enabled": false, |
| | | "tags": [ |
| | | "太极鸟", |
| | | "机构用户" |
| | |
| | | "datetime_update": "2025-07-14T09:00:00", |
| | | "platforms": [ |
| | | { |
| | | "name": "kuaishou", |
| | | "name": "gongzhonghao", |
| | | "enabled": false, |
| | | "max_session_hour": 24, |
| | | "task_type": "docx_upload", |
| | | "task_ahead_days": 2, |
| | | "media_generator": "DocxGeneratorRewriter", |
| | | "media_generator_args": { |
| | | "docx_author": "小优", |
| | | "docx_dir":"E:/古原文章合集/output" |
| | | }, |
| | | "upload_times": [ |
| | | "08:00" |
| | | ] |
| | | }, |
| | | { |
| | | "name": "gongzhonghao", |
| | | "enabled": true, |
| | | "max_session_hour": 24, |
| | | "task_type": "docx_upload", |
| | | "task_ahead_days": 4, |
| | | "media_generator": "DocxGeneratorCreator", |
| | | "media_generator_args": { |
| | | "docx_author": "小优优" |
| | | }, |
| | | "upload_times": [ |
| | | "08:00" |
| | | ] |
| | | }, |
| | | { |
| | | "name": "kuaishou", |
| | | "enabled": false, |
| | | "max_session_hour": 24, |
| | | "task_type": "video_upload", |
| | | "task_ahead_days": 14, |
| | |
| | | }, |
| | | { |
| | | "name": "baijiahao", |
| | | "enabled": true, |
| | | "enabled": false, |
| | | "max_session_hour": 24, |
| | | "task_type": "video_upload", |
| | | "task_ahead_days": 7, |
| | |
| | | }, |
| | | { |
| | | "name": "bilibili", |
| | | "enabled": true, |
| | | "enabled": false, |
| | | "max_session_hour": 24, |
| | | "task_type": "video_upload", |
| | | "task_ahead_days": 5, |
| | |
| | | "username": "不可不可", |
| | | "city": "上海", |
| | | "proxy": "None", |
| | | "enabled": true, |
| | | "enabled": false, |
| | | "tags": [ |
| | | "测试账号", |
| | | "员工账号" |
| New file |
| | |
| | | {"cookies": [{"name": "ua_id", "value": "Yp8GoVBn7Tj0PWR7AAAAADaCnYPYpvql9WPFzFkbL_A=", "domain": "mp.weixin.qq.com", "path": "/", "expires": 1788443924.066288, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "wxuin", "value": "53845090997782", "domain": "mp.weixin.qq.com", "path": "/", "expires": 1788405090.13786, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "_clck", "value": "1oxp806|1|fy1|0", "domain": ".qq.com", "path": "/", "expires": 1785381090, "httpOnly": false, "secure": false, "sameSite": "Lax"}, {"name": "uuid", "value": "8093d628ddf047d5a340ec437ca7fd08", "domain": "mp.weixin.qq.com", "path": "/", "expires": -1, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "rand_info", "value": "CAESIEjp7aANF1MLCho4lIEi6Ju8oYLEexqCUxELmbqpfG3Y", "domain": "mp.weixin.qq.com", "path": "/", "expires": 1754229560, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "slave_bizuin", "value": "3932822909", "domain": "mp.weixin.qq.com", "path": "/", "expires": 1754229560, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "data_bizuin", "value": "3932822909", "domain": "mp.weixin.qq.com", "path": "/", "expires": 1754229560, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "bizuin", "value": "3932822909", "domain": "mp.weixin.qq.com", "path": "/", "expires": 1754229560, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "data_ticket", "value": "TXXMQ0chAAhF8D9olYk9AhfbDAjnS2jHUUO8GHs0e45nt6P/zjA38GlY5q12SD0E", "domain": "mp.weixin.qq.com", "path": "/", "expires": 1754229560, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "slave_sid", "value": "OHl1NHRHZjd2N3poQTFDQ2d5WVBBWnJ5bm9obkZNVjZGank5S2dxSUMwblRqeFUwalBSNEpTbHlrMjZ6cUtxT2dRWk9NdElDcGRmUko1a1F4MENlUWFja0FvVjZDZnY0RXVkT0NiNUJnOVlITGQzOHRGYTBLUG10UEZzSzJhdWozakN1SUo5VXZRNmdkUGlz", "domain": "mp.weixin.qq.com", "path": "/", "expires": 1754229560, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "slave_user", "value": "gh_5624b93dc545", "domain": "mp.weixin.qq.com", "path": "/", "expires": 1754229560, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "xid", "value": "fedc4a4eeb3b124f5812d5b88b1265f4", "domain": "mp.weixin.qq.com", "path": "/", "expires": 1788405116.292443, "httpOnly": true, "secure": true, "sameSite": "Lax"}, {"name": "mm_lang", "value": "zh_CN", "domain": "mp.weixin.qq.com", "path": "/", "expires": 1788405116.292574, "httpOnly": false, "secure": true, "sameSite": "Lax"}, {"name": "_clsk", "value": "19x6m1p|1753883936581|2|1|mp.weixin.qq.com/weheat-agent/payload/record", "domain": ".qq.com", "path": "/", "expires": 1753970336, "httpOnly": false, "secure": false, "sameSite": "Lax"}], "origins": [{"origin": "https://mp.weixin.qq.com", "localStorage": [{"name": "USER_AGENT_BROWSER_MAJOR_VERSION", "value": "127"}, {"name": "loginMode", "value": "1"}, {"name": "adTransitionText", "value": "noAdText"}, {"name": "hasClick", "value": "[0]"}]}]} |
| | |
| | | async def main(): |
| | | if len(sys.argv) < 3: |
| | | print("python test_upload.py [user] [PLATFORM] [proxy] [JSON_PATH] ") |
| | | print("python test_upload.py 18918594752 xiaohongshu None data/video_final/18918594752bukebuke/test.json") |
| | | print("[PLATFORM] douyin, kuaishou, shipinhao, xiaohongshu, bilibili, baijiahao, tiktok, twitterX, all") |
| | | print("python test_upload.py 18918594752 xiaohongshu None data/media_final/18918594752bukebuke/test.json") |
| | | print("[PLATFORM] douyin, kuaishou, shipinhao, xiaohongshu, bilibili, baijiahao, tiktok, twitterX, gongzhonghao") |
| | | return |
| | | |
| | | handler = await create_media_uploader(user=sys.argv[1],platform=sys.argv[2],proxy=sys.argv[3]) |
| | | await handler.upload(load_json(sys.argv[4])) |
| | | await handler.upload_and_close(load_json(sys.argv[4])) |
| | | |
| | | if __name__ == "__main__": |
| | | asyncio.run(main()) |