From 93b37907f38180e2ecd5115ffbb7f65e8a3fda20 Mon Sep 17 00:00:00 2001 From: wangbo Date: Tue, 9 Sep 2025 11:52:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=9E=84=E5=BB=BA=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next.config.mjs | 1 + package-lock.json | 350 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 5 + src/lib/SunoApi.ts | 31 +++- test.ts | 51 +++++++ 5 files changed, 429 insertions(+), 9 deletions(-) create mode 100644 test.ts diff --git a/next.config.mjs b/next.config.mjs index 193509e..4f5942a 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -7,6 +7,7 @@ const nextConfig = { }); return config; }, + basePath: '/suno-api', // 👈 应用的统一前缀 experimental: { serverMinification: false, // the server minification unfortunately breaks the selector class names }, diff --git a/package-lock.json b/package-lock.json index 0681d64..46e2641 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,8 @@ "next-swagger-doc": "^0.4.0", "pino": "^8.19.0", "pino-pretty": "^11.0.0", + "playwright-extra": "^4.3.6", + "puppeteer-extra-plugin-stealth": "^2.11.2", "react": "^18", "react-dom": "^18", "react-markdown": "^9.0.1", @@ -1704,6 +1706,15 @@ "node": ">= 0.4" } }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/array-buffer-byte-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", @@ -2477,6 +2488,22 @@ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", "license": "MIT" }, + "node_modules/clone-deep": { + "version": "0.2.4", + "resolved": "https://registry.npmmirror.com/clone-deep/-/clone-deep-0.2.4.tgz", + "integrity": "sha512-we+NuQo2DHhSl+DP6jlUiAhyAjBQrYnpOk15rN6c6JSPScjiCLh8IbSU+VTcph6YS3o7mASE8a0+gbZ7ChLpgg==", + "license": "MIT", + "dependencies": { + "for-own": "^0.1.3", + "is-plain-object": "^2.0.1", + "kind-of": "^3.0.2", + "lazy-cache": "^1.0.3", + "shallow-clone": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/clone-response": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", @@ -3920,6 +3947,27 @@ "is-callable": "^1.1.3" } }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmmirror.com/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw==", + "license": "MIT", + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/foreground-child": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", @@ -4862,6 +4910,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "license": "MIT" + }, "node_modules/is-bun-module": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.2.1.tgz", @@ -4943,6 +4997,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmmirror.com/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -5089,6 +5152,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -5239,6 +5314,15 @@ "dev": true, "license": "ISC" }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/iterator.prototype": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz", @@ -5401,6 +5485,18 @@ "json-buffer": "3.0.1" } }, + "node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", @@ -5421,6 +5517,15 @@ "node": ">=0.10" } }, + "node_modules/lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -5753,6 +5858,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/merge-deep": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/merge-deep/-/merge-deep-3.0.3.tgz", + "integrity": "sha512-qtmzAS6t6grwEkNrunqTBdn0qKwFgNWvlxUbAV8es9M7Ot1EbyApytCnvE0jALPa46ZpKDUo527kKiaWplmlFA==", + "license": "MIT", + "dependencies": { + "arr-union": "^3.1.0", + "clone-deep": "^0.2.4", + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -6301,6 +6420,28 @@ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "license": "MIT" }, + "node_modules/mixin-object": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/mixin-object/-/mixin-object-2.0.1.tgz", + "integrity": "sha512-ALGF1Jt9ouehcaXaHhn6t1yGWRqGaHkPFndtFVHfZXOvkIZ/yoGaSi0AHVTafb3ZBGg4dr/bDwnaEKqCXzchMA==", + "license": "MIT", + "dependencies": { + "for-in": "^0.1.3", + "is-extendable": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-object/node_modules/for-in": { + "version": "0.1.8", + "resolved": "https://registry.npmmirror.com/for-in/-/for-in-0.1.8.tgz", + "integrity": "sha512-F0to7vbBSHP8E3l6dCjxNOLuSFAACIxFy3UehTUlG7svlXi37HHsDkyVcHo0Pq8QwrE+pXvWSVX3ZT1T9wAZ9g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -7070,6 +7211,30 @@ "node": ">=18" } }, + "node_modules/playwright-extra": { + "version": "4.3.6", + "resolved": "https://registry.npmmirror.com/playwright-extra/-/playwright-extra-4.3.6.tgz", + "integrity": "sha512-q2rVtcE8V8K3vPVF1zny4pvwZveHLH8KBuVU2MoE3Jw4OKVoBWsHI9CH9zPydovHHOCDxjGN2Vg+2m644q3ijA==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "playwright": "*", + "playwright-core": "*" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "playwright-core": { + "optional": true + } + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -7395,6 +7560,147 @@ "node": ">=6" } }, + "node_modules/puppeteer-extra-plugin": { + "version": "3.2.3", + "resolved": "https://registry.npmmirror.com/puppeteer-extra-plugin/-/puppeteer-extra-plugin-3.2.3.tgz", + "integrity": "sha512-6RNy0e6pH8vaS3akPIKGg28xcryKscczt4wIl0ePciZENGE2yoaQJNd17UiEbdmh5/6WW6dPcfRWT9lxBwCi2Q==", + "license": "MIT", + "dependencies": { + "@types/debug": "^4.1.0", + "debug": "^4.1.1", + "merge-deep": "^3.0.1" + }, + "engines": { + "node": ">=9.11.2" + }, + "peerDependencies": { + "playwright-extra": "*", + "puppeteer-extra": "*" + }, + "peerDependenciesMeta": { + "playwright-extra": { + "optional": true + }, + "puppeteer-extra": { + "optional": true + } + } + }, + "node_modules/puppeteer-extra-plugin-stealth": { + "version": "2.11.2", + "resolved": "https://registry.npmmirror.com/puppeteer-extra-plugin-stealth/-/puppeteer-extra-plugin-stealth-2.11.2.tgz", + "integrity": "sha512-bUemM5XmTj9i2ZerBzsk2AN5is0wHMNE6K0hXBzBXOzP5m5G3Wl0RHhiqKeHToe/uIH8AoZiGhc1tCkLZQPKTQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "puppeteer-extra-plugin": "^3.2.3", + "puppeteer-extra-plugin-user-preferences": "^2.4.1" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "playwright-extra": "*", + "puppeteer-extra": "*" + }, + "peerDependenciesMeta": { + "playwright-extra": { + "optional": true + }, + "puppeteer-extra": { + "optional": true + } + } + }, + "node_modules/puppeteer-extra-plugin-user-data-dir": { + "version": "2.4.1", + "resolved": "https://registry.npmmirror.com/puppeteer-extra-plugin-user-data-dir/-/puppeteer-extra-plugin-user-data-dir-2.4.1.tgz", + "integrity": "sha512-kH1GnCcqEDoBXO7epAse4TBPJh9tEpVEK/vkedKfjOVOhZAvLkHGc9swMs5ChrJbRnf8Hdpug6TJlEuimXNQ+g==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^10.0.0", + "puppeteer-extra-plugin": "^3.2.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "playwright-extra": "*", + "puppeteer-extra": "*" + }, + "peerDependenciesMeta": { + "playwright-extra": { + "optional": true + }, + "puppeteer-extra": { + "optional": true + } + } + }, + "node_modules/puppeteer-extra-plugin-user-data-dir/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/puppeteer-extra-plugin-user-data-dir/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/puppeteer-extra-plugin-user-data-dir/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/puppeteer-extra-plugin-user-preferences": { + "version": "2.4.1", + "resolved": "https://registry.npmmirror.com/puppeteer-extra-plugin-user-preferences/-/puppeteer-extra-plugin-user-preferences-2.4.1.tgz", + "integrity": "sha512-i1oAZxRbc1bk8MZufKCruCEC3CCafO9RKMkkodZltI4OqibLFXF3tj6HZ4LZ9C5vCXZjYcDWazgtY69mnmrQ9A==", + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "deepmerge": "^4.2.2", + "puppeteer-extra-plugin": "^3.2.3", + "puppeteer-extra-plugin-user-data-dir": "^2.4.1" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "playwright-extra": "*", + "puppeteer-extra": "*" + }, + "peerDependenciesMeta": { + "playwright-extra": { + "optional": true + }, + "puppeteer-extra": { + "optional": true + } + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -8067,7 +8373,6 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, "license": "ISC", "dependencies": { "glob": "^7.1.3" @@ -8084,7 +8389,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -8313,6 +8617,42 @@ "sha.js": "bin.js" } }, + "node_modules/shallow-clone": { + "version": "0.1.2", + "resolved": "https://registry.npmmirror.com/shallow-clone/-/shallow-clone-0.1.2.tgz", + "integrity": "sha512-J1zdXCky5GmNnuauESROVu31MQSnLoYvlyEn6j2Ztk6Q5EHFIhxkMhYcv6vuDzl2XEzoRr856QwzMgWM/TmZgw==", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.1", + "kind-of": "^2.0.1", + "lazy-cache": "^0.2.3", + "mixin-object": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shallow-clone/node_modules/kind-of": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-2.0.1.tgz", + "integrity": "sha512-0u8i1NZ/mg0b+W3MGGw5I7+6Eib2nx72S/QvXa0hYjEkjTknYmEYQJwGu3mLC0BrhtJjtQafTkyRUQ75Kx0LVg==", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shallow-clone/node_modules/lazy-cache": { + "version": "0.2.7", + "resolved": "https://registry.npmmirror.com/lazy-cache/-/lazy-cache-0.2.7.tgz", + "integrity": "sha512-gkX52wvU/R8DVMMt78ATVPFMJqfW8FPz1GZ1sVHBVQHmu/WvhIWE4cE1GBzhJNFicDeYhnwp6Rl35BcAIM3YOQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -9652,9 +9992,9 @@ } }, "node_modules/user-agents": { - "version": "1.1.362", - "resolved": "https://registry.npmjs.org/user-agents/-/user-agents-1.1.362.tgz", - "integrity": "sha512-mwDzPkR3IZswVYotnQJU4t/H56K0QBWGlkr3eDPHPzMYiUkxZCFICU1n4H3OHUN2QHVHsdlRpDMbsi39hhvvMg==", + "version": "1.1.655", + "resolved": "https://registry.npmmirror.com/user-agents/-/user-agents-1.1.655.tgz", + "integrity": "sha512-3zdmOqszMxPoqTzOAtOacV6L4N+g5+n4NStyZh+PSoYf4A/i5ZPQQNlW5tEkLaDLtu/XjQCaii2BZt//ZgaLrw==", "license": "BSD-2-Clause", "dependencies": { "lodash.clonedeep": "^4.5.0" diff --git a/package.json b/package.json index 9ff8e98..1e2774e 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,9 @@ "scripts": { "dev": "PORT=3013 next dev", "build": "next build", + "build:docker": "docker build . --platform linux/amd64 -t registry.cn-shanghai.aliyuncs.com/easyaigc/suno-api:latest", + "docker:push": "docker push registry.cn-shanghai.aliyuncs.com/easyaigc/suno-api:latest", + "deploy": "npm build:docker && npm docker:push", "start": "next start", "lint": "next lint" }, @@ -30,6 +33,8 @@ "next-swagger-doc": "^0.4.0", "pino": "^8.19.0", "pino-pretty": "^11.0.0", + "playwright-extra": "^4.3.6", + "puppeteer-extra-plugin-stealth": "^2.11.2", "react": "^18", "react-dom": "^18", "react-markdown": "^9.0.1", diff --git a/src/lib/SunoApi.ts b/src/lib/SunoApi.ts index e39a84f..f118689 100644 --- a/src/lib/SunoApi.ts +++ b/src/lib/SunoApi.ts @@ -7,11 +7,14 @@ import * as cookie from 'cookie'; import { randomUUID } from 'node:crypto'; import { Solver } from '@2captcha/captcha-solver'; import { paramsCoordinates } from '@2captcha/captcha-solver/dist/structs/2captcha'; -import { BrowserContext, Page, Locator, chromium, firefox } from 'rebrowser-playwright-core'; +import { BrowserContext, Page,chromium, Locator, firefox } from 'rebrowser-playwright-core'; import { createCursor, Cursor } from 'ghost-cursor-playwright'; import { promises as fs } from 'fs'; import path from 'node:path'; import { SocksProxyAgent } from 'socks-proxy-agent'; +// import { chromium } from 'playwright-extra'; // Import from playwright-extra +// import StealthPlugin from 'puppeteer-extra-plugin-stealth' + // sunoApi instance caching const globalForSunoApi = global as unknown as { sunoApiCache?: Map }; @@ -299,6 +302,7 @@ class SunoApi { '--disable-gpu', '--disable-setuid-sandbox'); try { + // chromium.use(StealthPlugin()) const browser = await this.getBrowserType().launch({ args, headless: yn(process.env.BROWSER_HEADLESS, { default: true }), @@ -306,7 +310,14 @@ class SunoApi { server: process.env.PROXY_URL, }}) }) - const context = await browser.newContext({ userAgent: this.userAgent, locale: process.env.BROWSER_LOCALE, viewport: null }); + // const browser = await chromium.launch({ + // args, + // headless: yn(process.env.BROWSER_HEADLESS, { default: true }), + // ...(process.env.PROXY_URL &&{ proxy: { + // server: process.env.PROXY_URL, + // }}) + // }) + const context = await browser.newContext({ userAgent: this.userAgent, locale: process.env.BROWSER_LOCALE, viewport: { width: 1920, height: 1080 } }); const cookies = []; const lax: 'Lax' | 'Strict' | 'None' = 'Lax'; cookies.push({ @@ -314,7 +325,8 @@ class SunoApi { value: this.currentToken+'', domain: '.suno.com', path: '/', - sameSite: lax + sameSite: lax, + }); for (const key in this.cookies) { cookies.push({ @@ -322,7 +334,8 @@ class SunoApi { value: this.cookies[key]+'', domain: '.suno.com', path: '/', - sameSite: lax + sameSite: lax, + secure: true, // Cookies from real browsers are often secure }) } await context.addCookies(cookies); @@ -344,7 +357,17 @@ class SunoApi { logger.info('CAPTCHA required. Launching browser...') const browser = await this.launchBrowser(); const page = await browser.newPage(); + // 1. 在 page.goto 之前设置监听器 + page.on('request', request => { + // 检查请求 URL 是否包含关键词 + console.log('>> Found project API request:', request.url()); + // if (request.url().includes('studio-api.prod.suno.com/api/project/default')) { + // console.log('>> Found project API request:', request.url()); + // } + }); await page.goto('https://suno.com/create', { referer: 'https://www.google.com/', waitUntil: 'domcontentloaded', timeout: 0 }); + //弹出cloudfare验证 + logger.info('Waiting for Suno interface to load'); // await page.locator('.react-aria-GridList').waitFor({ timeout: 60000 }); diff --git a/test.ts b/test.ts new file mode 100644 index 0000000..6ac75ae --- /dev/null +++ b/test.ts @@ -0,0 +1,51 @@ +import { chromium } from 'playwright-extra'; // Import from playwright-extra +import StealthPlugin from 'puppeteer-extra-plugin-stealth' +import yn from 'yn'; + + +const test = async () => { + const args = [ + '--disable-blink-features=AutomationControlled', + '--disable-web-security', + '--no-sandbox', + '--disable-dev-shm-usage', + '--disable-features=site-per-process', + '--disable-features=IsolateOrigins', + '--disable-extensions', + '--disable-infobars' + ]; + chromium.use(StealthPlugin()) + // const browser = await this.getBrowserType().launch({ + // args, + // headless: yn(process.env.BROWSER_HEADLESS, { default: true }), + // ...(process.env.PROXY_URL &&{ proxy: { + // server: process.env.PROXY_URL, + // }}) + // }) + const browser = await chromium.launch({ + args, + headless:false, + proxy: { + server: 'http://127.0.0.1:12334', + }, + }) + const page = await browser.newPage(); + console.log('Testing the stealth plugin..') + await page.goto('https://www.suno.com/creat', { waitUntil: 'networkidle' }) + + // const frame = page.mainFrame(); + // const captchaEl = await frame.$("iframe[src*='hcaptcha.com'], iframe[src*='challenges.cloudflare.com']"); + + const frame = page + .frames() + .find((f) => f.url().includes("hcaptcha.com") || f.url().includes("challenges.cloudflare.com")); + + if (frame) { + console.log("检测到 Cloudflare 验证组件,开始调用 2Captcha..."); + } + + console.log('All done, check the screenshot. ✨') +}; + + +test()