LOADING

加载过慢请开启缓存 浏览器默认开启

基于PyWebview与Selenium的智慧树脚本系统踩坑开发日志(二)—— 解决shadow-root反爬

2024/9/25 智慧树脚本 智慧树脚本 selenium 该文总阅读量

基于PyWebview与Selenium的智慧树脚本系统踩坑开发日志(二)—— 解决shadow-root反爬

解决shadow-root反爬(2024-9-23)

直接说最终解决方案,shadow-root鄙人是不可能爬得到了,我还是老老实实用ocr吧,最后找到一个非常不错的轻量级ocr

采用Cnocr识别题目文字

配置

CnOcr
onnxruntime

image-20240925222645169

pip下载这两个包就行,官方包是提供自动下载模型的,但是我这个最后要打包,必不可能让用户自己下载,直接用相对路径改了就行,而且并不是很想下载模型到C盘

使用

base_path = os.getcwd()
relative_path = 'Ocr_Model'
custom_model_path = os.path.join(base_path, relative_path)
os.environ['CNOCR_HOME'] = custom_model_path
ocr = CnOcr(
    det_model_name='naive_det',
    rec_root='/Model/Ocr_Model/cnocr',  # 自定义识别模型存储目录
    det_root='/Model/Ocr_Model/cnstd'  # 自定义检测模型存储目录
)

naive_det参数识别这种标准的矩形文字十分快,就是初始化需要一点时间,初始化完成后识别的速度基本上和爬取的速度没什么差别

测试

image-20240925223833962

基本上不会出很大的问题,而且模型大小只有十几M,非常轻量,最终选择了OCR

最初的方案(2023-4-23)

前端“shadow-root(closed)”反爬

image-20240925220736055

在用自动答章节测试系统中,本想爬取页面中的题目名称,再用题目名称去sqlite对应表中查找对应的题目名称如图所示,但遇到如图的反爬代码

image-20240925220814046

在经过无数次的失败后例如执行javascript脚本,访问vue的虚拟dom,暴力破解shadow-root(closed)源码,利用opencv截图导出对应文本…(在github上有大佬有软件可以获取,但版本较老,无法移植)最后查找资料中找到如图4.1.3-3所示,该反爬措施无法被dom挂载,无法修改,无法获取,无法访问…至少以我目前的实力碰到该元素等于 绝望,最后将算法修改为直接从数据库拿出该章节的答案,将答案按顺序将对应的选项勾选。

新的方案(2024-6-23)

后面重构代码的时候在stack-overflow上有个解决方案,python - How to locate element in shadow-root (closed) host - Stack Overflow,它的思路大概是这样的,既然shadow-root元素已经无法抓取,那么就刷新页面写入js让它能够抓取,想法很美好

image-20240925221445871

哈哈,丸辣,官方应该是做了判断,只要shadow-root被打开就意味着有脚本,这个还真挺好检测,但是鄙人也想不出什么解决办法了,另外再提一下这个脚本的使用,虽然对智慧树没用,但是对其他没有反爬的网站应该还是有点用的。

injected.js

Element.prototype._attachShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = function () {
    console.log('attachShadow');
    return this._attachShadow( { mode: "open" } );
};

manifest.json

{
    "name": "SeleniumTesting",
    "description": "Extension to open closed Shadow DOM for selenium testing",
    "version": "1",
    "author": "cy",
    "manifest_version": 2,
    "permissions": [
        "downloads",
        "<all_urls>"
    ],
    "content_scripts": [
        {
            "matches": [
            "https://onlineexamh5new.zhihuishu.com/*",
            "https://onlineweb.zhihuishu.com/*"
        ],
            "run_at": "document_start",
            "all_frames": true,
            "js": [
                "shadowInject.js"
            ]
        }
    ],
    "web_accessible_resources": [
        "injected.js"
    ]
}

matches里面的内容需要改网络地址的前缀

shadowInject.js

const injectedScript = document.createElement('script');
injectedScript.src = chrome.extension.getURL('injected.js');
(document.head || document.documentElement).appendChild(injectedScript);