激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - 用python寫個博客遷移工具

用python寫個博客遷移工具

2021-09-27 00:19Cookieboty Python

這篇文章主要介紹了如何用python寫個博客遷移工具,幫助大家更好的理解和學習使用python,感興趣的朋友可以了解下

前言

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

我最開始接觸的博客網址是 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

  1. 請自行替換user_nameblog_id
  2. // 下載單篇文章到默認目錄'./cnblogs' 并輸出日志到'./log'
  3. python3 main.py -m download -a https://www.cnblogs.com/{{user_name}}/p/{{blog_id}}.html --enable_log
  4.  
  5. // 下載用戶所有文章到目錄'/Users/cnblogs_t'
  6. python3 main.py -m download -u https://www.cnblogs.com/{{username}} -p /Users/cnblogs_t
  7.  
  8. // 上傳單篇文章到掘金草稿箱
  9. python3 main.py -m upload -f ./cnblogs/{{blog_id}}.html
  10.  
  11. // 上傳'./test_blogs'下所有的html文件到掘金草稿箱
  12. python3 main.py -m upload -d ./test_blogs

main.py

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

  1. # coding=utf-8
  2. import requests
  3. import os
  4. import argparse
  5. import sys
  6. import json
  7. from lxml import etree
  8. from urllib.parse import urlparse
  9. import logging
  10. reload(sys)
  11. sys.setdefaultencoding('utf-8')
  12.  
  13. parser = argparse.ArgumentParser()
  14. args_dict = {}
  15. list_url_tpl = 'https://www.cnblogs.com/%s/default.html?page=%d'
  16. draft_url = 'https://api.juejin.cn/content_api/v1/article_draft/create_offline'
  17. jj_draft_url_tpl = 'https://juejin.cn/editor/drafts/%s'
  18. cnblog_headers = {}
  19. log_path = './log'
  20.  
  21. def myget(d, k, v):
  22. if d.get(k) is None:
  23. return v
  24. return d.get(k)
  25.  
  26. def init_parser():
  27. parser.description = 'blog move for cnblogs'
  28. parser.add_argument('-m', '--method', type=str, dest='method', help='使用方式: download下載 upload上傳到草稿箱', choices=['upload', 'download'])
  29. parser.add_argument('-p', '--path', type=str, dest='path', help='博客html下載的路徑')
  30. parser.add_argument('-d', '--dir', type=str, dest='rec_dir', help='制定要上傳的博客所在文件夾')
  31. parser.add_argument('-f', '--file', type=str, dest='file', help='指定上傳的博客html')
  32. parser.add_argument('-u', '--url', type=str, dest='url', help='個人主頁地址')
  33. parser.add_argument('-a', '--article', type=str, dest='article_url', help='單篇文章地址')
  34. parser.add_argument('--enable_log', dest='enable_log', help='是否輸出日志到./log', action='store_true')
  35. parser.set_defaults(enable_log=False)
  36.  
  37. def init_log():
  38. root_logger = logging.getLogger()
  39. log_formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(pathname)s:%(lineno)s %(message)s')
  40. console_handler = logging.StreamHandler(sys.stdout)
  41. console_handler.setFormatter(log_formatter)
  42. root_logger.addHandler(console_handler)
  43. if myget(args_dict, 'enable_log', False):
  44. if not os.path.exists(log_path):
  45. os.mkdir(log_path)
  46. file_handler = logging.FileHandler('./log/debug.log')
  47. file_handler.setFormatter(log_formatter)
  48. root_logger.addHandler(file_handler)
  49. root_logger.setLevel(logging.INFO)
  50.  
  51. def download():
  52. cookies = json.load(open('cookie.json'))
  53. headers = {'cookie': cookies.get('cookie_cnblogs', '')}
  54.  
  55. dir_path = myget(args_dict, 'path', './cnblogs')
  56. if dir_path[len(dir_path)-1] == '/':
  57. dir_path = dir_path[:len(dir_path)-1]
  58. if not os.path.exists(dir_path):
  59. os.mkdir(dir_path)
  60.  
  61. article_url = myget(args_dict, 'article_url', '-1')
  62. if article_url != '-1':
  63. logging.info('article_url=%s', article_url)
  64. try:
  65. resp = requests.get(article_url, headers=headers)
  66. if resp.status_code != 200:
  67. logging.error('fail to get blog \'%s\', resp=%s', article_url, resp)
  68. return
  69. tmp_list = article_url.split('/')
  70. blog_id_str = tmp_list[len(tmp_list)-1]
  71. with open(dir_path+'/'+blog_id_str, 'w') as f:
  72. f.write(resp.text)
  73. logging.info('get blog \'%s\' success.', article_url)
  74. except Exception as e:
  75. logging.error('exception raised, fail to get blog \'%s\', exception=%s.', list_url, e)
  76. finally:
  77. return
  78.  
  79. raw_url = args_dict.get('url')
  80. rurl = urlparse(raw_url)
  81. username = (rurl.path.split("/", 1))[1]
  82. page_no = 1
  83. while True:
  84. list_url = list_url_tpl%(username, page_no)
  85. logging.info('list_url = %s', list_url)
  86. try:
  87. resp = requests.get(list_url, headers=headers)
  88. if resp.status_code != 200:
  89. break
  90. except Exception as e:
  91. logging.error('exception raised, fail to get list \'%s\', exception=%s.', list_url, e)
  92. return
  93. html = etree.HTML(resp.text)
  94. blog_list = html.xpath('//div[@class=\'postTitle\']/a/@href')
  95. if len(blog_list) == 0:
  96. break
  97. for blog_url in blog_list:
  98. tmp_list = blog_url.split('/')
  99. blog_id_str = tmp_list[len(tmp_list)-1]
  100. blog_resp = requests.get(blog_url, headers=headers)
  101. if resp.status_code != 200:
  102. logging.error('fail to get blog \'%s\', resp=%s, skip.', blog_url, resp)
  103. continue
  104. with open(dir_path+'/'+blog_id_str, 'w') as f:
  105. f.write(blog_resp.text)
  106. logging.info('get blog \'%s\' success.', blog_url)
  107. page_no += 1
  108.  
  109. def upload_request(headers, content, filename):
  110. body = {
  111. "edit_type": 0,
  112. "origin_type": 2,
  113. "content": content
  114. }
  115. data = json.dumps(body)
  116. try:
  117. resp = requests.post(draft_url, data=data, headers=headers)
  118. if resp.status_code != 200:
  119. logging.error('fail to upload blog, filename=%s, resp=%s', filename, resp)
  120. return
  121. ret = resp.json()
  122. draft_id = ret.get('data', {}).get('draft_id', '-1')
  123. logging.info('upload success, filename=%s, jj_draft_id=%s, jj_draft_url=%s', filename, draft_id, jj_draft_url_tpl%draft_id)
  124. except Exception as e:
  125. logging.error('exception raised, fail to upload blog, filename=%s, exception=%s', filename, e)
  126. return
  127.  
  128. def upload():
  129. cookies = json.load(open('cookie.json'))
  130. headers = {
  131. 'cookie': cookies.get('cookie_juejin', ''),
  132. 'content-type': 'application/json'
  133. }
  134. filename = myget(args_dict, 'file', '-1')
  135. if filename != '-1':
  136. logging.info('upload_filename=%s', filename)
  137. try:
  138. with open(filename, 'r') as f:
  139. content = f.read()
  140. upload_request(headers, content, filename)
  141. return
  142. except Exception as e:
  143. logging.error('exception raised, exception=%s', e)
  144.  
  145. rec_dir = myget(args_dict, 'rec_dir', '-1')
  146. if rec_dir != '-1':
  147. logging.info('upload_dir=%s', filename)
  148. try:
  149. g = os.walk(rec_dir)
  150. for path, dir_list, file_list in g:
  151. for filename in file_list:
  152. if filename.endswith('.html'):
  153. filename = os.path.join(path, filename)
  154. with open(filename, 'r') as f:
  155. content = f.read()
  156. upload_request(headers, content, filename)
  157. except Exception as e:
  158. logging.error('exception raised, exception=%s', e)
  159. return
  160.  
  161. if __name__ == '__main__':
  162. init_parser()
  163. args = parser.parse_args()
  164. args_dict = args.__dict__
  165. init_log()
  166.  
  167. empty_flag = True
  168. for k, v in args_dict.items():
  169. if k != 'enable_log' and v is not None:
  170. empty_flag = False
  171. if empty_flag:
  172. parser.print_help()
  173. exit(0)
  174.  
  175. if args_dict.get('method') == 'upload':
  176. upload()
  177. else:
  178. download()
  179. pass

cookie.json

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

  1. {
  2. "cookie_cnblogs": "請替換為博客園cookie",
  3. "cookie_juejin": "請替換為掘金cookie"
  4. }

github 地址

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

以上就是用python寫個博客遷移工具的詳細內容,更多關于python 博客遷移的資料請關注服務器之家其它相關文章!

原文鏈接:https://juejin.cn/post/6942882189277298696

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久嗨| 在线a亚洲视频播放在线观看 | 在线看免费的a | 在线成人看片 | 欧美成人二区 | 久久久久国产成人免费精品免费 | 日韩视频观看 | 免费看成年人视频在线 | 亚洲va国产va | 精品国产一区在线 | 高颜值美女啪啪 | 久久久成人精品 | 奇米影视四色7777 | 日本精品久久久一区二区三区 | 中文字幕在线观看亚洲 | 美国人成人在线视频 | 日本在线不卡一区二区三区 | 久久精品黄 | 国产青青 | 国产精品久久久久久久久久 | 蜜桃传媒视频麻豆第一区免费观看 | 国产成人精品午夜视频' | 意大利av在线 | 国产高潮好爽受不了了夜色 | av播播| 免费观看又色又爽又黄的崩锅 | 亚洲国产成人一区二区 | 欧美 videos粗暴| 久久久在线免费观看 | 久草视频在线看 | 一级大片在线观看 | 久久久一区二区精品 | 亚洲一区二区三区在线播放 | 国产精品视频一区二区三区四区国 | 看免费一级毛片 | 精品av在线播放 | 黄色网址免费在线播放 | 日韩av有码在线 | 日本网站在线看 | 免费看h网站 | 久久在现视频 |