V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
gezimonkey
V2EX  ›  Python

请教一个反爬的技术

  •  
  •   gezimonkey · 2023-01-10 11:44:00 +08:00 · 5301 次点击
    这是一个创建于 708 天前的主题,其中的信息可能已经有所发展或是发生改变。

    新加坡联合早报 https://www.zaobao.com/
    新闻详情页面采用了一种没见过的技术应对复制与爬虫
    例如 https://www.zaobao.com/news/china/story20230110-1351792

    在 P 标签内加入了 data-s="yGMGEZQ===="这种标签,导致页面看起来段落顺序是正确的,但复制,或者爬取,就是错的 请大神指点一下

    22 条回复    2023-01-16 12:27:19 +08:00
    viewrules
        1
    viewrules  
       2023-01-10 11:59:32 +08:00   ❤️ 1
    html 里的结构和视觉效果的结构不一致,这种你要打断点研究排序的那个方法,反向还原
    xiaopc
        2
    xiaopc  
       2023-01-10 12:05:04 +08:00   ❤️ 2
    Eiden
        3
    Eiden  
       2023-01-10 13:21:15 +08:00   ❤️ 4
    根据 data-s 标签算出来的排序, 感兴趣且有时间的可以跟进去看看, 混淆了有点费时间, o 值就是正常的顺序
    wangxiaoaer
        4
    wangxiaoaer  
       2023-01-10 13:40:34 +08:00
    这玩意儿是不是一个无头浏览器就解决了?
    sparklee
        5
    sparklee  
       2023-01-10 13:47:30 +08:00
    @wangxiaoaer +1, 就是需要在获取到数据之后浏览器执行一遍 js 重新排序
    yang3121099
        6
    yang3121099  
       2023-01-10 13:49:45 +08:00
    @Eiden 所以是数组定义了一层映射来打乱段落的顺序吗,确实直接复制段落就会隔三差五的,第一次见 hhh
    guaguaguaxia1
        7
    guaguaguaxia1  
       2023-01-10 13:57:24 +08:00
    @wangxiaoaer 爬虫一般都不用浏览器的,效率极低
    gezimonkey
        8
    gezimonkey  
    OP
       2023-01-10 14:36:28 +08:00
    @wangxiaoaer 我尝试过了,Firefox 无法获得 html 内容,chrome 获得的同样是乱序
    lkwfive
        9
    lkwfive  
       2023-01-10 14:55:04 +08:00
    浏览器截图 + OCR
    BeforeTooLate
        10
    BeforeTooLate  
       2023-01-10 14:57:04 +08:00
    那这样是否意味着搜索引擎也无法收录了?
    blankmiss
        11
    blankmiss  
       2023-01-10 14:58:08 +08:00
    @lkwfive 这样效率是不是太慢了 况且 ocr 还有识别不精准的问题,但确实是一种解决方法(狗头
    leaflxh
        12
    leaflxh  
       2023-01-10 15:01:56 +08:00
    (右键可以复制全文
    bluedawn
        13
    bluedawn  
       2023-01-10 15:13:14 +08:00 via iPhone
    没研究过但是
    不妨看看 rsshub 对联合早报的 rss 爬取策略?
    如果只是想获取新闻内容
    likeme
        14
    likeme  
       2023-01-10 15:16:18 +08:00
    @guaguaguaxia1 不用浏览器用什么?好奇...
    corcre
        15
    corcre  
       2023-01-10 15:22:24 +08:00
    @likeme 我只知道无头浏览器, 如果他说的不是无头浏览器的话我也很好奇这种需要执行 js 去计算 DOM 的内容要怎么抓取...
    jishuliu
        16
    jishuliu  
       2023-01-10 15:44:44 +08:00
    @Eiden 把这个老哥的函数给扣下里就好了,i.default.d 扣下来本地跑 js 代码解析 data-s
    chenzhe
        17
    chenzhe  
       2023-01-10 15:58:59 +08:00
    const axios = require("axios");
    const cheerio = require("cheerio");

    axios.get("https://www.zaobao.com/news/china/story20230110-1351792").then(res => {
    const $ = cheerio.load(res.data)
    const context = []
    $("#article-body").children().each((i, el) => {
    if (i > 0 && $(el).text() !== "") {
    context.push($(el).text())
    }
    })
    console.log(context.join("\n"))
    })
    getcharch
        18
    getcharch  
       2023-01-10 16:05:01 +08:00   ❤️ 7
    https://cmd.im/pmhr

    关键代码 传入参数 data-s.substring(3)
    ```
    d = function (e) {
    var t, n, o, i = e["length"], s = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=", l = 0, u = 0, c = "";
    e = e["toUpperCase"]();
    for (var d = 0; d < i; d += 1)
    (t = s["indexOf"](e["charAt"](d))) >= 0 && t < 32 && (n = n << 5 | t, u += 5, u >= 8 && (o = 255 & n >> (u - 8), c = (c + String["fromCharCode"](o)), u -= 8));
    if ((u > 0) && (o = (n << (8 - u) & 255) >> (8 - u), (o !== 0))) {
    c = c + String.fromCharCode(o)
    }
    return c
    }
    ```
    jishuliu
        19
    jishuliu  
       2023-01-10 16:11:02 +08:00
    @getcharch 大佬牛逼,能分享一下定位用的工具和思路吗
    ripperts
        20
    ripperts  
       2023-01-10 16:39:14 +08:00
    简单看了下就是 data-s 字符串截取 3 位,然后 base32 加码就行了。
    比如,data-s="6qsGE3A====" 然后 base32 解码 GE3A==== 直接返回 16
    随便找了个在线解码: https://www.usetoolbar.com/developer/base32.html

    试试吧,没仔细确认
    gezimonkey
        21
    gezimonkey  
    OP
       2023-01-10 16:41:37 +08:00
    @getcharch 大佬你就是生产力!!!
    NoOneNoBody
        22
    NoOneNoBody  
       2023-01-16 12:27:19 +08:00
    @likeme #14
    @corcre #15
    如果要爬取的内容是完整文字,js 只是用于渲染和排版,可以摒弃 DOM ,直接用正则,按自己规则重建排版

    其实爬取万级以上页面,每页建 DOM(即使非 js)搜索和正则搜索,耗费资源差别很大,正则快很多
    两者各有优劣,如果内容边界随机,例如随机的 class name 样式,正则要确定内容的位置不容易,要一定技巧,dom 就可以简单地用 path 就能找到
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2309 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 16:10 · PVG 00:10 · LAX 08:10 · JFK 11:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.