終於要講解我們親愛的掘金了。掘金是一個非常不錯的平臺。所以很多朋友會把部落格釋出到掘金上。
釋出到掘金要填寫的內容也比較多。今天給大家介紹一下如何用blog-auto-publishing-tools這個工具自動把部落格釋出到掘金平臺上去。
前提條件
前提條件當然是先下載 blog-auto-publishing-tools這個部落格自動釋出工具,地址如下:https://github.com/ddean2009/blog-auto-publishing-tools
掘金的實現
點選寫文章按鈕
要進入掘金的寫文章頁面,我們需要先點選掘金的釋出文章按鈕。
找到寫文章按鈕比較簡單,我們直接透過class name定位到寫文章按鈕,點選即可。
# 寫文章按鈕
write_btn = driver.find_element(By.CLASS_NAME, 'send-button')
write_btn.click()
time.sleep(2) # 等待3秒
點選寫文章按鈕之後,會開啟一個新的tab頁面。
所以接下來我們需要切換到這個新的tab頁面,然後等待輸入文章標題的title出現。
切換tab可以呼叫driver.switch_to.window方法。
然後我們呼叫wait.until來等待新標籤完成載入內容。
# 切換到新的tab
driver.switch_to.window(driver.window_handles[-1])
# 等待新標籤頁完成載入內容
wait.until(EC.presence_of_element_located((By.XPATH, '//input[@placeholder="輸入文章標題..."]')))
輸入文章標題
掘金的文章標題沒有id,所以我們只能透過xpth來定位。
# 文章標題
title = driver.find_element(By.XPATH, '//input[@placeholder="輸入文章標題..."]')
title.clear()
title.send_keys(common_config['title'])
time.sleep(2) # 等待3秒
輸入文章內容
從debug上來看,掘金的文章內容部分用的是CodeMirror這個富文字編輯工具。
CodeMirror的特點就是html內容會隨著你的輸入而動態變化。
所以這裡我們不能拿到某個元素用send_keys方法,來輸入文章內容。
我們需要轉變一下思路。
除了send_keys方法之外,我們還可以選擇把文章內容複製到系統的剪貼簿上,然後把滑鼠定位到文章內容部分之後,再呼叫系統的貼上命令把文章貼上到指定的位置。
對,就這麼幹:
# 文章內容
file_content = read_file_with_footer(common_config['content'])
# 掘金比較特殊,不能用元素賦值的方法,所以我們使用複製的方法
cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL
# 將要貼上的文字內容複製到剪貼簿
pyperclip.copy(file_content)
content = driver.find_element(By.XPATH, '//div[@class="CodeMirror-code"]//span[@role="presentation"]')
content.click()
# 模擬實際的貼上操作(在某些情況下可能更合適):
action_chains = webdriver.ActionChains(driver)
action_chains.key_down(cmd_ctrl).send_keys('v').key_up(cmd_ctrl).perform()
time.sleep(15) # 等待15秒 圖片解析需要花比較長時間
這裡要注意的是,掘金會嘗試重新上傳圖片,如果你的圖片內容比較多的話,需要耗費比較長的時間。
所以這裡我sleep了15秒鐘。
點選發布按鈕
接下來就可以點選發布按鈕了。
點選發布按鈕之後,會有一個彈出框:
這裡我們可以填寫型別,標籤,封面,專欄,話題和摘要。接下來我們一個個來看看怎麼實現。
文章分類
分類可以在class為category-list的div下面查詢對應文字內容的category,如下所示:
# 分類
category = juejin_config['category']
if category:
category_btn = driver.find_element(By.XPATH, f'//div[@class="form-item-content category-list"]//div[contains(text(), "{category}")]')
category_btn.click()
time.sleep(2)
新增標籤
新增標籤需要首先點選標籤下拉框:
tag_btn = driver.find_element(By.XPATH, '//div[contains(@class,"byte-select__placeholder") and contains(text(), "請搜尋新增標籤")]')
tag_btn.click()
然後需要在輸入框裡面輸入你需要新增的標籤,等標籤出現在下拉框的時候,輸入回車就可以選中了對應的標籤了。
# 使用複製貼上的方式
pyperclip.copy(tag)
action_chains = webdriver.ActionChains(driver)
action_chains.key_down(cmd_ctrl).send_keys('v').key_up(cmd_ctrl).perform()
# 從下拉框中選擇對應的tag
tag_element = driver.find_element(By.XPATH, f'//li[contains(@class,"byte-select-option") and contains(text(), "{tag}")]')
tag_element.click()
time.sleep(2) # 等待3秒
注意,這裡我們的輸入比較好的方式就是使用複製貼上,這樣不需要定位到輸入元素也可以進行。
設定文章封面
文章封面有一個input標籤,所以我們可以使用selenium的上傳圖片功能來實現:
# 文章封面
if 'image' in front_matter and front_matter['image']:
file_input = driver.find_element(By.XPATH, "//input[@type='file']")
# 檔案上傳不支援遠端檔案上傳,所以需要把圖片下載到本地
file_input.send_keys(download_image(front_matter['image']))
time.sleep(2)
注意,這裡的圖片是在markdown檔案的yaml front matter中設定的。如下所示:
收錄至專欄
收錄至專欄需要定位到專欄輸入框,輸入對應的專欄,然後回車即可。
# 收錄至專欄
collections = juejin_config['collections']
collection_button = driver.find_element(By.XPATH, '//div[contains(@class,"byte-select__placeholder") and contains(text(), "請搜尋新增專欄,同一篇文章最多新增三個專欄")]')
collection_button.click()
for coll in collections:
# 使用複製貼上的方式
pyperclip.copy(coll)
action_chains = webdriver.ActionChains(driver)
action_chains.key_down(cmd_ctrl).send_keys('v').key_up(cmd_ctrl).perform()
# 從下拉框中選擇對應的tag
coll_element = driver.find_element(By.XPATH, f'//li[contains(@class,"byte-select-option") and contains(text(), "{coll}")]')
coll_element.click()
time.sleep(2) # 等待3秒
同樣的,我們也使用的是複製貼上的方法進行輸入。
創作話題
話題跟專欄的實現方式類似,也是先定位,然後輸入,之後回車選擇。
程式碼如下所示:
# 創作話題
topic = juejin_config['topic']
if topic:
topic_btn = driver.find_element(By.XPATH, '//div[contains(@class,"byte-select__placeholder") and contains(text(), "請搜尋新增話題,最多新增1個話題")]')
topic_btn.click()
# 使用複製貼上的方式
pyperclip.copy(topic)
action_chains = webdriver.ActionChains(driver)
action_chains.key_down(cmd_ctrl).send_keys('v').key_up(cmd_ctrl).perform()
# 從下拉框中選擇對應的tag
topic_element = driver.find_element(By.XPATH, f'//li[@class="byte-select-option"]//span[contains(text(), "{topic}")]')
topic_element.click()
time.sleep(2) # 等待3秒
這裡也使用的是複製貼上的方式。
設定摘要
摘要是一個textarea,我們透過xpath來定位它:
if summary:
summary_ui = driver.find_element(By.XPATH, '//textarea[@class="byte-input__textarea"]')
summary_ui.clear()
summary_ui.send_keys(summary)
time.sleep(2) # 等待3秒
最終的釋出
最後就是釋出了。
publish_button = driver.find_element(By.XPATH, '//button[contains(text(), "確定併發布")]')
publish_button.click()
同樣的,我們透過xpath來定位到釋出按鈕。
總結
掘金相對而言實現是比較複雜的。大家可以仔細研究一下具體的實現細節。
點我檢視更多精彩內容:www.flydean.com