|
@@ -0,0 +1,123 @@
|
|
|
+import time
|
|
|
+import numpy as np
|
|
|
+import pandas as pd
|
|
|
+import requests
|
|
|
+import os
|
|
|
+from selenium import webdriver
|
|
|
+from selenium.webdriver.common.by import By
|
|
|
+from selenium.webdriver.support.ui import WebDriverWait
|
|
|
+from selenium.webdriver.support import expected_conditions as EC
|
|
|
+from selenium.webdriver.common.keys import Keys
|
|
|
+from selenium.common.exceptions import NoSuchElementException
|
|
|
+from selenium_stealth import stealth
|
|
|
+import redis
|
|
|
+import json
|
|
|
+import random
|
|
|
+import fire
|
|
|
+
|
|
|
+
|
|
|
+def open_driver(profile_file):
|
|
|
+ op = webdriver.ChromeOptions()
|
|
|
+ # op.binary_location = os.environ.get("GOOGLE_CHROME_BIN")
|
|
|
+ # op.add_argument('--headless')
|
|
|
+ op.add_argument('--disable-dev-shm-usage')
|
|
|
+ op.add_argument('--no-sandbox')
|
|
|
+ op.add_argument(r'user-data-dir=C:\Users\Administrator\AppData\Local\Google\Chrome\User Data')
|
|
|
+ op.add_argument(f"profile-directory={profile_file}")
|
|
|
+ op.add_experimental_option("excludeSwitches", ["enable-automation"])
|
|
|
+ op.add_experimental_option('useAutomationExtension', False)
|
|
|
+ driver = webdriver.Chrome(options=op,
|
|
|
+ executable_path=r'C:\Users\Administrator\Downloads\chromedriver_win32 (4)\chromedriver')
|
|
|
+ # stealth(driver,
|
|
|
+ # languages=["en-US", "en"],
|
|
|
+ # vendor="Google Inc.",
|
|
|
+ # platform="Win32",
|
|
|
+ # webgl_vendor="Intel Inc.",
|
|
|
+ # renderer="Intel Iris OpenGL Engine",
|
|
|
+ # fix_hairline=True,
|
|
|
+ # )
|
|
|
+ time.sleep(5)
|
|
|
+ # driver.get("https://www.youtube.com/watch?v=eFZckOTi24c")
|
|
|
+ # driver.find_element(By.XPATH,'// *[ @ id = "openid-buttons"] / button[1]').click()
|
|
|
+ return driver
|
|
|
+
|
|
|
+
|
|
|
+def comment_page(driver, url, comment):
|
|
|
+ if len(url) == 0:
|
|
|
+ print('Youtube Comment Bot: Finished!')
|
|
|
+ return []
|
|
|
+
|
|
|
+ # url = urls.pop()
|
|
|
+
|
|
|
+ driver.get(url)
|
|
|
+ print(url)
|
|
|
+ driver.implicitly_wait(1)
|
|
|
+
|
|
|
+ if not check_exists_by_xpath(driver, '//*[@id="movie_player"]'):
|
|
|
+ return comment_page(driver, url, random_comment())
|
|
|
+ time.sleep(4)
|
|
|
+ driver.execute_script("window.scrollTo(0, 600);")
|
|
|
+
|
|
|
+ if not check_exists_by_xpath(driver, '//*[@id="simple-box"]/ytd-comment-simplebox-renderer'):
|
|
|
+ return comment_page(driver, url, random_comment())
|
|
|
+
|
|
|
+ if check_exists_by_xpath(driver, '//*[@id="contents"]/ytd-message-renderer'):
|
|
|
+ return comment_page(driver, url, random_comment())
|
|
|
+
|
|
|
+ WebDriverWait(driver, 20).until(
|
|
|
+ EC.presence_of_element_located((By.CSS_SELECTOR, "ytd-comments ytd-comment-simplebox-renderer")))
|
|
|
+
|
|
|
+ driver.find_element_by_css_selector("ytd-comments ytd-comment-simplebox-renderer div#placeholder-area").click()
|
|
|
+ driver.implicitly_wait(5)
|
|
|
+ driver.find_element_by_xpath('//*[@id="contenteditable-root"]').send_keys(comment)
|
|
|
+ driver.find_element_by_xpath('//*[@id="contenteditable-root"]').send_keys(Keys.CONTROL, Keys.ENTER)
|
|
|
+
|
|
|
+ post = WebDriverWait(driver, 15).until(
|
|
|
+ EC.element_to_be_clickable((By.CSS_SELECTOR, 'ytd-comments ytd-comment-simplebox-renderer'))
|
|
|
+ )
|
|
|
+ post.click()
|
|
|
+
|
|
|
+ r = np.random.randint(2, 5)
|
|
|
+ time.sleep(r)
|
|
|
+ driver.quit()
|
|
|
+ return comment_page(driver, url, random_comment())
|
|
|
+
|
|
|
+
|
|
|
+def random_comment():
|
|
|
+ # You can edit these lines=======
|
|
|
+ # df = pd.read_excel('/Users/zooeytsai/Downloads/yt留言.xlsx')
|
|
|
+ # messages = df['文字']
|
|
|
+ r = redis.Redis(host='db.ptt.cx', port=6379, db=0, password='choozmo9')
|
|
|
+ js = r.get('yt_comment')
|
|
|
+ messages = json.loads(js)
|
|
|
+ # ===============================
|
|
|
+ r = np.random.randint(0, len(messages))
|
|
|
+ print(messages[r])
|
|
|
+ return messages[r]
|
|
|
+
|
|
|
+
|
|
|
+def check_exists_by_xpath(driver, xpath):
|
|
|
+ try:
|
|
|
+ driver.find_element_by_xpath(xpath)
|
|
|
+ except NoSuchElementException:
|
|
|
+ return False
|
|
|
+
|
|
|
+ return True
|
|
|
+
|
|
|
+
|
|
|
+class JParams(object):
|
|
|
+
|
|
|
+ def get(self, profile):
|
|
|
+ print(profile)
|
|
|
+ r = redis.Redis(host='db.ptt.cx', port=6379, db=0, password='choozmo9')
|
|
|
+ js = r.get('yt_video')
|
|
|
+ jsobj = json.loads(js)
|
|
|
+ videoId = random.choice(jsobj)
|
|
|
+ url = f"https://www.youtube.com/watch?v={videoId}"
|
|
|
+
|
|
|
+ driver = open_driver(profile)
|
|
|
+ comment_page(driver, url, random_comment())
|
|
|
+
|
|
|
+
|
|
|
+if __name__ == '__main__':
|
|
|
+ fire.Fire(JParams)
|