亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

用python寫個博客遷移工具

瀏覽:16日期:2022-06-24 10:25:47
前言

最近不少寫博客的朋友跟我反饋博客園的一些文章下架了,這讓我聯想到去年簡書一樣,我之前寫的博客都被下架不可見了。

我最開始接觸的博客網址是 csdn、思否、簡書還有博客園等,但是后期發現,單論博客的生態感覺做的越來越不行,干貨雖然很多,但是垃圾、標題黨很嚴重,我自己也有一些博文被莫名的搬走直接標為原創。

雖然搜問題在上面還是能搜到很多解決方案,但寫作的欲望降低了很多。

綜上我從去年入駐掘金,并以掘金作為博客的主平臺。個人感覺掘金團隊對個人原創的保護是非常好的,同時也在不斷的聽取用戶的建議而去改進。有問題與建議能隨時與掘金的同學討論、溝通,非常方便。

掘金的成長

最開始的時候,掘金也是面試、標題黨滿天飛,但是掘金的運營大佬逐步整頓起來之后,文章的質量有了顯著的提高,并且也不斷推出有利于新手作者、高質量博文的各種活動,鼓勵新人創作、老人分享。

同樣在我入駐掘金之后,作為一個長期用戶,新人作者,也是見證了這段時間以來掘金為了社區活躍,博客質量而做的種種努力。

而最開始使用掘金的 markdown,能吐槽的地方還是很多,但掘金的研發也非常給力,吸納了用戶的建議后,最新升級的 markdown 編輯器也是廣受好評,使用過你就知道真相定律是什么了。

掘金在使用的時候,一直有種特殊的感覺,是一種很純粹的 coding 情懷。并不僅僅只是一個單純的博客平臺,而是一直致力于社區共建、開源項目、掘金翻譯計劃等等的建設,為技術社區打造一片純粹干凈的后花園。

搬家命令行工具

那么作為程序員,手動搬文章顯然是略 low 的

所以寫了一個簡單的 python 腳本,有興趣的同學可以使用它將 cnblogs 上面已有或者創作中的草稿轉移到掘金來。

如果有興趣可以試試改造的更完美點,但不建議泄露自己的隱私信息

環境配置

腳本跑起來需要 python3 環境,所以先安裝一下 python 環境

請在 cookie.json 中補充博客園與掘金的 cookie

使用 python3 main.py -h 查看使用說明

作為程序員應該都了解 cookie 是啥,也知道從哪里撈出來吧

使用方法

用python寫個博客遷移工具

還是上個獲取 cookie 的圖吧,哈哈

請先在 cookie.json 中替換 cookie_cnblogs 與 cookie_juejin 為自己在對應站點上的 cookie

請自行替換user_name與blog_id// 下載單篇文章到默認目錄’./cnblogs’ 并輸出日志到’./log’python3 main.py -m download -a https://www.cnblogs.com/{{user_name}}/p/{{blog_id}}.html --enable_log // 下載用戶所有文章到目錄’/Users/cnblogs_t’python3 main.py -m download -u https://www.cnblogs.com/{{username}} -p /Users/cnblogs_t// 上傳單篇文章到掘金草稿箱python3 main.py -m upload -f ./cnblogs/{{blog_id}}.html// 上傳’./test_blogs’下所有的html文件到掘金草稿箱python3 main.py -m upload -d ./test_blogsmain.py

新建 main.py 文件,將下述 python 代碼復制進去

# coding=utf-8import requestsimport osimport argparseimport sysimport jsonfrom lxml import etreefrom urllib.parse import urlparseimport loggingreload(sys)sys.setdefaultencoding(’utf-8’)parser = argparse.ArgumentParser()args_dict = {}list_url_tpl = ’https://www.cnblogs.com/%s/default.html?page=%d’draft_url = ’https://api.juejin.cn/content_api/v1/article_draft/create_offline’jj_draft_url_tpl = ’https://juejin.cn/editor/drafts/%s’cnblog_headers = {}log_path = ’./log’def myget(d, k, v): if d.get(k) is None: return v return d.get(k)def init_parser(): parser.description = ’blog move for cnblogs’ parser.add_argument(’-m’, ’--method’, type=str, dest=’method’, help=’使用方式: download下載 upload上傳到草稿箱’, choices=[’upload’, ’download’]) parser.add_argument(’-p’, ’--path’, type=str, dest=’path’, help=’博客html下載的路徑’) parser.add_argument(’-d’, ’--dir’, type=str, dest=’rec_dir’, help=’制定要上傳的博客所在文件夾’) parser.add_argument(’-f’, ’--file’, type=str, dest=’file’, help=’指定上傳的博客html’) parser.add_argument(’-u’, ’--url’, type=str, dest=’url’, help=’個人主頁地址’) parser.add_argument(’-a’, ’--article’, type=str, dest=’article_url’, help=’單篇文章地址’) parser.add_argument(’--enable_log’, dest=’enable_log’, help=’是否輸出日志到./log’, action=’store_true’) parser.set_defaults(enable_log=False)def init_log(): root_logger = logging.getLogger() log_formatter = logging.Formatter(’%(asctime)s [%(levelname)s] %(pathname)s:%(lineno)s %(message)s’) console_handler = logging.StreamHandler(sys.stdout) console_handler.setFormatter(log_formatter) root_logger.addHandler(console_handler) if myget(args_dict, ’enable_log’, False): if not os.path.exists(log_path): os.mkdir(log_path) file_handler = logging.FileHandler(’./log/debug.log’) file_handler.setFormatter(log_formatter) root_logger.addHandler(file_handler) root_logger.setLevel(logging.INFO) def download(): cookies = json.load(open(’cookie.json’)) headers = {’cookie’: cookies.get(’cookie_cnblogs’, ’’)} dir_path = myget(args_dict, ’path’, ’./cnblogs’) if dir_path[len(dir_path)-1] == ’/’: dir_path = dir_path[:len(dir_path)-1] if not os.path.exists(dir_path): os.mkdir(dir_path) article_url = myget(args_dict, ’article_url’, ’-1’) if article_url != ’-1’: logging.info(’article_url=%s’, article_url) try: resp = requests.get(article_url, headers=headers) if resp.status_code != 200: logging.error(’fail to get blog ’%s’, resp=%s’, article_url, resp) return tmp_list = article_url.split(’/’) blog_id_str = tmp_list[len(tmp_list)-1] with open(dir_path+’/’+blog_id_str, ’w’) as f: f.write(resp.text) logging.info(’get blog ’%s’ success.’, article_url) except Exception as e: logging.error(’exception raised, fail to get blog ’%s’, exception=%s.’, list_url, e) finally: return raw_url = args_dict.get(’url’) rurl = urlparse(raw_url) username = (rurl.path.split('/', 1))[1] page_no = 1 while True: list_url = list_url_tpl%(username, page_no) logging.info(’list_url = %s’, list_url) try: resp = requests.get(list_url, headers=headers) if resp.status_code != 200: break except Exception as e: logging.error(’exception raised, fail to get list ’%s’, exception=%s.’, list_url, e) return html = etree.HTML(resp.text) blog_list = html.xpath(’//div[@class=’postTitle’]/a/@href’) if len(blog_list) == 0: break for blog_url in blog_list: tmp_list = blog_url.split(’/’) blog_id_str = tmp_list[len(tmp_list)-1] blog_resp = requests.get(blog_url, headers=headers) if resp.status_code != 200: logging.error(’fail to get blog ’%s’, resp=%s, skip.’, blog_url, resp) continue with open(dir_path+’/’+blog_id_str, ’w’) as f: f.write(blog_resp.text) logging.info(’get blog ’%s’ success.’, blog_url) page_no += 1def upload_request(headers, content, filename): body = { 'edit_type': 0, 'origin_type': 2, 'content': content } data = json.dumps(body) try: resp = requests.post(draft_url, data=data, headers=headers) if resp.status_code != 200: logging.error(’fail to upload blog, filename=%s, resp=%s’, filename, resp) return ret = resp.json() draft_id = ret.get(’data’, {}).get(’draft_id’, ’-1’) logging.info(’upload success, filename=%s, jj_draft_id=%s, jj_draft_url=%s’, filename, draft_id, jj_draft_url_tpl%draft_id) except Exception as e: logging.error(’exception raised, fail to upload blog, filename=%s, exception=%s’, filename, e) return def upload(): cookies = json.load(open(’cookie.json’)) headers = { ’cookie’: cookies.get(’cookie_juejin’, ’’), ’content-type’: ’application/json’ } filename = myget(args_dict, ’file’, ’-1’) if filename != ’-1’: logging.info(’upload_filename=%s’, filename) try: with open(filename, ’r’) as f: content = f.read() upload_request(headers, content, filename) return except Exception as e: logging.error(’exception raised, exception=%s’, e) rec_dir = myget(args_dict, ’rec_dir’, ’-1’) if rec_dir != ’-1’: logging.info(’upload_dir=%s’, filename) try: g = os.walk(rec_dir) for path, dir_list, file_list in g: for filename in file_list: if filename.endswith(’.html’): filename = os.path.join(path, filename) with open(filename, ’r’) as f: content = f.read() upload_request(headers, content, filename) except Exception as e: logging.error(’exception raised, exception=%s’, e) returnif __name__ == ’__main__’: init_parser() args = parser.parse_args() args_dict = args.__dict__ init_log() empty_flag = True for k, v in args_dict.items(): if k != ’enable_log’ and v is not None: empty_flag = False if empty_flag: parser.print_help() exit(0) if args_dict.get(’method’) == ’upload’: upload() else: download() passcookie.json

本地新建 cookie.json 文件,與 main.py 同級

{ 'cookie_cnblogs': '請替換為博客園cookie', 'cookie_juejin': '請替換為掘金cookie'}github 地址

最后附上 github 地址,里面除了 demo 的 源碼之外也有錄制好的一個視頻,有興趣的同學可以下載使用或者研究研究,腳本有問題或者寫的不好改進的地方也可以互相探討下。有意見也可以隨時留言反饋

以上就是用python寫個博客遷移工具的詳細內容,更多關于python 博客遷移的資料請關注好吧啦網其它相關文章!

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 国产成人永久免费视 | 黄色一级在线观看 | 国内精品久久久久久西瓜色吧 | 精品久久一区二区 | 69xx在线观看视频 | 激情爱爱网 | 亚欧毛片| 欧美一级黄视频 | 亚洲国产成人九九综合 | 日韩欧美在线观看视频一区二区 | 97精品国产91久久久久久久 | 国产精品国产三级国产专不∫ | 在线观看视频日韩 | 精品黄色录像 | 精品福利视频在线观看视频 | 国产高清在线精品一区 | 美女国产一区 | 亚洲国产毛片aaaaa无费看 | 在线黄色小视频 | 最新亚洲精品国自产在线观看 | 黄色在线不卡 | 国产美女精品视频 | 综合色99 | 欧美日韩一区二区三区在线观看 | 一区二区不卡 | 美国特级a毛片免费网站 | 国产的老妇人 | 亚洲精品一区二区深夜福利 | 亚洲精选在线观看 | 黄色网址在线免费观看 | 国产一区二区在线免费观看 | 在线观看精品国产 | 午夜激情福利视频 | 成人免费视频网站 | 精品欧美一区二区三区免费观看 | 色婷婷伊人| 精品欧美在线观看视频 | 亚洲成年人影院 | 最新黄色地址 | 久色网 | 成人在线午夜 |