Qiitaに予約投稿する仕組みを作る【予約投稿編】 ~1日10行コーディング 〜~

## 9日目

前回から発展させてQiitaに自動投稿する仕組みを作りたいと思います。

### 【技術テーマ】
Qiitaへの自動投稿

### 言語
* Ruby

### 目標成果物
Qiitaの自分の下書きを予定日に自動投稿する

### コードと資料

#### 挫折

前回までmechanizeで頑張ってきてたのですが、どうしても投稿する部分ができず、諦めて禁断のseleniumを使うことにしました...
その点だけご了承ください.....

### seleniumで前回までのところを爆速で作る

ただ、seleniumにするとホント...頭使わない脳筋プレイができてしまうんですね...
JSが使えてしまうので....

Gemfile

```Gemfile
gem 'selenium-webdriver'
```

Gemfileに上記のものを追加して、

```crawler.rb
require 'nokogiri'
require 'mechanize'
require 'selenium-webdriver'

def selemium_init
  ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36'
  # caps = Selenium::WebDriver::Remote::Capabilities.chrome('chromeOptions' => { args: ["--user-agent=#{ua}", 'window-size=1280x800', '--incognito'] }) # シークレットモード
  caps = Selenium::WebDriver::Remote::Capabilities.chrome('chromeOptions' => {args: ["--headless","--no-sandbox", "--disable-setuid-sandbox", "--disable-gpu", "--user-agent=#{ua}", 'window-size=1280x800']})
  
  client = Selenium::WebDriver::Remote::Http::Default.new
  driver = Selenium::WebDriver.for :chrome, desired_capabilities: caps  
end

driver = selemium_init
driver.navigate.to 'https://qiita.com/login'
driver.execute_script("document.getElementsByName('identity')[0].value = 'メールアドレス'")
driver.execute_script("document.getElementsByName('password')[0].value = 'パスワード'")
driver.execute_script("document.getElementsByName('commit')[0].click()")
sleep 1
driver.navigate.to 'https://qiita.com/drafts'
```

これだけでログインして、下書きのページに飛ぶところまで完了です...
もうね、こんなの作業ですよ笑

### 日付比較〜予約投稿まで実装


そこに実際に記事を投稿する機能を付けて、日付の比較をすれば...

```crawler.rb
require 'nokogiri'
require 'mechanize'
require 'selenium-webdriver'

def selemium_init
  ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36'
  # caps = Selenium::WebDriver::Remote::Capabilities.chrome('chromeOptions' => { args: ["--user-agent=#{ua}", 'window-size=1280x800', '--incognito'] }) # シークレットモード
  caps = Selenium::WebDriver::Remote::Capabilities.chrome('chromeOptions' => {args: ["--headless","--no-sandbox", "--disable-setuid-sandbox", "--disable-gpu", "--user-agent=#{ua}", 'window-size=1280x800']})
  
  client = Selenium::WebDriver::Remote::Http::Default.new
  driver = Selenium::WebDriver.for :chrome, desired_capabilities: caps  
end

driver = selemium_init
driver.navigate.to 'https://qiita.com/login'
driver.execute_script("document.getElementsByName('identity')[0].value = 'メールアドレス'")
driver.execute_script("document.getElementsByName('password')[0].value = 'パスワード'")
driver.execute_script("document.getElementsByName('commit')[0].click()")
sleep 1
driver.navigate.to 'https://qiita.com/drafts'

doc = Nokogiri::HTML.parse(driver.page_source, nil, 'utf-8')
json = JSON.parse(doc.css('.js-react-on-rails-component')[1].inner_html)
json['creating_draft_items'].each do |item|
  if item['raw_body'].match(/予約投稿/)
    date = item['raw_body'].split('予約投稿:')[1]
    # 予約投稿予定日のものがあったら
    if Date.today == Date.parse(date)
      driver.navigate.to "https://qiita.com/drafts/#{item['item_uuid']}/edit?resume=true"
      element = driver.find_element(:class, 'editorSubmit_dropdownToggle')
      element.click
      element = driver.find_elements(:class,'editorSubmit_dropdownItem')[2]
      element.click
      submit_element = driver.find_element(:class,'editorSubmit_submitBtnLabel')
      submit_element.click
      label_element = driver.find_element(:class,'creatingModal_label')
      label_element.click
      button_element = driver.find_elements(:class,'btn-primary')[-1]
      button_element.click
      end
  end
end
```

これで完成です。
このバッチを毎日20時位に流せば20時に自動で投稿されるというわけです....

試しにサーバーでcronを設定して動かしてみます！！！！
(この記事で予約投稿を試してみます笑)

→いやぁ..めっちゃ馬鹿なミスに気づきました...この記事には予約投稿って文字が添付したソースにも乗ってるからパースでコケてたわ....

予約投稿:2020-06-12