由于长期受剽窃和盗用的困扰,很久之前就想过是否能采取一些措施来反抄袭和反剽窃。最近 51CTO 的官方剽窃真是恶心到我了(详情参见我的上一篇文章《51CTO,一个抄袭剽窃的流氓网站!》),最终我决定得行动起来了。
先说一下整体思路,由于是反抄袭和反剽窃,我不能介绍地过于细致,涉及到技术部分就是需要使用某类工具定期登录我的博客,执行一些必要的操作,我需要把这些自动化的操作写成脚本,然后放到某种作业调度工具中定期执行。
经过初步的筛选,我选择了 Playwright + GitHub Actions 的技术方案,简单、轻量、完全第三方托管且无费用(免额度已经可以支撑日常运行),本文先简单介绍一下 MVP 的实现细节。
1. 安装 Node.js
首先,去 https://nodejs.org/en 下载 node.js 的安装包,并完成安装。这里就不赘述了。
2. 创建工程目录
找一个合适的位置,创建一个空目录作为工程根目录,这是我们取名为csdn-bot
3. 初始化工程脚手架
Playwright 官方提供有 Playwright 项目的脚手架,使用命令可一键创建出一个 Playwright 项目,命令如下:
npm init playwright@latest默认生成的 Playwright 项目在工程根目录下有一个tests目录,目录下还会自动生成一个example.spec.ts文件,使用以下命令可以直接执行这个测试脚本:
npx playwright test但实际上,我们不会使用这种单元测试风格的方式去执行我们的脚本,尽管可以保留着自动生成的资源,但为了使用项目简洁干净,建议还是删除以下文件夹或文件:
- tests 目录
- playwright.config.ts
4. 安装 tsx
如果,我们不想总是以单元测试的方式书写我们的脚本,而是要编写并执行正式的脚本,那需要提前安装一下 tsx,它是 TypeScript 的一个运行时(Runtime),让你可以像运行 JavaScript 一样直接运行 .ts 文件,而不用先手工编译。
npm install -D tsx-D是指明:要安装的属于开发工具,不是运行时依赖。
5. 添加独立脚本
在工程目录下添加一个src文件夹,然后添加一个简单的main.ts文件,内容如下:
import{chromium}from'playwright';asyncfunctionmain(){constbrowser=awaitchromium.launch({headless:true});constpage=awaitbrowser.newPage();// 打开登录页awaitpage.goto('https://passport.csdn.net/login?code=applets');console.log(awaitpage.title());awaitbrowser.close();}main().catch(err=>{console.error(err);process.exit(1);});同时,我们还要配置 GitHub Actions 的工作流,工作流的描述文件在使用npm init playwright@latest初始化项目时已经自动创建,位置是.github\workflows\playwright.yml,我们把它修改为如下内容:
name:csdn-boton:workflow_dispatch:jobs:run:runs-on:ubuntu-lateststeps:-uses:actions/checkout@v4-uses:actions/setup-node@v4with:node-version:24-run:npm ci-run:npx playwright install chromium-run:npm run start6. 修改配置
为了配合脚本的执行,我们需要对自动生成的tsconfig.json做几处改动:
在
package.json中,将"scripts": {}改为:"scripts":{"start":"tsx src/main.ts"}上述改动将允许我们使用
npm run start来运行 main.ts在
package.json中,将"type": "commonjs"改为"type": "module",否则,在 IDE 中会报:TS1295: ECMAScript imports and exports cannot be written in a CommonJS file under ‘verbatimModuleSyntax’. Adjust the ‘type’ field in the nearest ‘package.json’ to make this file an ECMAScript module, or adjust your ‘verbatimModuleSyntax’, ‘module’, and ‘moduleResolution’ settings in TypeScript.
在
tsconfig.json中,将"types": []改为"types": ["node"],否则,在 IDE 中会报:TS2591: Cannot find name ‘process’. Do you need to install type definitions for node? Try npm i --save-dev @types/node and then add ‘node’ to the types field in your tsconfig.
7. 运行项目
在项目根目录下,使用执行:
npm run start看到输出:
CSDN-专业IT技术社区-登录就表示项目的原型已经跑通了。
然后,把项目提交到 GitHub 上,在项目主页的 tab 页中找到 Actions 标签页,然后会看到我通过.github\workflows\playwright.yml定义的工作流,名称是csdn-bot,选中这个工作流点击Run按钮即可,在 Job Run 页面中看以看作业的每一个执行步骤以及相关的内容输出,这可以辅助我们了解工作流是否执行成功:
8. 关于登录的初步探索
前面的都是较为基本的操作,比较大的挑战是通过登录获得身份认证。通常有如下几种处理方式:
- 最直白的方案:模拟用户登录操作,输入用户名和密码进行登录。但对于有图片验证码的网站来说,这种方法不可行;
- 使用 Playwright 以非无头方式(
headless: false)打开一个浏览器,手抖完成登录操作,然后在 Playwright 脚本中保存整个浏览器状态(一个 json 文件,包含 cookie 等信息),然后在正式的自动化脚本中先 load 这个 json 数据,获得身份认证数据,再完成其他页面操作。该方法被认为是一种较为稳妥的方案,但是一些网站的风控系统能识别出浏览器是一种自动化的环境,进而在第一步登录时就失败了,CSDN 就是这类情况 - 使用 Playwright 直接读取本地 Chrome 用户目录,但同样的,一些网站依然能识别出这种情形从而拒绝用户登录
目前先探索到这里,做一个简要的记录。后面根据需要看要不要再进一步研究。