Skip to content
This repository has been archived by the owner on Jan 10, 2022. It is now read-only.

Commit

Permalink
fix: #2 投币完成再次运行专栏会投币
Browse files Browse the repository at this point in the history
  • Loading branch information
catlair committed Mar 25, 2021
1 parent a791c00 commit ed8341e
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 38 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,16 @@

- 自定义关注分组请注意分组中的 up 数量(主要是 up 的投稿总数量),过低会导致一直找不到可投币目标,直到无法控制 ( **没必要修改的问题自己避免即可** )

- 投币数在执行前已经达成, 访问到的稿件投币数也达到, ~~会出现多此一举的再出寻找下一个稿件~~(判断是否投币完成需要点击弹出投币界面,不能投币的已经没有这个页面了)

- UP 主的部分视频可能是纪录片或者活动作品,界面不同会导致无法进行操作, 打开此类视频后会 **关闭页面并重新选择内容**

- 环境中不存在开发时依赖`ts-node`, 如需要请自行安装

## 其他已知问题

- [ ] 关注的 up 列表是动态加载的, 目前存在只抓取到【全部关注】而非指定标签的情况(在延时和判断页面 loading 的情况下极小概率)

## 一些设想

- 试图拦截 request 直接修改某些请求,实际上 puppeteer 不支持串行的拦截,导致此行为和第三方的包有所冲突
Expand Down
14 changes: 9 additions & 5 deletions src/dailyTask/getFollow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const logger = log4js.getLogger('upTask');
const includesFollow = DailyTask.includesFollow;
const excludesFollow = DailyTask.excludesFollow;

export default async function(page: Page): Promise<Page> {
export default async function (page: Page): Promise<Page> {
let upTargetPage: Page = null,
gotoFollowPageCount = 0,
chooseFollowTagCount = 0,
Expand Down Expand Up @@ -139,7 +139,9 @@ export default async function(page: Page): Promise<Page> {
await paginationToJump(page, pageNum, logger);
await page.util.wt(3, 6);
//等待页面真正的渲染完成
await page.waitForSelector('.follow-content.section:not(.loading)');
await page.waitForSelector('.follow-content.section:not(.loading)', {
timeout: 13000,
});
await page.util.wt(1, 3);
//获取到的$$包含头像和昵称(两者都可点击)
logger.trace(`选择第${num + 1}个`);
Expand All @@ -157,11 +159,13 @@ export default async function(page: Page): Promise<Page> {
await page.util.wt(3, 6);
await $target.click();
} catch (error) {
if (++chooseFollowUpCount > 3) {
logger.fatal('前往随机up失败');
await page.screenshot({
path: '/usr/src/app/testimg',
});
logger.warn('前往随机up失败', error.message);
if (++chooseFollowUpCount > 2) {
throw new Error(error);
}
logger.warn('前往随机up失败', error.message);
await page.reload();
await chooseFollowUp();
}
Expand Down
31 changes: 16 additions & 15 deletions src/dailyTask/shareVideo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,24 @@ export default async function shareVideo(page: Page, logger?: Logger) {
if (!logger) {
logger = getLogger('shareVideo');
}
logger.debug('开始分享视频');
await page.waitForTimeout(_.random(2000, 5000));
await page.hover('.share');
const $$btn = await page.util.$$wait('.share-btn');
await page.waitForTimeout(_.random(1000, 3000));
logger.debug('点击分享按钮');
await $$btn[_.random(1, 4)].click();
const { x, y } = await $$btn[4].boundingBox();
await page.mouse.move(x, y - 60);
//分享页面的url十分长
const target = await page
.browser()
.waitForTarget(x => x.url().length > 500 && x.url().includes('share'));
await page.waitForTimeout(_.random(4000, 7000));

let sharePage: Page;

try {
logger.debug('开始分享视频');
await page.waitForTimeout(_.random(2000, 5000));
await page.hover('.share');
const $$btn = await page.util.$$wait('.share-btn');
await page.waitForTimeout(_.random(1000, 3000));
logger.debug('点击分享按钮');
await $$btn[_.random(1, 4)].click();
const { x, y } = await $$btn[4].boundingBox();
await page.mouse.move(x, y - 60);
//分享页面的url十分长
const target = await page
.browser()
.waitForTarget(x => x.url().length > 500 && x.url().includes('share'));
await page.waitForTimeout(_.random(4000, 7000));

logger.trace('尝试关闭分享窗口');
// ppeteer-extra-plugin-stealth 会报错
sharePage = await target.page();
Expand Down
56 changes: 38 additions & 18 deletions src/dailyTask/upTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ export class UPTask {
async init() {
try {
await this.page.util.wt(2, 4);
await this.goToUpByUid();
await this.goToUpSpace();
const username = await this.getUserName();
logger.info(`访问UP主 【${username}】`);
} catch (error) {
await this.closeUpPage();
logger.error('前往up页面失败');
return;
}
/** 投稿 */
/** 稿件获取 */
await this.page.waitForTimeout(_.random(2000, 5000));
const nums = await this.getContributeItem();
await this.changeContributeType(nums);
Expand All @@ -61,12 +61,12 @@ export class UPTask {
case 0:
//视频
(await this.commonHandle()) &&
(isStopCoin = await this.videoHandle());
(isStopCoin = await this.videoHandle());
break;
case 1:
//音频
(await this.commonHandle()) &&
(isStopCoin = await this.audioHandle());
(isStopCoin = await this.audioHandle());
break;
case 2:
//专栏
Expand All @@ -88,6 +88,10 @@ export class UPTask {
return isStopCoin;
}

/**
* 切换稿件类型(视频,音频,专栏)
* @param nums 每种类型的数量
*/
async changeContributeType(nums: number[]) {
/** 0 - (total - 1) */
const { value, area } = distributedRandom(nums);
Expand All @@ -110,7 +114,10 @@ export class UPTask {
}
}

async goToUpByUid() {
/**
* 去往用户页面
*/
async goToUpSpace() {
if (!this.uid) {
await this.page.evaluate(() =>
$('.n-tab-links [href*="video"]')[0].click(),
Expand Down Expand Up @@ -138,6 +145,10 @@ export class UPTask {
]);
}

/**
* 获取稿件的ID
* @param $item 展示稿件的元素
*/
async getContributeId(
$item: ElementHandle,
): Promise<{
Expand Down Expand Up @@ -267,8 +278,7 @@ export class UPTask {
await shareVideo(this.page, logger);
await this.page.util.wt(2, 4);
}
} catch {
}
} catch {}

if (!(await this.isUp())) {
logger.debug('视频up主非指定up主,放弃投币');
Expand Down Expand Up @@ -309,17 +319,20 @@ export class UPTask {
}
const $coin = await this.page.util.$wait('.article-action .coin-btn');
await $coin.hover();
await $coin.click();
const $coinSure = await this.page.util.$wait('.coin-sure.b-btn'),
$coinTipsExp = await this.page.util.$wait(
'.coin-content .coin-tips .exp',
);
const exp = +(await $coinTipsExp
.getProperty('innerText')
.then(jH => jH.jsonValue()));
return await this.addCoinSure(exp, $coinSure);
const [$coinSure, res] = await this.getCoinExp(
$coin,
'.coin-sure.b-btn',
'account/exp.php',
);
const { number } = await res.json();
return await this.addCoinSure(number, $coinSure);
}

/**
* 确认投币
* @param exp 已获得经验
* @param $coinSure 确认投币按钮
*/
async addCoinSure(exp: number, $coinSure: ElementHandle): Promise<boolean> {
await this.page.waitForTimeout(_.random(2000, 4000));
if (exp === 40 && this.contributeType !== Contribute['专栏']) {
Expand Down Expand Up @@ -375,6 +388,7 @@ export class UPTask {
return Number(multiply);
}
logger.warn('投币失败', code, message);
//137004 帐号封禁
if (code === 137004) {
logger.fatal(message, '结束任务执行');
process.exit(0);
Expand Down Expand Up @@ -403,6 +417,9 @@ export class UPTask {
this.coinStatus = false;
}

/**
* 获取该音频已经投币状态
*/
async getAudioCoinStatus() {
//音频可投币数是否可变不知
//暂时当成2
Expand All @@ -422,8 +439,11 @@ export class UPTask {
this.coinStatus = false;
}

/**
* 获取该文章已投币状态
*/
async getArticleCoinStatus() {
//专栏可以投两颗(漏洞),当然这里一颗处理
//专栏可以投两颗(但是pc端只能一颗),当然这里一颗处理
// {"code":0,"data":{like:0,coin:0,favorite:false}}}
try {
const res = await this.page.waitForResponse(r =>
Expand All @@ -448,7 +468,7 @@ export class UPTask {
*
* 使用时需要注意设置延时,避免浏览器关闭太快
*/
export default async function(page: Page, uid?: string | number) {
export default async function (page: Page, uid?: string | number) {
if (!page) {
throw new Error('不存在的页面');
}
Expand Down

0 comments on commit ed8341e

Please sign in to comment.