寫在開始
本篇介紹用Python
+Selenium
自動發佈簡書文章,一些必要的前置準備說明在上篇文章裏面有提到,這裏就不再重複了。
使用說明
同樣的,還是需要先分析下簡書寫博客的界面(記得設置默認編輯器爲Markdown)。
write-blog-jianshu
從上圖可以看到,在簡書寫一篇博客,需要依次選擇分類(也就是文集),新建文章,然後填入標題和內容。
結合auto.md
的內容進行分析,標題有了,定義在title
處;正文內容同樣通過匹配-->\n
獲取。剩下分類,按規則已經定義在註釋裏了(self_category
)。
代碼說明
main.py:程序入口類,主要負責正則匹配解析Markdown
和調用post
發佈文章
import re import jianshu import linecache class Main(object): # init def __init__(self, file): self.title = '' self.content = '' self.category = '' self.tags = '' # OsChina的系統分類, 設個默認值 self.osChina_sys_category = '編程語言' # CSDN的文章分類, 設個默認值 self.csdn_article_category = '原創' # CSDN的博客分類, 設個默認值 self.csdn_blog_category = '後端' self.read_file(file) # 讀取MD中的title, content, self_category, self_tags, osChina_sys_category, csdn_article_category, csdn_blog_category def read_file(self, markdown_file): self.title = linecache.getline(markdown_file, 2).split('title: ')[1].strip('\n') with open(markdown_file, 'r', encoding='UTF-8') as f: self.content = f.read().split('-->\n')[1] # 重置文件指針偏移量 f.seek(0) for line in f.readlines(): if re.search('self_category: ', line) is not None: self.category = line.split('self_category: ')[1].strip('\n') elif re.search('self_tags: ', line) is not None: self.tags = line.split('self_tags: ')[1].strip('\n') elif re.search('osChina_sys_category: ', line) is not None: self.osChina_sys_category = line.split('osChina_sys_category: ')[1].strip('\n') elif re.search('csdn_article_category: ', line) is not None: self.csdn_article_category = line.split('csdn_article_category: ')[1].strip('\n') elif re.search('csdn_blog_category: ', line) is not None: self.csdn_blog_category = line.split('csdn_blog_category: ')[1].strip('\n') if __name__ == '__main__': md_file = 'auto.md' print("Markdown File is ", md_file) timeout = 10 main = Main(md_file) # 簡書 jian_shu = jianshu.JianShu() jian_shu.post(main, timeout)
authorize.py:目前僅實現了用qq進行授權登錄的方法
from selenium.webdriver.support.wait import WebDriverWait # QQ授權登錄, 使用前提是QQ客戶端在線 def qq(driver, timeout): # 切換到最新打開的窗口 window_handles = driver.window_handles driver.switch_to.window(window_handles[-1]) print('qq authorize title is ', driver.title) # 切換iframe iframe = WebDriverWait(driver, timeout).until(lambda d: d.find_element_by_id('ptlogin_iframe')) driver.switch_to.frame(iframe) # 點擊頭像進行授權登錄 login = WebDriverWait(driver, timeout).until(lambda d: d.find_element_by_xpath('//*[@id="qlogin_list"]/a[1]')) login.click()
jianshu.py:這個是簡書自動寫(發)博客的核心類
import time import authorize from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait # 簡書 class JianShu(object): @staticmethod def post(main, timeout, self_timeout=3): # 1.跳轉登陸 login = 'https://www.jianshu.com/sign_in' driver = webdriver.Chrome() driver.get(login) # 2.窗口最大化 driver.maximize_window() # 3.使用QQ授權登錄 driver.find_element_by_xpath('/html/body/div[1]/div[2]/div/div/ul/li[3]/a/i').click() driver.close() authorize.qq(driver, timeout) # 4.點擊"寫文章" write_blog = WebDriverWait(driver, timeout).until(lambda d: d.find_element_by_xpath('/html/body/nav/div/a[2]')) write_blog.click() driver.close() window_handles = driver.window_handles driver.switch_to.window(window_handles[-1]) # 5.點擊指定分類 classify = WebDriverWait(driver, timeout).until(lambda d: d.find_elements_by_class_name('_3DM7w')) for c in classify: html = c.get_attribute('innerHTML') if main.category in html: c.click() else: # TODO 如果分類不存在,還可以直接新建分類 pass # 6.點擊'新建文章' time.sleep(self_timeout) new_article = WebDriverWait(driver, timeout).until( lambda d: d.find_element_by_xpath('//*[@id="root"]/div/div[2]/div[1]/div/div/div/div[1]/i')) new_article.click() article = WebDriverWait(driver, timeout).until( lambda d: d.find_element_by_xpath('//*[@id="root"]/div/div[2]/div[1]/div/div/div/ul/li[1]')) article.click() # 7.填寫標題, 內容 time.sleep(self_timeout) title = driver.find_element_by_class_name('_24i7u') title.clear() title.send_keys(main.title) content = driver.find_element_by_id('arthur-editor') content.clear() content.send_keys(main.content) # 8.保存草稿 driver.find_element_by_xpath('//*[@id="root"]/div/div[2]/div[2]/div/div/div/div/ul/li[8]/a').click() # 8.發佈文章 # driver.find_element_by_xpath('//*[@id="root"]/div/div[2]/div[2]/div/div/div/div/ul/li[1]/a').click()
其實簡書也是支持賬號密碼登錄的,但無奈這種方式登錄還有文字驗證層,感覺比較棘手,目前也沒研究怎麼解決,所以先用qq授權的方式登錄吧。
運行效果
還是來看看運行效果圖吧,這裏測試的是保存草稿。
auto-post-jianshu
寫在最後
在簡書自動寫文章的思路大概就這樣,同樣這也不是唯一的辦法,根據代碼自己做調整即可,網頁的結構也可能會改變,故不保證程序可以一直正常運行。最後,下一篇繼續介紹如何在CSDN自動寫(發)文章。