猿でも分かる! PythonでFC2ブログを自動更新する方法を教えます

10 min読了の目安(約6300字TECH技術記事

皆さんこんにちは。

今回はPOST送信とXML-RPC,Seleniumで更新する方法をご紹介していきます。

今回紹介する方法とスクレイピングをかけ合わせれば、エログを手作業で更新する手間が省けます。

Google Croud PlatformやAWSを使えば、そのままFC2ブログの自動投稿ツールとしても使えるようになります。

自動更新ツールは、技術的にも決して難しいものではありませんし、作っていても面白いものですので、ぜひ取り組んでみてください。

*理解するために必要なスキル

こちらの記事を理解するには、以下のスキルと知識が必要です。もし、これらのスキルがない場合は、まず最低限の勉強をすると良いでしょう。

**HTML,CSS,JavaScript,Pythonの基礎知識
デベロッパーツールの使い方
Seleniumの基礎知識
**

それではまずそれぞれの技術のメリットをご紹介します。

XML-RPC投稿の特徴

XML-RPCでの投稿が一般的ですが、あまり細かく記事の設定を行えません。

アイキャッチ画像の指定や投稿テーマ等の詳細な設定が出来ず、詳細な投稿設定をしたい際には、少し不便です。

ただ、あまり詳細な投稿設定が必要ない場合は、XML-RPCがおすすめ。何故なら、少ないコードで自動投稿をすることが出来るからです。

POST送信の特徴

POST送信のメリットは、XML-RPCでの自動投稿のデメリットをカバーできること。

けれども、手動でサイトを更新するときと同じように細かく設定できます。

しかし、どうしても送信するデータが多くなるため、設定項目が多くなってしまいどうしてもコードが長くなってしまいます。

Seleniumの特徴

Seleniumは、自動でブラウザを操作するオートメーションツールです。

一般的にテストを自動化するために使われますが、スクレイピングでデータを取得したりする際にもよく使われます。

Seleniumではシステムの自動化だけでなく、ブログの自動化も出来ます。

ある程度Seleniumを使いこなすことが出来たら、簡単にスクリプトを組みことが出来るのですが、ある程度のプログラミングスキルが必要です。

少なくとも以下のNoteに書かれている知識とスキルが必要。

Seleniumを使いこなすのは、プログラミング初心者には難しいかもしれません。ただ使いこなせるようになった場合は、とても便利ですのでぜひ皆様にも身につけてもらえたらと思います。

それでは早速コードの方を見ていきましょう。まずPOST送信のやり方をご紹介します。

POST送信

import requests
#ログイン
class autoArticle:
   def __init__(self):
       self.headers = {"User-Agent": 
       "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"}
   
  def reqPost(self,email,password):
       headers = self.headers
       url = "https://secure.id.fc2.com/?mode=login&switch_language=ja&error=1"
  
       data = {
           "email":email,
           "pass":password,
           "keep_login":"1",
           "image":"ログイン",
           "done":"blog"
       }
       session = requests.Session()
       res = session.post(
           url,
           data=data,
           headers=headers
       )
       return session
   def sentArticle(self,session,title,tag,body):
       headers = self.headers
       data = {
               "entry[title]":title,
               "entry[category]":"0",
               "name":"",
               "entry[tag]":tag,
               "entry[allowtag]":"",
               "entry[body]":body,
               "entry[extend]":"",
               "entry[genre]":"",
               "entry[theme]":"",
               "entry[eyecatch]":"",
               "entry[sendtb]":"",
               "entry[format]":"b",
               "entry[allowcomment]":"n",
               "entry[allowtb]":"n",
               "entry[timestamp]":"auto",
               "entry[year]":"",
               "entry[month]":"",
               "entry[day]":"",
               "entry[hour]":"",
               "entry[minute]":"",
               "entry[second]":"",
               "entry[is_pinned]":"",
               "entry[property]":"y",
               "entry[topping]":"checked",
               "process":"save",
               "mode":"editor",
               "mission_id":"",
               "tbtheme_id":"",
               "entry[eno]":"",
               "MAX_FILE_SIZE":"500",
               "entry[sessid]":"",
               "entry[sespsd]":"",
               "checkid":"",
               }
       
       url = "https://admin.blog.fc2.com/control.php?mode=editor&process=new"
       res = session.post(
           url,
           data=data,
           headers=headers
       )
       print(res)
if __name__ == "__main__":
   ed = autoArticle()
   session = ed.reqPost("","")
   ed.sentArticle(session,"おはよう","Hello","おはよう")

変数名dataの中あるオブジェクトの名前は、Fc2の投稿画面のHTMLのnameです。

例えばentry[title]の場合は、以下を示しています。

上記画像は、右クリックを押した後検証を押せば開くことが出来ます。

XML-RPC投稿

import xmlrpc.client

def xmlrPost(infos,obj,PubNum):
   Domain =  "http://blog.fc2.com/xmlrpc.php"
   BlogID = infos.get("BlogID")
   UserName = infos.get("UserName")
   PassWord = infos.get("PassWord")
   con = {}
   con["title"] = obj.get("title")
   con["description"] = obj.get("description")
   con["mt_text_more"] = obj.get("mt_text_more")
   con["dateCreated"] = obj.get("dateCreated")
   publish = PubNum
   proxy = xmlrpc.client.ServerProxy(Domain)
   proxy.metaWeblog.newPost(BlogID,UserName,PassWord,con,publish)
if __name__ == "__main__":
   infos = {
       "BlogID":"",
       "UserName":"",
       "PassWord":"",
   }
   obj = {
       "title":"Hello",
       "description":"Hello",
       "mt_text_more":"",
       "dateCreated":""
   }
   #下書き 0 公開1
   pubNum = 1
  xmlrPost(infos,obj,pubNum)

変数名infosには、ブログIDとユーザー名、パスワードを格納オブジェクト型が格納されています。

変数名infosには、ブログIDとユーザー名、パスワードを

変数名objには、タイトルと本文、追記と時間を設定しています。

Selenium

from selenium import webdriver
from time import sleep
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException


def GetID(wait,id):
   return wait.until(expected_conditions.visibility_of_element_located((By.ID,id)))
   
def GetName(wait,name):
   return wait.until(expected_conditions.visibility_of_element_located((By.NAME,name)))

class Fc2Auto:
   def __init__(self):
       options = webdriver.ChromeOptions()
       options.add_argument("")
       #パスを指定
       bot = webdriver.Chrome(executable_path="", chrome_options=options)
       self.bot = bot
       self.wait = WebDriverWait(bot,60)

   def AutoPost(self,url,title,value):
       bot = self.bot
       bot.get(url)
       wait = self.wait
       #タイトルを設定
       EntryTitle = GetID(wait,"entry_title")
       EntryTitle.send_keys(title)
       #ボディを設定
       EntryBody = GetName(wait,"entry[body]")
       EntryBody.send_keys(value)

       saveButton = """
       const save_button= document.querySelector(`[value="記事を保存"]`);
       save_button.click();
       """

       bot.execute_script(saveButton)

       bot.quit()

if __name__ == "__main__":
   ed = Fc2Auto()
   ed.AutoPost("",
               "Hello",
               "Hello")

このプログラムは、Seleniumで自動投稿するプログラム。

関数名GetIDは、IDで要素を取得する関数で、関数名GetNameはnameで取得する関数です。

FC2の場合、まずログインする必要があります。ただプログラムを起動する度にログインしていては、FC2側に不正ログイン扱いされる可能性があるでしょう。

そのため、セッションでログイン状態を保持する必要があります。

Seleniumでログイン情報を保持する方法は、以下のサイトが詳しい。

Seleniumで次の実行時にもサイトのログイン状態を維持したい場合

最後まで読んでいただきありがとうございました。
他のサイトを自動化してみたり、色々なWeb APIを使っていきます。
これからもよろしくお願いします。