批量下载自己的随笔

文档说明:只记录关键地方; 2023-04-15

缘由和意义:

东西都在自己手里,平台倒闭还可以迁移

数据永远在自己手里,发什么都有自主权

可以避免人为刀俎,我为鱼肉的情况

无广告、自主可控、打造自己的品牌、高度定制化

知道为啥大家自己买硬盘了吧 (网盘行业大家有目共睹)

为啥写: 汲取了知识,同时也需要回馈,相互促进的关系

破除知识优越感 !

破除知识诅咒 !

copyleft !

下载自己随笔的脚本

都是使用markdown 写的,下载就方便了很多

办法一: 控制台注入javascript 直接就可以下载
办法二:浏览器扩展注入javascript 直接就可以下载
办法三: python3 直接抓取
办法四: python3 注入javascript
办法五: python3 浏览器扩展注入javascript
办法六: 上述办法混合使用

实操原理图

实操

准备数据源

打开地址: https://i.cnblogs.com/posts
把每页显示随笔数 设置为最大值
打开web控制台,输入如下代码
浏览器右上角 允许下载随笔索引文件
通过查看控制台: 发现还有更简单的 https://i.cnblogs.com/api/posts/list?p=1&cid=&t=1&cfg=0&search=&orderBy=&s=80&scid=

{

    function createJSONFile(content, filename) {
        let blob = new Blob([JSON.stringify(content)], {type: "application/json"});
        let url = window.URL.createObjectURL(blob);
        let a = document.createElement("a");
        a.style.display = "none";
        a.href = url;
        a.download = filename;
        a.click();
        setTimeout(function () {
            window.URL.revokeObjectURL(url);
        }, 3000);
    }

    let list = []
    let pattern = /^\/posts\/edit;postId=(\d+)$/
    let download_url_prefix = 'https://www.cnblogs.com/jingjingxyk/p/';
    document.querySelectorAll('.cnb-table table tbody tr').forEach((value, key, parent) => {
        let title_link = value.querySelector('.post-title-appendix')
        let title_content = value.querySelector('.post-title-content span')
        let public_date = value.querySelector('.post-title-suffix-date span')
        let editor_operator = value.querySelector('td:nth-child(6) a')
        let public_state = value.querySelector('td:nth-child(3)')

        let post_id = parseInt(pattern.exec(editor_operator.getAttribute('href'))[1]);

        let data = {
            "title": title_content.innerText.trim(),
            'url': location.protocol + title_link.getAttribute('href'),
            'public_date': public_date.getAttribute('title'),
            "post_id": post_id,
            'public_state': public_state.innerText,
            'public_state_code': public_state.innerText === '已发布' ? 1 : 0,
            'download_md_link': download_url_prefix + post_id + '.md'
        }
        list.push(data)
    })
    let current_page = document.querySelector('.cnb-pager-position .indexes .current')
    let current_page_number = parseInt(current_page.innerText)

    createJSONFile(list, "i-cnblogs-com-" + current_page_number + ".json")

}


浏览器启用远程调试功能

更多参考信息: https://www.cnblogs.com/jingjingxyk/p/16577987.html

以chromium 内核浏览器为例


chromium --remote-debugging-port=9221

准备python 运行环境

Pipfile 文件

pipenv update --pypi-mirror https://pypi.tuna.tsinghua.edu.cn/simple

[[source]]
url = "https://pypi.tuna.tsinghua.edu.cn/simple"
verify_ssl = true
name = "pip_conf_index_global"

[packages]
requests = "*"
playwright = "*"

[dev-packages]

[requires]
python_version = "3.10"
python_full_version = "3.10.6"


准备 python3 脚本

进入 运行环境 pipenv shell

执行 python3 main.py

import os
import json
import glob
import optparse
import datetime
from playwright.async_api import async_playwright
import asyncio
import re

'''
  下载 随笔 markdown 文档
  原理: 借助浏览器  远程调试 实现
  --remote-debugging-port=9221 
  前提: 用自己的帐号先登录,这样 跳过了登录环节
  
'''


def get_cnblogs_index(filename):
    with open(filename, mode='r', encoding='utf-8') as f:
        content = f.read()
        result = json.loads(content)
    return result


def init():
    wildcard = project_dir + '/i-cnblogs-com-*.json'
    data_origin_index = list()
    for file in glob.glob(wildcard):
        res = get_cnblogs_index(file)
        for cell in res:
            data_origin_index.append(cell)
    return data_origin_index


async def get_content(element, SEMAPHORE, browser):
    async with SEMAPHORE:
        # 文件名中的空格替换为下划线
        pattern = r'\s+'
        title = re.sub(pattern, '_', element['title'])
        filename = project_dir + '/cnblogs/' + title + '.md'
        if not os.path.isfile(filename):
            context = browser.contexts[0]
            page = await context.new_page()
            print(element)

            await page.goto(element['url'])
            content = await page.evaluate(
                '''
                        async (url) => {
                               //使用 ajax 原始文本
                               let response = await fetch(url)
                               let content= await response.text()
                               return content
                        }
                '''
                , element['download_md_link'])
            print("{}".format(content))

            with open(filename, "w+") as f:
                f.write(content)
            await asyncio.sleep(3)
            await page.close()


async def run(playwright):
    data_origin_index = init()

    browser = await playwright.chromium.connect_over_cdp("http://localhost:9222")
    tasks = [asyncio.create_task(get_content(element, SEMAPHORE, browser)) for element in data_origin_index]
    result = await asyncio.gather(*tasks)

    await browser.close()


async def main():
    async with async_playwright() as playwright:
        await run(playwright)


if __name__ == '__main__':
    parser = optparse.OptionParser('usage: %prog [OPTIONS]', description=__doc__)
    parser.add_option('--id', help='随笔 ID ', type=int, default=None)
    parser.add_option('--max_parallel', help='最大并发数', type=int, default=os.cpu_count())
    args = parser.parse_args()  # 暂不启用传递命令行参数

    project_dir = os.path.abspath(os.path.dirname(__file__) + '/')
    if not os.path.isdir(project_dir + '/cnblogs'):
        os.mkdir(project_dir + '/cnblogs')

    start_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    # 控制并发数 默认为3 ;不要轻易改大,改大以后,影响服务器性能,可能会惹上麻烦
    SEMAPHORE = asyncio.Semaphore(3)
    asyncio.run(main())
    end_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    print("start_time: {} \nend_time: {}".format(start_time, end_time))

小结:

此方法不仅仅可以备份 博客园 随笔文件,更多应用。。。。。

其实就是各种爬虫的玩法 (甚至可以操纵自动登录)

爬虫写的好,牢饭吃到老 爬取个人隐私身份信息是违法的

更多 请看这里 https://www.cnblogs.com/jingjingxyk/p/16845153.html

法律法规

  1. 立法禁止非法使用网络地址自动切换系统
  2. 中华人民共和国反电信网络诈骗法
  3. 工信部印发《网络产品安全漏洞收集平台备案管理办法》
  4. 中华人民共和国网络安全法
  5. 中华人民共和国反电信网络诈骗法
  6. 帮信罪
  7. 破坏计算机信息系统犯罪
  8. 中华人民共和国个人信息保护法
  9. 互联网信息服务管理办法
posted @ 2023-04-15 17:37  jingjingxyk  阅读(125)  评论(0编辑  收藏  举报