之前說過blog-auto-publishing-tools的實現方式是連到現有的瀏覽器中,而不是使用內置的瀏覽器。
其中一個很大程度的原因是像騰訊雲這種博客發佈平臺幾乎每天都需要重新登錄一次,登錄還需要手機掃碼。所以自動化實現起來非常複雜。
所以,我們需要一個已經登錄好的瀏覽器,來實現自動化功能。
前提條件
前提條件當然是先下載 blog-auto-publishing-tools這個博客自動發佈工具,地址如下:https://github.com/ddean2009/blog-auto-publishing-tools
騰訊雲的實現
切換到markdown編輯器
騰訊雲有兩個編輯器,一個是markdown,一個是富文本。
這個兩個選項是沒法設置的,我感覺是隨機的,所以我們需要一個機制來保證我們現在是在markdown編輯器中。
可以看到這個切換到富文本編輯器是一個div,裏面包含了一個img和一個a標籤。
我們可以通過判斷a標籤中的文字來確定現在是在富文本編輯器中,還是在markdown編輯器中。
實現方式如下:
# 切換到markdown編輯器
a_switch = driver.find_element(By.XPATH, '//div[@class="col-editor-switch"]//a')
# 獲取a元素的文本內容
text_content = a_switch.text
if text_content == '切換到Markdown編輯器':
a_switch.click()
time.sleep(2)
拿到元素之後,獲取他的text,然後判斷text的內容。
文章標題
騰訊雲的文章標題是一個textarea,我們可以通過placeholder來定位到這個元素:
# 文章標題
title = driver.find_element(By.XPATH, '//textarea[@placeholder="請輸入標題"]')
title.clear()
title.send_keys(common_config['title'])
time.sleep(2) # 等待3秒
文章內容
騰訊雲的文章內容編輯器是一個叫做monaco-editor的東西。
這種編輯器會根據文章內容,動態變化html的內容。所以對於這種編輯器來說,我們需要使用到拷貝粘貼的方法。
# 文章內容 markdown版本, 騰訊雲不能有引流鏈接
file_content = read_file(common_config['content'])
# 用的是CodeMirror,不能用元素賦值的方法,所以我們使用拷貝的方法
cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL
# 將要粘貼的文本內容複製到剪貼板
pyperclip.copy(file_content)
action_chains = webdriver.ActionChains(driver)
content = driver.find_element(By.XPATH, '//div[contains(@class,"draft-markdown-editor")]//div[@class="view-line"]')
content.click()
time.sleep(2)
# 模擬實際的粘貼操作
action_chains.key_down(cmd_ctrl).send_keys('v').key_up(cmd_ctrl).perform()
time.sleep(3) # 等待3秒
粘貼的時候需要定位到文章編輯器的位置,點擊一下,然後才能進行粘貼。
發佈文章
接下來就可以點擊發布文章按鈕了。
# 發佈文章
send_button = driver.find_element(By.XPATH, '//button[contains(@class, "c-btn") and contains(text(),"發佈")]')
send_button.click()
time.sleep(2)
點擊發布按鈕之後,會在側邊欄彈出一個對話框,如下所示:
這裏可以選擇文章來源,文章分類,文章標籤和自定義關鍵字這些內容。
文章來源
文章來源我們就選擇原創了,文章來源是一個input,我們可以使用下面的方法來定位:
# 文章來源
source = driver.find_element(By.XPATH, '//ul[@class="com-check-list"]/li/label/span[contains(text(),"原創")]')
source.click()
time.sleep(2)
文章分類
文章分類比較複雜點。
我們需要先點擊文章分類下拉框,然後在輸入框中輸入要設置的文章分類。
實現代碼如下:
article_type_select = driver.find_element(By.XPATH, '//section[@class="col-editor-sidebar publish"]//div[@class="tea-dropdown col-editor-classify is-expanded"]/div')
article_type_select.click()
time.sleep(1)
article_type_element = driver.find_element(By.XPATH,f'//div[@class="tea-dropdown-box"]//ul//li//label//span[text()="{article_type}"]')
article_type_element.click()
time.sleep(1)
文章標籤
文章標籤需要選擇標籤輸入框,然後根據設置好的標籤內容,輸入到輸入框中,然後回車即可:
tag_label = driver.find_element(By.XPATH,
'//div[@class="com-2-tag-cont"]/label[contains(text(),"搜索並選擇合適的標籤")]')
tag_input = tag_label.find_element(By.XPATH, '../input[@class="com-2-tag-input"]')
for tag in tags:
tag_input.send_keys(tag)
time.sleep(1)
tag_input.send_keys(Keys.ENTER)
time.sleep(1)
關鍵詞
自定義關鍵詞和文章標籤的實現方式很類似,也是先找到自定義關鍵詞框,點擊,然後輸入,最後回車即可:
keyword_label = driver.find_element(By.XPATH, '//div[@class="com-2-tag-cont"]/label[contains(text(),"最多5個關鍵詞")]')
keyword_input = keyword_label.find_element(By.XPATH, '../input[@class="com-2-tag-input"]')
for keyword in keywords:
keyword_input.send_keys(keyword)
time.sleep(1)
keyword_input.send_keys(Keys.ENTER)
time.sleep(1)
專欄
騰訊雲的專欄是一個個的checkbox,我們可以通過他的具體內容來選擇:
zhuanlan_element = driver.find_element(By.XPATH, f'//span[@class="col-editor-create-name" and contains(text(),"{zhuanlan}")]')
zhuanlan_element.click()
封面圖片
騰訊雲的封面圖片是一個input,帶有id的,所以實現起來比較簡單:
file_input = driver.find_element(By.ID, "editor-upload-input")
# 文件上傳不支持遠程文件上傳,所以需要把圖片下載到本地
file_input.send_keys(download_image(front_matter['image']))
time.sleep(2)
最後的發佈按鈕
最後就是發佈按鈕了:
publish_button = driver.find_element(By.XPATH, '//div[contains(@class,"block c-btn") and contains(text(),"確認發佈")]')
publish_button.click()
我們通過包含的text來選擇。
總結
騰訊雲的選項比較多,實現起來也比較複雜。