zoukankan      html  css  js  c++  java
  • 爬虫技能之内容提取:如何从有不可见元素混淆的页面中抽取数据

    概述

    之前在知乎上看到有人分享的一个有趣的反爬策略:

    image

    那个变态混淆页面源码是这个样子的,正文内容穿插在混淆元素中:

    image

    看到这么变态的页面结构很感兴趣于是就尝试解析了一下。

    知乎分享地址:有哪些有趣的反爬虫手段? - 阿阿聪的回答 - 知乎

    微信变态混淆页面地址:过年同学聚会,到底该不该去?

    分析 & 实现

    对于这种一般都是在选择器中过滤掉不可见的元素就可以了,对于不可见元素目前遇到过并解决掉的两种情况:

    1. 通过display:none;来隐藏(全网代理公开ip爬取(隐藏元素混淆+端口加密)

    2. 通过透明度和偏移来隐藏,比如opacity: 0;虽然元素透明了但是在盒子模型中还是占用了空间的,会把旁边挤开太明显了所以就需要再margin偏移一下将其占用空间释放掉。

    实际上两种方式还是有区别的,display:none;的内容复制不会被影响,复制到的是看到的内容,opacity:0; 并偏移的复制的话会把混淆元素的内容也带上,复制到的并不是看到的内容。

    这个微信页面就是第二种方式,来看下它的套路:

    <span style="margin-right: -1em; max- 100%; opacity: 0; box-sizing: border-box !important; word-wrap: break-word !important;">钔</span>

    先通过opacity:0;将自己变成透明的,然后使用margin-right:-1em;将占用的位置腾出来。

    思路就是遍历整个DOM树手动过滤收集,下面是一个简单的实现,只是将文本内容抓取没有保存样式和图片:

    """
    微信不可见元素混淆页面内容解析
    https://mp.weixin.qq.com/s?__biz=MzI0MDYwNjk2OA==&mid=2247484365&idx=4&sn=291a93e8a4ce6e90d3b6ef8b98fe09c4&chksm=e919085ade6e814cc037ecf6a873f22da0e492911a4e539e6f8fdeff022806b4d248c4d54194&scene=4
    """
    import requests
    import bs4
    
    
    def get_html(url):
        return requests.get(url).content.decode('UTF-8')
    
    
    def dfs_extract_text(tag):
        result_content = ''
        for child in tag.contents:
            if type(child) == bs4.NavigableString:
                result_content += child
            elif 'style' not in child.attrs or 'opacity: 0;' not in child.attrs['style']:
                # 过滤掉透明元素,要么没有style属性,要么style属性中不包含透明样式,否则认为是透明元素直接忽视掉
                result_content += dfs_extract_text(child)
        return result_content
    
    
    def parse(url):
        html_content = get_html(url)
        page = bs4.BeautifulSoup(html_content, 'html.parser')
        content_panel = page.find(id='js_content')
        return dfs_extract_text(content_panel)
    
    
    if __name__ == '__main__':
        target_url = 'https://mp.weixin.qq.com/s?__biz=MzI0MDYwNjk2OA==&mid=2247484365&idx=4&sn=291a93e8a4ce6e90d3b6ef8b98fe09c4&chksm=e919085ade6e814cc037ecf6a873f22da0e492911a4e539e6f8fdeff022806b4d248c4d54194&scene=4'
        content = parse(target_url)
        print(content)

    程序运行结果:

    昨晚回来晚了,是因为我去参加了一个同学聚会,回来后已经夜里十一点多了。这个聚会:并没有想象中那么亲近,也没有传说中的那么美好,更没有当年时的那种纯粹。给我整体的感觉就是六个字:人很累,心很悲 !原因有三个:第一个原因: 你念念不忘的过去,别人已经忘得一干二净了。我和一个女同学上学时很要好(也许只是我的以为,她未必这么认为),那时因为学校离家远,中午放学我们都不回家,就在学校里吃点从家里带来的饭菜。多年以来,和她之间在我脑海中最清晰的画面,就是吃过简单凑合的午饭,我们手牵手围着硕大的操场一圈又一圈的走,有时谈笑,有时打闹,有时就那么静静,静静的牵手走着……昨晚,我向她提起了这段对于我来说,最难忘最深刻最眷恋的记忆。她却给了我最具杀伤力最具毁灭性的一个回答:我都忘了!!!瞬间,我再也没有聊下去的欲望,索然无味……第二个原因: 我们都被经历戴上了面具,被现实披上了虚伪,再也没有上学时的纯粹!尽管是高档的饭店,晶亮的酒杯,我却觉得抵不上年少时你用零花钱买给我的一颗两毛钱的雪糕,一份自己笨手笨脚做的生日礼物。聚会里面有一个同学经历非常坎坷(我们都知道),他却笑得没心没肺,我们明白他在坚强面对。如果和一群老同学,都要装,都要扛,都要说自己无所谓,那还有什么时候,什么朋友,能让一个人打开心扉 ? ?莫名的感到悲哀:曾经的感情只能留给曾经,过去的记忆只能住在过去。老同学之间,没有共同的未来 !第三个原因: 我们都还是原来的那个人,却没有了原来的那颗心。漫长的岁月肯定改变了我们的容貌,不过仔细分辨,我们都能认出来彼此,眉眼,笑容,举止,习惯,年少时的记忆总是那么的深刻,那么的不可磨灭。最可怕的事:不是岁月让一个人变胖了,变老了,变得外表不一样了,而是,它改变了一个人是非分明的心,一个人错对分清的心,一个人向善护弱的心!混得好的,高谈阔论,一大群人追捧围绕着;混得不好的,沉默不语,一大群人敷衍冷淡着!上学时的我们,没有层次,没有高低,没有等级之分的,因为我们是处在同一个起跑线的。现在的我们,再不是当初了……别再妄想着:彼此亲密无间,没有距离,别再奢望着:彼此畅所欲言,没有顾忌!我们说着交际的话,喝着应酬的酒,带着应付的笑,却再也走不进彼此的心……如今的同学聚会,聚的只能是一群的人,而不是一众的心了;如今的同学聚会,聚的只能是外放的笑声,而不是内在的心声了;如今的同学聚会,聚的只能是重逢的酒菜飘香,散场后的感触凄凉 !—《END》—
    

    优点 & 缺点

    使用这种方式渲染出的页面,当我复制网页内容并粘贴到别处的时候:

    image 

    悲剧啊,我复制出来的内容包括了不可见元素的内容,这可以说是一把双刃剑吧,如果作为一个遵纪守法的正常用户我感觉很无辜,为毛我复制到的内容不是我看到的内容呢,这啥破网站啊,这是网站方不希望看到的。但是如果对面的是爬虫的话,一个不小心就会造成这种后果:
    image 

    这恐怕是网站方喜闻乐见的…

    具有同样特性的还有自定义字体反爬,欲知详情且听下回分析。

    .

  • 相关阅读:
    Time Zone 【模拟时区转换】(HDU暑假2018多校第一场)
    HDU 1281 棋盘游戏 【二分图最大匹配】
    Codeforces Round #527 (Div. 3) F. Tree with Maximum Cost 【DFS换根 || 树形dp】
    Codeforces Round #527 (Div. 3) D2. Great Vova Wall (Version 2) 【思维】
    Codeforces Round #527 (Div. 3) D1. Great Vova Wall (Version 1) 【思维】
    Codeforces Round #528 (Div. 2, based on Technocup 2019 Elimination Round 4) C. Connect Three 【模拟】
    Avito Cool Challenge 2018 E. Missing Numbers 【枚举】
    Avito Cool Challenge 2018 C. Colorful Bricks 【排列组合】
    005 如何分析问题框架
    004 如何定义和澄清问题
  • 原文地址:https://www.cnblogs.com/cc11001100/p/8766632.html
Copyright © 2011-2022 走看看