CSDN應該是大家接觸到最多的部落格平臺了,所以一款能夠釋出到CSDN的自動化工具還是非常有必要的。
今天給大家講講自動化CSDN部落格釋出的思路和一些問題的解決辦法。
解決問題的思路一定是最重要的,知識是死的,問題是活的,如何在工作中解決遇到的問題是我們需要面臨的大問題。
前提條件
前提條件當然是先下載 blog-auto-publishing-tools這個部落格自動釋出工具,地址如下:https://github.com/ddean2009/blog-auto-publishing-tools
CSDN的實現
csdn的文章編輯頁面進入很簡單,在你已經登入的情況下,直接訪問https://editor.csdn.net/md/就可以進入他的部落格釋出頁面了。
具體實現的程式碼在publisher/csdn_publisher.py中。
標題
csdn的標題部分,沒有ID,也沒有name,只有一個孤零零的input。
那麼我們怎麼找到這個元素呢?
一個常用的辦法是透過xpath和placeholder來定位到這個input元素。
# 文章標題
title = driver.find_element(By.XPATH, '//div[contains(@class,"article-bar")]//input[contains(@placeholder,"請輸入文章標題")]')
title.clear()
if 'title' in front_matter['title'] and front_matter['title']:
title.send_keys(front_matter['title'])
else:
title.send_keys(common_config['title'])
time.sleep(2) # 等待3秒
文章內容
csdn的文章內容部分也是動態變動的,不是一個固定的textarea,但是看了它的程式碼,用的也不是常見的CodeMirror,我猜應該是自己實現的一個動態編輯器。
不過沒關係,萬變不離其宗。
既然不用使用send_keys來新增內容,我們就是用複製和複製大法來實現這個功能。
# 文章內容 markdown版本
file_content = read_file_with_footer(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[@class="editor"]//div[@class="cledit-section"]')
content.click()
time.sleep(2)
# 模擬實際的貼上操作
action_chains.key_down(cmd_ctrl).send_keys('v').key_up(cmd_ctrl).perform()
time.sleep(3) # 等待3秒
複製就是通用的流程了。
但是複製之前,我們需要先定位到複製的地址。
這裡我用的是xpath定位到editor class下面的cledit-section。
定位之後,按下click按鈕,然後直接貼上內容即可。
釋出文章按鈕
內容都輸入好之後,我們就可以點選右邊的釋出文章按鈕了。
csdn的按鈕沒有id,所以我們還是得使用xpath來定位到這個button。
# 釋出文章
send_button = driver.find_element(By.XPATH, '//button[contains(@class, "btn-publish") and contains(text(),"釋出文章")]')
send_button.click()
time.sleep(2)
點選發布文章後,會有一個彈窗框:
這個彈出框裡面是需要填寫的一些額外資訊。比如文章標籤,新增封面,文章摘要,分類專欄,文章型別和可見範圍等等內容。
文章標籤
新增文章標籤的路徑有點複雜。
首先我們點選新增文章標籤按鈕,這時候又會彈出一個對話方塊。
在這個對話方塊裡面,我們需要文字搜尋框,輸入tag,然後回車,然後繼續輸入tag,繼續回車。
做完所有的操作之後,還需要點選右上角的x關閉按鈕,把這個彈出框關閉。
# 文章標籤
if 'tags' in front_matter and front_matter['tags']:
tags = front_matter['tags']
else:
tags = csdn_config['tags']
if tags:
add_tag = driver.find_element(By.XPATH,
'//div[@class="mark_selection"]//button[@class="tag__btn-tag" and contains(text(),"新增文章標籤")]')
add_tag.click()
time.sleep(1)
tag_input = driver.find_element(By.XPATH, '//div[@class="mark_selection_box"]//input[contains(@placeholder,"請輸入文字搜尋")]')
for tag in tags:
tag_input.send_keys(tag)
time.sleep(2)
tag_input.send_keys(Keys.ENTER)
time.sleep(1)
# 關閉按鈕
close_button = driver.find_element(By.XPATH, '//div[@class="mark_selection_box"]//button[@title="關閉"]')
close_button.click()
time.sleep(1)
新增封面
CSDN的封面會自動檢測文章內容中的圖片,把這些圖片設定為文章的封面。
當然我們也可以自行設定。
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)
要注意的是,這裡的image地址是在markdown檔案中的yaml front matter中設定的。
如圖所示:
設定摘要
csdn的摘要部分也沒有ID,還是需要透過xpath來進行獲取。
這裡透過textarea的placeholder來進行獲取。
# 摘要
if 'description' in front_matter['description'] and front_matter['description']:
summary = front_matter['description']
else:
summary = common_config['summary']
if summary:
summary_input = driver.find_element(By.XPATH, '//div[@class="desc-box"]//textarea[contains(@placeholder,"摘要:會在推薦、列表等場景外露")]')
summary_input.send_keys(summary)
time.sleep(2)
分類專欄
csdn的分類專欄需要提前建立好。
每個專欄都是一個checkbox,我們可以透過checkbox的value來定位到這個專欄選項。
實現程式碼如下:
# 分類專欄
categories = csdn_config['categories']
if categories:
for category in categories:
category_input = driver.find_element(By.XPATH, f'//input[@type="checkbox" and @value="{category}"]/..')
category_input.click()
time.sleep(1)
可見範圍
最後可以設定的就是文字的可見範圍了。
可見範圍是有id的,我們可以根據id來獲取到這個input,然後點選他。
# 可見範圍
visibility = csdn_config['visibility']
if visibility:
visibility_input = driver.find_element(By.ID, visibility)
visibility_input.click()
最後的釋出
最後,我們終於可以釋出了。
csdn的釋出按鈕也沒有id,我們只能透過對應的class和button的text內容來定位到釋出按鈕。
# 釋出
if auto_publish:
publish_button = driver.find_element(By.XPATH, '//div[@class="modal__button-bar")]//button[contains(text(),"釋出文章")]')
publish_button.click()
總結
CSDN的實現還是比較複雜的,因為涉及到的東西比較多。大家可以好好琢磨琢磨。
點我檢視更多精彩內容:www.flydean.com