最近、不労所得を得る事を目的に自動化にハマっており、いくつかシステムを作りました。
その一貫で5chまとめサイトに自動投稿するシステムを作ったので、ここではそのデモとコードを紹介します。
5chまとめサイト自動投稿システムのデモ
日本語版
English
使用環境
使用環境としては下記を使用しています。
- JupyterLab Version 2.1.5
- Selenium
- Mac OS Catalina 10.15.2
- Google Chrome 86.0.4240.75
自動投稿システムで使用したコード
下記に、そのデモで実際に使用したコードの一部を貼り付けておきます。
元々は全て貼り付ける予定でしたが、Amazonの電子書籍という形で出版する事にしました。
Kindle Unlimited(読み放題サービス)に加入している方であれば無料で中身を見れるので、そちらで確認してみてください。
URLはこちらです。
USER、PASS、ファイルパスはご自身で設定したものをお使い下さい。
基本的にはそのまま使用する事ができると思いますが、Wordpressのバージョンやウェブサイトのアップデート等により、正常に動作しない場合もあります。
その際はお気軽にご相談ください(エラー画面と一緒にお問い合わせコーナーから質問を投げてください)。
Beatutiful soupやSeleniumは便利なのは良いですが、環境の影響をうけやすくてメンテナンスが必要なのがネックですね。
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 | #!/usr/bin/env python # coding: utf-8 #ブラウザ操作用 from selenium import webdriver #recaptcha対策で常にログイン状態を保持するためにoptionでargumentが必要 from selenium.webdriver.chrome.options import Options #所定時間待機用 import time #データ解析用 import pandas as pd #HTML解析用 from bs4 import BeautifulSoup #HTTPリクエスト用 import urllib.request as req #相対URL→絶対URL変換用 import urllib #画像保存フォルダ作成用 from pathlib import Path #リンクファイル読み込み用 import csv #javascriptでボタンをクリックする用 from selenium.webdriver.common.action_chains import ActionChains #selectタグを選択できるようにする from selenium.webdriver.support.ui import Select #絵文字駆逐用 import emoji #エンターキーを押す用 from selenium.webdriver.common.keys import Keys #chromeのユーザプロファイル新規作成用 import os #Google画像検索取得用 from PIL import Image import io import requests import hashlib import random #まとめくす ログイン情報 USER = "your_address" PASS = "your_pass" #selenium用ユーザプロファイルを使用する場合 #option設定。ログイン状態を保持する https://rabbitfoot.xyz/selenium-chrome-profile/ PROFILE_PATH = 'your_path' PROFILE_DIRECTORY = 'your_profile' options = Options() 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) ###################################################### # youtuberリスト読み込み ###################################################### #キャプチャ画像のパス listfile = 'your_file' #cronを使用する場合は絶対パスを使用 youtuber_list = [] with open(listfile) as f: all_youtuber = csv.reader(f) for youtuber in all_youtuber: youtuber_list.append(youtuber[0]) print(youtuber_list) ###################################################### # グローバル変数設定 ###################################################### res_number = 0 #対象となるスレッドのレスの総数 is_succeeded = 0 #まとめくすでスレッドの取得が成功したら1, 失敗したら0 thread_title = '' #wordpressの投稿の記事タイトルにする用 yoyaku_is_succeeded = 0 #要約が成功したら1,失敗したら0 res_is_found = 0 #条件に合うレスが見つかったら1, 見つからなかったら0 img_is_existed = 0 #もしスレッド内に画像があったら、Google画像検索ではなくスレッド内の画像を使う wp_is_succeeded = 0 #wordpressへの投稿が成功したら1 ###################################################### # ログ速でホットなスレッドを取得 ###################################################### #指定されたクエリからレスを取得する関数 (thread_numberで何個目のスレッドを取得するかを指定する) def getReses(word): #res_numberがグローバル変数である事を教えてあげる必要あり global res_number global res_is_found res_is_found = 0 #フラグをリセット #まずはログ速の検索画面へ url = 'https://www.logsoku.com/search?q='+ word driver.get(url) time.sleep(1) print('ログ速ページにアクセスしました') #1ページ目の全てのスレッドのURLを取得 logsoku_urls = [] elems = driver.find_elements_by_css_selector('td.title > a') for i in range(len(elems)): for elem in elems: logsoku_url = elem.get_attribute('href') logsoku_urls.append(logsoku_url) #レスの数が少なかったら次のスレッドにする logsoku_resnumber = [] nums = driver.find_elements_by_css_selector('td.length') #投稿が見つかったら if len(elems) > 0: for i in range(5): if i < len(elems): title = elems[i].text print('タイトルは ' + elems[i].text) print('レス数は ' + nums[i+1].text) if ('【悲報】' in title or '【朗報】' in title or '【速報】' in title or '【疑問】' in title or '【真実】' in title or '【衝撃】' in title or '【話題】' in title or '【訃報】' in title or '【報告】' in title or '【動画】' in title or '【画像】' in title) and int(nums[i+1].text) > 5 and len(elems[i].text) < 60 and not ('part' in elems[i].text or 'Part' in elems[i].text): url = logsoku_urls[i] #レスの数をグローバル変数に格納する (resesには改行タグが全ての行に含まれているので、正味のレスの数はその半分) res_number = int(nums[i+1].text) res_is_found = 1 break #レスが見つかった場合のみ if res_is_found == 1: driver.get(url) time.sleep(1) #1つ目の掲示板URLを取得 board_url = driver.find_elements_by_class_name('nav-btn')[0].get_attribute('href') #欲しいURLは必ずnab-btnの1つ目にあったので #デフォルトだと最新の50記事しか取得しない。そのためURLの最後の"/l50"の4文字を削除 if '/l50' in board_url: board_url = board_url.rstrip('/l50') print(board_url) #スレッドページへ driver.get(board_url) time.sleep(8) #すごい遅い時あったので長めに待つ print('スレッドページにアクセスしました') #レスを取得 (URLを含んだ行は削除) l_removed_list = [] #2ch.sc, 2ch.net, open2ch.net, bbspink.com でそれぞれ取得方法が異なるので注意!! if ('2ch.sc' in board_url) or ('5ch.sc' in board_url): elems = driver.find_elements_by_css_selector('dd.net') #サイトによっては、dd.netが存在せずddだけの場合もあったので if not elems: elems = driver.find_elements_by_css_selector('dd') elif ('2ch.net' in board_url) or ('5ch.net' in board_url): elems = driver.find_elements_by_css_selector('dd') elif ('open2ch.net' in board_url) or ('open5ch.net' in board_url): elems = driver.find_elements_by_css_selector('dd.mesg') elif 'bbspink.com' in board_url: elems = driver.find_elements_by_css_selector('dd') for elem in elems: elemtext = elem.text #レスごとに除去 #if not '>>' in elemtext: #Lineごとに除去 #URLが混じっていると文章要約制度が落ちるので除外 l_removed = [line for line in elemtext.splitlines() if not (('http' in line) or ('tp:/' in line) or ('jpg' in line) or ('tps:/' in line) or ('jpeg' in line) or ('bmp' in line) or ('gif' in line) or ('png' in line) or ('mpg' in line) or ('>>' in line))] l_removed_list.append(l_removed) l_removed_list.append('\n') #レスを一つの文字列に合体 gathered_reses = [] for i in range(len(l_removed_list)): gathered_res = '\n'.join(l_removed_list[i]) #.joinができてなさそう。あとで要確認 #絵文字除去 gathered_res = remove_emoji(gathered_res) gathered_reses.append(gathered_res) print(gathered_reses) return gathered_reses, board_url else: print('今回は良いレスが見当たらなかったよ!') #絵文字駆逐関数 def remove_emoji(src_str): return ''.join(c for c in src_str if c not in emoji.UNICODE_EMOJI) |
困ったときはお気軽にご相談下さい
冒頭でも言いましたが、SeleniumやBeautiful soupは環境による影響を大きく受けます。
エラーが出て全然動かない、、というかたはお気軽にご相談ください。
あと1行ずつに細かいノウハウもあるので、そのあたりは余力があればまた動画やこちらのサイトで説明していきたいと思います。
「こんな自動化システムを作って欲しい」という相談も受け付けていますので、どしどしリクエスト下さい!
I'm receiving requests that relate to this kind of automatic system.
Don't hesitate to contact me!