こんにちは、ボーノです。
今回は、Seleniumとマルコフ連鎖を使って、自動での文章生成と自動でのWordpressへの投稿のデモをやってみます。
今回はアフィリエイターに方に耳寄りの情報です。
一部のアフィリエイターは、新規・中古ドメインをいくつも用意し、最初は「適当な」記事を仕込んでおいて、順位が上がってきたらちゃんとした記事を入れる、という事を行っています。
その「適当な」記事を作成するツールが世の中にはあります(例えばラクキジやCワードなど)
しかし、実はこの「適当な」記事は、Seleniumとマルコフ連鎖を使用する事で自動生成し、且つ自動投稿する事が可能なんです。
フローとしては下記になります。
- 狙いたいキーワードでGoogle検索
- 上位ページの本文を取得
- 2の文字列を元に、マルコフ連鎖で新たな記事を生成
- Seleniumでアフィリエイトサイトに自動ログイン
- 3で作成した記事を投稿・公開
- 上記1〜5をアフィリエイトサイトの分だけ繰り返す
このように、ブラウザ自動化はアイデア次第では応用例が無限にあるので、皆さんもやりたい事を明確にして、トライしてみてはいかがでしょうか?
YouTubeでのデモ
使用したコード
実際に使用しているコードです。
ご自由にお使い下さい!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 | ############################################################################################################ # 記事自動ポスト サテライト用 マルコフ連鎖使用 V1 # ・メインキーワードで検索して上位10個から1つのサイトを決定 # ・記事の見出しを全て取得→見出しは最大10個、10文字以下は除外 # ・本文をマルコフ連鎖で作成 # ・自動でwordpressに投稿 ############################################################################################################ import os # ディレクトリの操作用 from selenium.webdriver import Chrome, ChromeOptions # ヘッドレスブラウザ from selenium.webdriver.chrome.options import Options from selenium import webdriver #所定時間待機用 import time #正規表現用 import re #キー操作用 from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.action_chains import ActionChains #pythonでコピペをする用 import pyperclip #リンクファイル読み込み用 import csv #YouTubeタイトルに絵文字が含まれているかを検知する用 #import emoji import sys #メモリ不足で重くなるのを解消する 参考:https://iseed.jp/selenium-tips/ #Options.add_argument('--disable-dev-shm-usage') #ポップアップアラートポップアップアラートをクリックする用 from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions from selenium.webdriver.common.alert import Alert #乱数生成用 import random #Beautiul soup用 import requests from bs4 import BeautifulSoup #マルコフ連鎖用 import re import MeCab from collections import deque #絵文字駆逐用 import emoji #アラート用 from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException #辞書の順番を保つ(通常の辞書は順番情報は持たないため順番がランダムになる) from collections import OrderedDict ###################################################### # サイト設定 ###################################################### #サテライトサイト情報 site_dict = OrderedDict() site_dict = { 'キーワード':'サイトURL', } #wordpressログイン情報 USER = 'ユーザ名' PASS = 'パスワード' ###################################################### # グローバル変数 ###################################################### selected_site_url = '' #Google検索でランダムで選んだ1つのサイト first_midashi = 0 #一番最初の見出し (記事のタイトルに設定する用) ###################################################### # 初期設定 ###################################################### #selenium用ユーザプロファイルを使用する場合 #option設定。ログイン状態を保持する https://rabbitfoot.xyz/selenium-chrome-profile/ PROFILE_PATH = 'プロファイルのパス' PROFILE_DIRECTORY = 'プロファイルが保存されているディレクトリ' options = Options() #Driverの読み込みとラクキジ拡張機能の読み込み options.add_argument("--user-data-dir=" + PROFILE_PATH) options.add_argument("--profile-directory=" + PROFILE_DIRECTORY) driver = webdriver.Chrome(executable_path = '/usr/local/bin/chromedriver', options = options) driver.implicitly_wait(1) ###################################################### # 絵文字除去 ###################################################### #絵文字駆逐関数 def remove_emoji(src_str): return ''.join(c for c in src_str if c not in emoji.UNICODE_EMOJI) ###################################################### # Googleでサイトを1つ決定し、見つかった記事から見出しの取得 ###################################################### def getMidashis(word): global selected_site_url midashis = [] #Googleでwordを検索 page_num = random.randrange(9)*10 #1〜10ページ目の範囲でkennsaku url = 'https://www.google.com/search?start='+ str(page_num) +'&q=' + word driver.get(url) time.sleep(2) #検索結果からランダムで記事を選択 index_num = random.randrange(7) + 1 #1〜10個目の記事からランダムに選択 広告が入ってると10を超える場合あるけど無視 elems = driver.find_elements_by_xpath('//*[@class="yuRUbf"]/a') selected_site_url = elems[index_num].get_attribute('href') print(selected_site_url) #見出しタグを取得 r = requests.get(selected_site_url) soup = BeautifulSoup(r.content, 'lxml') h2s = soup.find_all('h2') h3s = soup.find_all('h3') for i in range(len(h2s)): midashis.append(h2s[i]) for i in range(len(h3s)): midashis.append(h3s[i]) print(midashis) return midashis ###################################################### # サイトの本文を全て取得 ###################################################### def getBody(url): driver.get(url) time.sleep(2) r = requests.get(url) soup = BeautifulSoup(r.content, 'lxml') body = soup.body.get_text() #絵文字除去 body = remove_emoji(body) return body ###################################################### # マルコフ連鎖の準備 # https://qiita.com/k-jimon/items/f02fae75e853a9c02127 ###################################################### def wakati(text): t = MeCab.Tagger("-Owakati") parsed_text = "" for one_line_text in one_sentence_generator(text): parsed_text += " " parsed_text += t.parse(one_line_text) wordlist = parsed_text.rstrip("\n").split(" ") return wordlist def one_sentence_generator(long_text): sentences = re.findall(".*?。", long_text) for sentence in sentences: yield sentence order = 2 #まずはモデルを作成する def make_model(text): model = {} wordlist = wakati(text) queue = deque([], order) queue.append("[BOS]") for markov_value in wordlist: if len(queue) == order: if queue[-1] == "。": markov_key = tuple(queue) if markov_key not in model: model[markov_key] = [] model[markov_key].append("[BOS]") queue.append("[BOS]") markov_key = tuple(queue) if markov_key not in model: model[markov_key] = [] model[markov_key].append(markov_value) queue.append(markov_value) return model #作成したモデルを使って文章を新しく作り出す def make_sentence(model, sentence_num=10, seed="[BOS]", max_words = 1000): sentence_count = 0 key_candidates = [key for key in model if key[0] == seed] if not key_candidates: print("Not find Keyword") return markov_key = random.choice(key_candidates) queue = deque(list(markov_key), order) sentence = "".join(markov_key) for _ in range(max_words): markov_key = tuple(queue) next_word = random.choice(model[markov_key]) sentence += next_word queue.append(next_word) if next_word == "。": sentence_count += 1 if sentence_count == sentence_num: break #[BOS]の文字列が邪魔なので削除する sentence = sentence.replace('[BOS]', '') return sentence ###################################################### # マルコフ連鎖でオリジナル文章生成 ###################################################### def makeMarkovBody(body): text = body order = 3 model = make_model(text) markovbody = make_sentence(model) return markovbody ###################################################### # 見出しとオリジナル文章を合体 ###################################################### def makeArticle(midashis, body): global first_midashi article = '' midashi_num = 0 first_midashi = 0 for i in range(len(midashis)): if len(midashis[i].text) > 10: #見出しの文字数は一定数以上にしてゴミは除去 if first_midashi == 0: #一番最初の10文字以上の見出しを入れる first_midashi = i midashi_num = midashi_num + 1 if midashi_num < 5: #見出しは10個まで article = article+'<h2>'+midashis[i].text+'</h2>' markovbody = makeMarkovBody(body) article = article+markovbody return article ###################################################### # wordpressの操作 ###################################################### #wordpressログインページにアクセス def postWordpress(domain, article, midashis): global first_midashi #Wordpressにログイン url_login= domain + "/wp-login.php" driver.get(url_login) time.sleep(1) print(domain + 'のログインページにアクセスしました') #IDとパスワードのフォームに入力 elem = driver.find_element_by_id('user_login') elem.clear() elem.send_keys(USER) elem = driver.find_element_by_id('user_pass') elem.clear() elem.send_keys(PASS) print("フォームを送信") time.sleep(5) #ログインボタンを押してログイン browser_from = driver.find_element_by_name('wp-submit') browser_from.click() time.sleep(1) #テスト用 本当は1 print("情報を入力してログインボタンを押しました") #新規投稿ページにアクセス url_login= domain + "/wp-admin/post-new.php" driver.get(url_login) time.sleep(1) print(domain + 'の新規投稿ページにアクセスしました') #タイトルを入力(一番最初の見出しをいれる) title = driver.find_element_by_id('title') title.send_keys(midashis[first_midashi].text) #テキストタブをクリック elem = driver.find_element_by_id('content-html') elem.click() #ラク記事で生成した内容をコンテンツに追加 content = driver.find_element_by_id('content') content.send_keys(article) time.sleep(1) #更新ボタンが見えるところまでスクロール driver.execute_script('window.scrollTo(0, 0);') #注意!Seleniumでは画面で表示している領域の外にあるボタンはクリックできない! #設定を保存 time.sleep(1) #エラー出たのでここに挟んだ publish_post = driver.find_element_by_id('publish') publish_post.send_keys(Keys.SPACE) time.sleep(10) #公開までに5秒くらいかかった print('\n\n') num = 0 for word, domain in site_dict.items(): print(num) print(domain) num = num + 1 midashis = [] while 1: midashis = getMidashis(word) time.sleep(2) #これないと短時間にリクエストが発生してHTTPSConnectionPoolエラーになる if len(midashis) > 0: #見出しがないサイトがあるので break body = getBody(selected_site_url) article = makeArticle(midashis, body) if len(article) > 300: #中身がないサイトの場合は除去 300文字は目安 print('big article!!') postWordpress(domain, article, midashis) else: print('small article!!') print('\n\n') #プロセスを終了(これやらないとゾンビプロセスが増える) driver.quit() print('DONE!') |
関連リンク
マルコフ連鎖プログラム引用元
https://qiita.com/k-jimon/items/f02fa...
(このページはめちゃくちゃお勧めです!orderの数値などを変えると色々と結果が変わるようです)
Selenium
https://www.selenium.dev/documentatio...
ラクキジ
Cワード
まとめ
デモでも説明したように、Seleniumとマルコフ連鎖を使用して、適当な記事を自動で生成して、しかもそれをWordpressに投稿することは可能です。
このように、ブラウザ自動化はアイデア次第で色んなことが実現できるので、ぜひ皆さんも覚えてみてはいかがでしょうか。
ソフトウェアの知識がほとんどない自分でも作れたので、絶対皆さんもできると断言します。
不明な点などあったら問い合わせフォームよりご質問ください。
それでは。