segmentfault是我在這些平臺中看過介面最為簡潔的部落格平臺了。
今天就以segmentfault為例,講講在blog-auto-publishing-tools中的實現原理。
前提條件
前提條件當然是先下載 blog-auto-publishing-tools這個部落格自動釋出工具,地址如下:https://github.com/ddean2009/blog-auto-publishing-tools
segmentfault的實現
接下來我們手把手看看具體在segmentfault的自動化是如何實現的。
segmentfault的配置檔案
在config目錄下面,你會找到一個segmentfault.yaml的檔案,這個就是segmentfault的配置檔案了。
內容很簡單,如下所示:
site: https://segmentfault.com/write
tags:
- 人工智慧
- aigc
- openai
- ai開發
裡面主要是兩個內容,site是segmentfault的部落格編寫頁面。
tags是你的部落格的一些標籤,可以自行設定。
這裡要注意的是,segmentfault中的標籤並不能隨意寫,你需要選擇segmentfault中已有的標籤才可以。
segmentfault的實現邏輯
所有的釋出器都在publisher目錄下,在下面你可以找到segmentfault_publisher這個專門給segmentfault的釋出器。
首先我們需要開啟新的tab,然後切換到segmentfault的部落格釋出頁面:
# 開啟新標籤頁並切換到新標籤頁
driver.switch_to.new_window('tab')
# 瀏覽器例項現在可以被重用,進行你的自動化操作
driver.get(segmentfault_config['site'])
time.sleep(2) # 等待2秒
處理標題
進入釋出頁面,我們看看頁面的一些結構,首先是標題。
標題比較簡單,自帶了ID:
所以我們可以直接使用find_element by ID直接獲得title的input,然後呼叫send_keys方法,把title的內容輸入進去。
如下所示:
# 文章標題
title = driver.find_element(By.ID, 'title')
title.clear()
title.send_keys(common_config['title'])
time.sleep(2) # 等待3秒
處理內容
接下來我們看看內容這一塊。如果進入除錯模式,你會看到segmentfault的內容部分不是一個簡單的textarea,而是使用了CodeMirror這個開源的線上程式碼編輯工具。
這個CodeMirror的程式碼內容是會隨著你的輸入不斷進行變化的。
那麼我們怎麼才能把滑鼠定位到CodeMirror的程式碼塊中進行內容輸入呢?
這裡我們有一個小技巧。
如果你進入segmentfault寫部落格的首頁,你會發現滑鼠預設是定位在『請輸入標題』這個標題欄的部分。
接下來如果我們連續輸入三次tab鍵,滑鼠就會定位到CodeMirror內容編輯框了。
然後我們只需要使用複製貼上功能,把markdown的內容貼上到內容框即可完成內容的輸入。
以下是程式碼實現:
# 文章內容
file_content = read_file_with_footer(common_config['content'])
# segmentfault比較特殊,用的是CodeMirror,不能用元素賦值的方法,所以我們使用複製的方法
cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL
# 將要貼上的文字內容複製到剪貼簿
pyperclip.copy(file_content)
# 三次tab按鈕,讓游標定位到內容視窗:
action_chains = webdriver.ActionChains(driver)
for i in range(3):
action_chains.key_down(Keys.TAB).key_up(Keys.TAB).perform()
time.sleep(1)
# 模擬實際的貼上操作
action_chains.key_down(cmd_ctrl).send_keys('v').key_up(cmd_ctrl).perform()
time.sleep(3) # 等待3秒
實際上在操作中,你會發現使用tab鍵定位之後,複製是複製不進去的。
所以上面的方法其實是不可行的。我們仍然需要定位到文章內容部分.....
我們仔細看看內容編輯部分,可以看到在CodeMirror-code下面有一個span的role=presentation,就它了,我們使用xpath來定位,程式碼如下所示:
# 文章內容
file_content = read_file_with_footer(common_config['content'])
# segmentfault比較特殊,用的是CodeMirror,不能用元素賦值的方法,所以我們使用複製的方法
cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL
# 將要貼上的文字內容複製到剪貼簿
pyperclip.copy(file_content)
action_chains = webdriver.ActionChains(driver)
# 三次tab按鈕,讓游標定位到內容視窗:
for i in range(3):
action_chains.key_down(Keys.TAB).key_up(Keys.TAB).perform()
time.sleep(1)
# 找到初始的內容描述文字
content = driver.find_element(By.XPATH, '//div[@class="CodeMirror-code"]//span[@role="presentation"]')
content.click()
# 模擬實際的貼上操作
action_chains.key_down(cmd_ctrl).send_keys('v').key_up(cmd_ctrl).perform()
time.sleep(3) # 等待3秒
處理標籤
標題,內容都有了,接下來就是標籤處理了。
segmentfault的標籤處理邏輯:
- 點選新增標籤按鈕
- 在搜尋標籤框輸入要新增的標籤
- 回車即可。
- 如果有多個標籤,重複2-3這兩步。
所以我們可以得到下面的程式碼:
# 新增標籤
tag_button = driver.find_element(By.ID, 'tags-toggle')
tag_button.click()
tag_input = driver.find_element(By.XPATH, '//input[@placeholder="搜尋標籤"]')
for tag in segmentfault_config['tags']:
tag_input.send_keys(tag)
tag_input.send_keys(Keys.ENTER)
time.sleep(2)
time.sleep(2)
點選發布文章按鈕
點選發布文章按鈕之後,會有一個下拉彈窗框,讓你選擇封面,文章型別,釋出到,定時釋出和註明版權這些東西。
釋出文章按鈕很簡單,直接根據ID查詢即可:
# 釋出按鈕
publish_button = driver.find_element(By.ID, 'publish-toggle')
publish_button.click()
time.sleep(2)
設定封面
正常情況下設定封面需要點選設定封面按鈕,然後從本地選擇一個封面圖片上傳。
這樣就比較麻煩了。我們直接從markdown的front matter中讀取imge的地址,上傳到網站上。
事實上,除了image之外,title,tags,description 都會優先從markdown的front matter中去會獲取。這樣就不用每次去修改配置檔案了。
title: 一鍵自動化部落格釋出工具,用過的人都說好(segmentfault篇)
authors: flydean
tags: [自動化工具,部落格,自動釋出]
image: https://flydean-1301049335.cos.ap-guangzhou.myqcloud.com/img/202405061040404.png
description: 使用一鍵自動化部落格釋出工具blog-auto-publishing-tools把部落格釋出到segmentfault上。
上傳封面的程式碼如下:
# 設定封面
if front_matter['image']:
file_input = driver.find_element(By.XPATH, "//input[type='file']")
file_input.send_keys(front_matter['image'])
time.sleep(2)
設定版權
# 版權
copy_right = driver.find_element(By.ID, 'license')
copy_right.click()
time.sleep(2)
版權設定比較簡單,直接找到對應的ID即可。
最終釋出
最後找到釋出按鈕就可以釋出了。
# 確認釋出
if auto_publish:
confirm_button = driver.find_element(By.ID, 'sureSubmitBtn')
confirm_button.click()
點我檢視更多精彩內容:www.flydean.com