我們已經學習了很多自動化的知識了,接下來讓我們看看在blog-auto-publishing-tools中是如何實現自動發送博文到知乎的。
前提條件
前提條件當然是先下載 blog-auto-publishing-tools這個博客自動發佈工具,地址如下:https://github.com/ddean2009/blog-auto-publishing-tools
知乎的實現
知乎的字段不是太多,算是中規中矩。但是有些實現還是需要一些技巧的。一起來看看吧。
設置標題
知乎的標題是一個textarea,可以看到知乎的textarea有class,placeholder這些屬性。class後面的那一長串是自動生成的。
所以可以使用的字段就只有placeholder這個屬性了。
所以,我們可以這樣來定位標題字段:
# 文章標題
title = driver.find_element(By.XPATH, '//textarea[contains(@placeholder, "請輸入標題")]')
title.clear()
title.send_keys(common_config['title'])
time.sleep(2) # 等待3秒
設置內容
知乎的內容部分也是動態的,通過調試可以看到,好像是用的是一個叫做DraftEditor的東西(不太確定)。
基本上和之前講過的CodeMirror是類似的東西。
如果你看過我之前的文章,那麼就可以知道類似這種動態的標籤,我們可以使用拷貝和粘貼的方法來實現內容的輸入。
另外,知乎是不支持markdown格式的。
雖然知乎有個識別markdown格式的東西,但是如果你試過就會發現,markdown在知乎並不好使。
所以,我們在拷貝之前,需要把markdown格式轉換成爲html格式。
網上有很多把markdown轉換成html的工具,其中一個比較出名的就是pandoc。
pandoc的功能很強大,可以轉換很多格式的文本。
對於markdown轉換成html,可以使用下面的命令:
pandoc -f markdown -t html5 input.md -o output.html
當然爲了拷貝出來的樣式好看一些,這裏我還添加了css文件。
實現方法都寫在了convert_md_to_html方法裏面了。
感興趣的朋友可以去看看。
最後我們的實現代碼如下:
# 文章內容 html版本
content_file = common_config['content']
# 注意,zhihu 不能識別轉換過後的代碼塊格式
content_file_html = convert_md_to_html(content_file)
get_html_web_content(driver, content_file_html)
time.sleep(2) # 等待2秒
driver.switch_to.window(driver.window_handles[-1])
time.sleep(1) # 等待1秒
# 不能用元素賦值的方法,所以我們使用拷貝的方法
cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL
action_chains = webdriver.ActionChains(driver)
# 點擊內容元素
content_element = driver.find_element(By.XPATH, '//div[@class="DraftEditor-editorContainer"]//div[@class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr"]')
content_element.click()
time.sleep(2)
# 模擬實際的粘貼操作
action_chains.key_down(cmd_ctrl).send_keys('v').key_up(cmd_ctrl).perform()
time.sleep(3) # 等待5秒 不需要進行圖片解析
解釋下實現的邏輯。
convert_md_to_html是把markdown轉換成了html。
get_html_web_content是在新的web tab中打開這個html文件,然後使用系統的複製功能把html內容拷貝到剪貼板上。
然後再定位到要粘貼的位置,使用系統的粘貼功能把內容粘貼到內容框中。
設置封面
很棒的是知乎的的上傳封面有一個input標籤,如下所示:
所以我們可以使用selenium的input上傳功能,來上傳封面。
封面數據可以寫到markdown文件的YAML Front Matter中,如下所示:
具體的實現代碼如下:
file_input = driver.find_element(By.XPATH, "//input[@type='file']")
# 文件上傳不支持遠程文件上傳,所以需要把圖片下載到本地
file_input.send_keys(download_image(front_matter['image']))
time.sleep(2)
投稿至問題
說實話,這個我真的不知道怎麼實現,因爲每個文章對應的問題是不一樣的。
所以這個作爲待解決的問題。如果有朋友希望我實現這個功能,可以跟我說。
文章話題
知乎這個文章話題實現起來比較困難。
因爲知乎會自動給你文件打上話題。如果要自定義話題的話,需要先刪除已有的話題,然後再添加上自己的話題。
這個這裏就不實現了。
專欄收錄
專欄當然要收錄在自己的專欄裏面啦。
所以我們需要點擊發布到專欄按鈕。
還好,知乎的的專欄按鈕是有一個id的。
# 專欄收錄
pubish_panel = driver.find_element(By.ID, 'PublishPanel-columnLabel-1')
pubish_panel.click()
最後的發佈
最後就是確認發佈了。我們找到最後的發佈按鈕,點擊即可。
confirm_button = driver.find_element(By.XPATH, '//button[contains(text(), "發佈")]')
confirm_button.click()