@习猪习
@习猪习
抵抗者运动
关注的小组(5)
动态 帖子 8 评论 106 短评 0 收到的赞 200 送出的赞 60
  1. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    在天安门广场悬挂习近平总书记画像

    习近平总书记是我党继毛泽东同志之后的又一划时代伟人,如果讲毛主席是近代中国的伟大舵手1. 0 ,那么习近平总书记则就是当代中国的伟大舵手2. 0。

    这充分验证了习近平总书记与生具备的天降伟才

    這是加速主義嗎?

  2. 习猪习 抵抗者运动
    习猪习   在小组 站务 回复文章

    2047最上面一栏的颜色为啥是品葱灰

  3. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    【每日翻车新闻搬运】586:使用繁体字入刑,该提上日程了

    内容已删除
    内容已被作者本人或管理员删除。 如有疑问,请点击菜单按钮,查看管理日志以了解原因。
  4. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    由好奇心日報備份計劃教大家備份網站

    @thphd 可以為 code block 加上代碼高亮嗎?

  5. 习猪习 抵抗者运动
    习猪习   在小组 2047 发表文章

    由好奇心日報備份計劃教大家備份網站

    大家好,我是 习猪习 a.k.a. 新品蔥 和 Github 上的 PincongBot。有論壇用戶邀請我搶救性備份 Qdaily 好奇心日報,因此就趁這個機會,淺談一下我一直在做的網站備份,同時手把手地教大家寫一點代碼。

    PincongBot 這個名字來自於小二使用的 TerminusBot

    我寫這篇文章的原意是作為自己的日常筆記,但是希望這能夠成為為 2047 論壇引流的優質內容。

    我先假設讀者們不懂技術,因此我會嘗試使用儘可能直白的語言和代碼為大家解釋。


    和一些人想象的不同,我在備份網站時優先考慮使用的不是爬蟲,而是會尋找是否有 API 可供使用,因為 API 往往可以提供比網頁更多的信息。

    如何找到需要的 API ?

    首先,搜尋 API 文檔。如果網站願意開放 API,都會提供詳細的 API 文檔。

    如果沒有,則尋找頁面發出的異步(和頁面自身不是同時加載)网络请求。

    XHR,或者現代化的 fetch API 請求

    http://www.qdaily.com/articles/65148.html 這一個頁面為例。按 開啟開發者工具中的網路監視器,點選工具條中的 XHR ,以過濾出 XHR 請求。

    將頁面下拉以加載 lazy-loading 的剩餘內容,可以看到幾個 XHR 請求,其中看起來有用的是 http://www.qdaily.com/comments/article/65148/0.json。其中 65148 可以知道是 article id ,0 的意義目前還未知。

    後面知道這個是 :key 分頁索引 時間戳,第一頁為 0 ,下一頁的索引為返回結果中的 last_key 字段

    通過同樣的方法我還找到了下列 API
    http://www.qdaily.com/homes/articlemore/:key.json
    http://www.qdaily.com/tags/tagmore/:tag_id/:key.json
    http://www.qdaily.com/comments/paper/:paper_id/:key.json
    http://www.qdaily.com/labs/papermore/:key.json
    

    吐槽一下,都 2020 年了還沒有部署 HTTPS

    行動端 APP 往往會使用 API 獲取數據,因此讓我們來解包 Android apk

    通過解包 Android apk 檔案(如何解包 apk 就是另外一個話題了,挖坑待填),檢索代碼中的關鍵字,如 api,真的有。

    發現的 API 列表(有些是不能使用的)

    前面都要加上 http://app3.qdaily.com/

    app3/articles/detail/%s.json
    app3/articles/info/%s.json
    app3/authors/index/%s/%s.json
    app3/boot_advertisements.json
    app3/categories/index/%s/%s.json
    app3/column_ads/info/%s.json
    app3/columns/all_columns_index/%s.json
    app3/columns/article_in_all_columns/%s.json
    app3/columns/index/%s/%s.json
    app3/columns/info/%s.json
    app3/comments/create_comment
    app3/devices/android
    app3/feedbacks
    app3/homes/index/%s.json
    app3/homes/left_sidebar.json
    app3/options/mob_create_option
    app3/options/mob_create_praise
    app3/paper/choices
    app3/paper/choices/%s
    app3/paper/choices/result/%s
    app3/paper/tot_results/%s
    app3/paper/tots
    app3/paper/tots/%s
    app3/paper/whos
    app3/paper/whos/%s
    app3/paper/whos/result/%s
    app3/papers/detail/%s.json
    app3/papers/done
    app3/papers/index/%s.json
    app3/praises/create_praise
    app3/radars/index/%s/%s.json
    app3/read_the_statistics
    app3/reads
    app3/searches/post_list
    app3/shares
    app3/subscribes/create_subscribe
    app3/subscribes/remove_subscribe
    app3/tags/index/%s/%s.json
    app3/user_feedbacks
    app3/users/center
    app3/users/comment_on_my
    app3/users/find_password
    app3/users/my_comments
    app3/users/my_praises
    app3/users/my_subscription
    app3/users/paper_detail?paper_id=%s
    app3/users/papers
    app3/users/praise_on_my
    app3/users/praises
    app3/users/profiles/message_number.json?uuid=%s
    app3/users/radar
    app3/users/scan_history
    app3/users/setting
    app3/users/sync_to_phone_praises
    app3/users/sync_to_server_praises
    app3/users/system_message_on_my
    app3/users/tourist_praises
    app3/users/update_my_personal_information
    

    嘗試其中一個,如 http://app3.qdaily.com/app3/authors/index/589058/0.json 。WTF! 這就把行動端的 API 全部暴露給我們了。

    這就是在生產環境將環境變量 (在這裡是 PASSENGER_APP_ENV) 設為 development 忘記改回來的後果。在生產環境中開發調試是一個不好的習慣。

    暴露的 API 中能找到一些對我們有用的。

    使用 API 備份

    準備

    1. 配置 Python3 環境
    2. 安裝依賴
    pip3 install requests
    
    1. 新建 main.py 文件
    2. 編輯 main.py 文件

    代碼中使用到的 request_json, format_user_info, format_category_info, format_article_info, format_comment_info, format_child_comment, write_json 等函數,需要根據需求和實際情況自行實現

    備份文章

    使用的 API 為 /wxapp/articles/info/:id

    為什麼要用這個而不是 /app3/articles/info/:id? 因為它一次性提供的信息最全

    定義 URL 模板

    BASE_URL = "http://app3.qdaily.com"
    ARTICLE_URL_TPL = BASE_URL + "/wxapp/articles/info/{id}"
    

    定義函數 backup_article, 參數為 article_id

    def backup_article(article_id):
        # 用實際的 article id 替換 URL 模板中的 `:id`
        url = ARTICLE_URL_TPL.format(id=article_id)
    
        # API 請求
        json = request_json(url)
        if json is None:
            return
    
        post = json['response']['post']
    
        # 格式化作者信息
        author = format_user_info(json['response']['author'])
    
        # 格式化分類信息
        category = format_category_info(post['category'])
    
        # 格式化文章數據,只保留我們想要的數據
        article = format_article_info(post, author['id'])
    
        ###
        # 寫入文章數據
        ###
        write_json(article)
    
        ###
        # 寫入作者信息
        ###
        write_json(author)
    
        ###
        # 寫入分類信息
        ###
        write_json(category)
    

    恰巧文章的 id 是遞增的整數。我們用暴力方法,備份所有文章(因為一些文章根本就不會出現在文章索引中)

    我們需要從 article id 為 1 開始嘗試備份,一直到目前最新的 65270

    因此寫一個 for range 循環

    for article_id in range(1, 65270+1):
        backup_article(article_id)
    

    備份文章評論

    使用的 API 為 /wxapp/comments/index/:comment_type/:id/:last_key,其中 :last_key 是分頁索引,第一頁為 0 ,下一頁的索引為返回結果中的 last_key 字段

    定義 URL 模板

    COMMENT_URL_TPL = BASE_URL + "/wxapp/comments/index/{comment_type}/{id}/{last_key}"
    

    定義函數 backup_comments, 參數為 parent (backup_article 中的 article 文章數據)

    def backup_comments(parent):
        last_key = 0  # 分頁索引第一頁為 0
    
        # 不斷備份下一頁,直到跳出循環
        while True:
            url = COMMENT_URL_TPL.format(
                comment_type=parent['type'], id=parent['id'],
                last_key=last_key
            )
    
            json = request_json(url)
            comments = json['response']['comments']
    
            # 處理這一頁上的每一個評論
            for c in comments:
                # 格式化作者信息
                author = format_user_info(c['author'])
                # 格式化評論數據
                comment = format_comment_info(c)
                # 寫入作者信息
                write_json(author)
                # 寫入評論數據
                write_json(comment)
                # 備份子評論
                for cc in c['child_comments']:
                    # 寫入子評論數據
                    write_json(format_child_comment(cc))
                    # 寫入子評論的作者信息
                    write_json(format_user_info(cc['author']))
    
            # 有更多評論 (分頁)
            if json['response']['has_more']:
                # 下一頁的分頁索引為返回結果中的 last_key 字段
                last_key = int(json['response']['last_key'])
                # 備份下一頁
                continue
            else:
                # 沒有更多頁了
                # 跳出循環
                break
    

    backup_article 函數的最後加上

        if article['comment_count'] > 0:
            backup_comments(article)
    

    備份圖片

    由於圖片都儲存在好奇心日報主站的服務器上,如果主站挂了,圖片就全部丟失了。

    這是小二曾提出的問題

    其中一種解決方案是,在格式化文章數據時,使用 正則表達式 查找正文中的圖片,非阻塞地下載並保存

    備份好奇心研究所

    TODO



    備份的成果在 https://github.com/PincongBot/qdaily ,欢迎 star 和 fork 。

  6. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    明天是國殤日,大家有什麼想說的嗎?

    我認為的國殤日是4月23日首都南京淪陷

  7. 习猪习 抵抗者运动
    习猪习   在小组 站务 回复文章

    对本站换行的设计有个小建议

    等站長配置一下 markdown parser,設置將換行 \n 轉換為 HTML 的 <br> 就可以了
    python-markdown2 就有 break-on-newline 設置

  8. 习猪习 抵抗者运动
  9. 习猪习 抵抗者运动
    习猪习   在小组 站务 回复文章

    (已废除)隐私声明

    2049bbs 早期(2019-10-21 前)是提供精确到分钟的注册和发帖时间的,备份了下来。之后的注册时间就属于备份时带的私货,因为每15/20分钟整站备份一次,所以可以精确到15/20分钟之内

  10. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    微信公众号-备份及存档

    哇,欣賞你的高效率

  11. 习猪习 抵抗者运动
  12. 习猪习 抵抗者运动
    习猪习   在小组 2047 发表文章

    大家好,我是 2049bbs 备份的作者

    既然論壇中有用戶已經知道了,這件事没有什么值得隐瞒的,我是 2049bbs.github.io 的备份者。

    首先感谢站长 @thphd 能够利用好我的备份数据,恢复论坛。

    没事儿,论坛源码在这里,……把站长抓了,总有一个站友站出来,……2050bbs再续前缘。

    如果不是有 2049bbs 的近乎完整的公開備份數據,加上站長的無私努力,很難想象能否在 2049bbs 关闭後,在這裡再次與大家相見。

    2018年9月牆外樓关闭,10月30日,品葱爆破。一周多后的11月8日,旧膜乎 (mohu.club) 关闭了。2019年1月香港人站長的奇闻录也迫於壓力关站(不知多少人還記得這幾個網站)。很可惜,大部分數據沒能留存下來,煙消雲散了,只能从网页快照中恢复一些断垣残壁,心痛。所以對於任何一個抵抗者網站來說,在網站還正常運行的時候,就嘗試去備份它!能夠用及时的数据恢复完整内容,非常重要。

    我非常希望站長 @thphd@NodeBE4@沉默的广场@Resistance ,我 ,還有任何有能力/有技術的同僚,可以一起合作完成一項有意义的开源项目。


    To @九頭鳥@NodeBE4,我自己,和所有不是共匪國安網警的用戶

    無論是誰,有著共同目標的大家請間放下一切的猜疑、指責、内斗,坦诚相见。 我们共同的敌人是共匪的專制暴政,而抵抗者们原子化、散沙化是共匪乐意看见的。

  13. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    〖每日微博谈搬运〗2020/9/20:中共狱警收入何以高出普通公务员数倍?

    内容已删除
    内容已被作者本人或管理员删除。 如有疑问,请点击菜单按钮,查看管理日志以了解原因。
  14. 习猪习 抵抗者运动
    习猪习   在小组 站务 回复文章

    2047论坛 数据库备份

  15. 习猪习 抵抗者运动
  16. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    初到貴境,淺談啓蒙反專制的三個邏輯認知

    專制政權一切的統治基礎在於謊言,只要謊言被世人識破,專制政權也就再也無法取得普遍民眾和武裝力量的積極支持

  17. 习猪习 抵抗者运动
    习猪习   在小组 站务 回复文章

    页面每隔一段时间 ping 服务器的意义是什么?

    @20202047 #13818145 setTimeout的 call signature 是 (callback, ms, ...args),所以應該是

    setTimeout(() => document.getElementById('editor_btnsubmit').click(), 1000000)
    
  18. 习猪习 抵抗者运动
  19. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    为端点星案蔡伟和陈玫写中秋贺卡

  20. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    为端点星案蔡伟和陈玫写中秋贺卡

    字很好看,有特别练过吗?

  21. 习猪习 抵抗者运动
  22. 习猪习 抵抗者运动
  23. 习猪习 抵抗者运动
    习猪习   在小组 站务 回复文章

    (已废除)隐私声明

    @thphd #14093060 请正面解释这是什么的 log?为什么找不到相关代码,是因为代码不是全部开源的,还是因为代码在某一次提交中被移除了?

  24. 习猪习 抵抗者运动
  25. 习猪习 抵抗者运动
    习猪习   在小组 站务 回复文章

    (已废除)隐私声明

  26. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    【端点星案】端点星志愿者将于9月21日前被起诉

    内容已删除
    内容已被作者本人或管理员删除。 如有疑问,请点击菜单按钮,查看管理日志以了解原因。
  27. 习猪习 抵抗者运动
    习猪习   在小组 站务 回复文章

    (已废除)隐私声明

    原2049也对这个时间做了记录
    

    2049bbs 不提供注册时刻,只有注册日期

  28. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    当小明遇上DNS污染

    内容已删除
    内容已被作者本人或管理员删除。 如有疑问,请点击菜单按钮,查看管理日志以了解原因。
  29. 习猪习 抵抗者运动
    习猪习   在小组 站务 回复文章

    页面每隔一段时间 ping 服务器的意义是什么?

    @thphd #13755187 既然 2047 继承了 2049bbs,尊重 2049bbs 的传统,就不该为了追求流量,做个性化推荐

  30. 习猪习 抵抗者运动
    习猪习   在小组 江湖 回复文章

    当局已经放弃通过Tor爬取本站

    tor 上爬虫对于服务器的实际影响有多少(如果还远不到 DoS 的级别),为什么站长要费心防爬?

  31. 习猪习 抵抗者运动
    习猪习   在小组 江湖 回复文章

    当局已经放弃通过Tor爬取本站

    @thphd #13864835 如果对方用的是 headless 的 Tor Browser ,怎么检测?

  32. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    【端点星案】端点星志愿者将于9月21日前被起诉

    内容已删除
    内容已被作者本人或管理员删除。 如有疑问,请点击菜单按钮,查看管理日志以了解原因。
  33. 习猪习 抵抗者运动
  34. 习猪习 抵抗者运动
    习猪习   在小组 江湖 回复文章

    当局已经放弃通过Tor爬取本站

  35. 习猪习 抵抗者运动
    习猪习   在小组 站务 回复文章

    测试网站是否被中国屏蔽的一些工具

    「我國萬事不進步,而獨防民之術乃突過於先進國,此真可為痛哭也。」
    
  36. 习猪习 抵抗者运动
    习猪习   在小组 站务 发表文章

    页面每隔一段时间 ping 服务器的意义是什么?

    • 如果是为了显示右下角的连接时间 ms ,那么零次或者一次足矣
    • 如果是为了分析页面停留时间,那么动机……
  37. 习猪习 抵抗者运动
    习猪习   在小组 江湖 回复文章

    当局已经放弃通过Tor爬取本站

    如果我是爬虫者,如何确保数据库备份的质量和频率稳定?
    隔壁新品葱自从小二出事后,https://gitlab.com/pin-cong/data 的每周数据备份就没了

  38. 习猪习 抵抗者运动
    习猪习   在小组 江湖 回复文章

    当局已经放弃通过Tor爬取本站

    处理用户数据的理念不同,站长请见谅

  39. 习猪习 抵抗者运动
    习猪习   在小组 江湖 回复文章

    当局已经放弃通过Tor爬取本站

    既然备份都可以下载,那么站长将之前的备份都删除,只留最新版本的意义是什么? 如果是出于删帖隐私保护的考量,匿名网站做好隐私保护应该是用户自己的事

  40. 习猪习 抵抗者运动
    习猪习   在小组 江湖 回复文章

    当局已经放弃通过Tor爬取本站

    @thphd #13503668 希望站长可以将备份频率提高一些,丢失一天的数据对于用户来说都是损失

  41. 习猪习 抵抗者运动
    习猪习   在小组 江湖 回复文章

    当局已经放弃通过Tor爬取本站

    比起下流事做尽的共匪,我认为正常人更需要隱藏自己,不过爬虫完全可以用免费的 CI 服务

  42. 习猪习 抵抗者运动
    习猪习   在小组 江湖 回复文章

    当局已经放弃通过Tor爬取本站

    为什么爬站就一定是匪共的人,站长不就是靠别人爬虫的数据恢复了 2049bbs 的大部分内容的吗?

  43. 习猪习 抵抗者运动
    习猪习   在小组 2047 回答问题

    跑了7个衙门,备案终于搞定了

    支持在五道口公司内建立党的领导

  44. 习猪习 抵抗者运动
    习猪习   在小组 2047 回答问题

    跑了7个衙门,备案终于搞定了

    支持站长依法建站

  45. 习猪习 抵抗者运动
  46. 习猪习 抵抗者运动
    习猪习   在小组 2047 回复文章

    网站建设,应该以用户为中心,还是以网站理念为中心?

    以网站理念为中心才能尽可能避免出现人治

  47. 习猪习 抵抗者运动
    习猪习   在小组 江湖 回复文章

    怎么墙外中文网站这么多破事

    @BE4 现在在 2047 吗?

  48. 习猪习 抵抗者运动
    习猪习   在小组 江湖 回复文章

    怎么墙外中文网站这么多破事

    2049bbs像是超大型集市中的一个小茶馆。用户非常成熟独立,大部分时候在各自领域活动,偶尔来分享一下新发现和有趣的资源,但对2049bbs并无平台依赖。2049bbs则扮演一个精华资源的集散地,帮助这个小茶馆的过客拓展在整个互联网大集市中的视野,让用户更独立更成熟。这样一种完全开放、个人主义的建站思想我个人是非常推崇的。
    
    某些论坛那样创造封闭空间、传销式拉人头,霸占用户的信息获取和交流带宽,目的是让用户对平台产生依赖,最终让用户群变成观点类似的封闭社区。这种遵循集体主义思维创立的论坛,我本身就无比反感,至于其在封闭体系下放纵职业五毛对公民发动战争的行为,更是让人感到生理不适了。
    

    http://terminusnemheqvy.onion/t/1190#2270694 作者是 @BE4

  49. 习猪习 抵抗者运动
  50. 习猪习 抵抗者运动
    习猪习   在小组 江湖 回复文章

    刚刚临时切换机房(附:CF错误码详解)

    每次网站 5xx 都会担心人出事。小二的事已经过去五个月了