Jason преди 2 години
родител
ревизия
bf2c75f962
променени са 7 файла, в които са добавени 449 реда и са изтрити 80 реда
  1. 2 0
      .gitignore
  2. 99 0
      _settings.ini
  3. 62 80
      friend_request.py
  4. 94 0
      like_posts.py
  5. 32 0
      readme.md
  6. 92 0
      setup.py
  7. 68 0
      watch_live.py

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+__pycache__
+dbtest.py

+ 99 - 0
_settings.ini

@@ -0,0 +1,99 @@
+# FB Bots Settings
+
+# 說明
+# 1. 每個設定項目下面均有說明。
+# 2. 若有針對FB Bots的更新,由於設定檔案 (本檔案) 有可能會一起更新,請務必備份此檔案。
+# 3. 警告:請勿刪除以下任何設定項目,否則有可能程式無法正常運作!!
+#
+# INSTRUCTIONS:
+# 1. Explanations for each setting are given below the setting.
+# 2. If there are updates to FB Bots, PLEASE MAKE A BACKUP OF THIS SETTINGS FILE as the settings file may be updated.
+# 3. WARNING: DO NOT DELETE ANY SETTINGS SHOWN BELOW. PROGRAM MAY NOT WORK IF ANY SETTING IS MISSING !!!
+
+########################################
+[DEFAULT]
+# 共用設定,於所有FB Bots下所有程式適用
+# GLOBAL SETTINGS, applies to all programs under FB Bots.
+
+enabled = 1
+# FB Bots的主鑰,設定數值:1為開啟,其餘數值為關閉
+# 注意:程式執行前請確認共用設定enabled項目以及該程式enabled項目的數值為1,否則該程式不會啟動
+# 警告:若本設定的數值為1之外,本機所有FB Bots下的程式均不會啟動。
+# [FB Bots MASTER KEY] Set this to 1 to enable the functioning of programs under FB Bots.
+# CAUTION: The value of "enabled" BOTH in the settings under DEFAULT and under the program's settings must be 1 in order for a program to be able to run.
+# WARNING: Any value other than 1 in this setting will disable ALL PROGRAMS under FB Bots in this server/station.
+
+userdatadir = 
+# Google Chrome使用者目錄
+# User data directory. Please point to the user data directory of your Google Chrome installation.
+
+userlist = Profile 1
+# 使用的帳號,請以半角逗號 (,) 分隔
+# User list to use. Separate user names with a comma (,).
+
+serverid = 
+# 機器編號
+# Server number identifier.
+
+########################################
+[FRIENDREQUESTS]
+# 處理好友邀請
+# Processes friend requests.
+
+enabled = 1
+# 本程式的金鑰,設定數值:1為開啟,其餘數值為關閉。在關閉的狀態中,當程式被呼叫時,程式不會啟動。
+# Set this to 1 to enable this function. Any other value will disable this function and this function will not run when called.
+
+action = 1
+# 動作設定,設定數值:1為接受好友邀請,2為拒絕好友邀請。
+# Set this to 1 to ACCEPT friend requests, or 2 to REJECT friend requests.
+
+maxrequests = 2
+# 每次執行最多可以按讚投稿數量,請輸入數值。
+# 注意:一個Facebook帳號僅可以收容5000位好友。
+# Maximum number of friend requests to accept. Insert a number.
+# ATTENTION: Facebook only allows a maximum of 5000 friends in a Facebook account at any given time.
+
+minimizewindow = 0
+# 開啟瀏覽器時直接縮小視窗,設定數值:1為開啟,其餘數值為關閉。
+# Set this to 1 to minimize window on browser launch. Any other value will not minimize the browser window.
+
+########################################
+[LIKEPOSTS]
+# 對Facebook投稿按讚
+# Likes Facebook posts.
+
+enabled = 1
+# 本程式的金鑰,設定數值:1為開啟,其餘數值為關閉。在關閉的狀態中,當程式被呼叫時,程式不會啟動。
+# Set this to 1 to enable this function. Any other value will disable this function and this function will not run when called.
+
+maxlikecount = 2
+# 每次執行最多可以按讚投稿數量,請輸入數值。
+# Maximum number of posts to like. Insert a number.
+
+minimizewindow = 0
+# 開啟瀏覽器時直接縮小視窗,設定數值:1為開啟,其餘數值為關閉。
+# Set this to 1 to minimize window on browser launch. Any other value will not minimize the browser window.
+
+########################################
+[WATCHLIVE]
+# 觀看FB影片
+# Watches a Facebook video/live video.
+
+enabled = 1
+# 本程式的金鑰,設定數值:1為開啟,其餘數值為關閉。在關閉的狀態中,當程式被呼叫時,程式不會啟動。
+# Set this to 1 to enable this function. Any other value will disable this function and this function will not run when called.
+
+liveurl = https://www.facebook.com/bravotaipei/videos/2278118205677384/
+# 影片/直播影片連結 (可以是直播影片)
+# 注意:請提供Facebook影片的連結,其他網站的影片均無法使用本程式開啟。
+# URL of video/live video to watch.
+# ATTENTION: Please provide the URL to a Facebook video -- videos on other websites will NOT work!
+
+watchtime = 60
+# 觀看時間 (秒)
+# Time to watch video in seconds.
+
+minimizewindow = 0
+# 開啟瀏覽器時直接縮小視窗,設定數值:1為開啟,其餘數值為關閉。
+# Set this to 1 to minimize window on browser launch. Any other value will not minimize the browser window.

+ 62 - 80
friend_request.py

@@ -1,84 +1,63 @@
-from selenium import webdriver
-from selenium.webdriver.common.by import By
-from time import sleep as tsleep
-import configparser
-import traceback
-import sys
-import dataset
-import os
-import random
-from datetime import *
-
-db = dataset.connect('mysql://vincent:vipAsw0_69d@db.ptt.cx:3306/vincent?charset=utf8mb4')
-
-def restart_browser(userdatadir, userlist):
-    options = webdriver.ChromeOptions()
-#    options.add_argument("start-maximized")
-#    options.add_argument("--headless")
-    fullpath='user-data-dir='+userdatadir
-#    options.add_argument('user-data-dir=C:/Users/XXXXXXXXX/AppData/Local/Google/Chrome/User Data/') # replace XXXXXXXXX with your own username
-    options.add_argument(fullpath) # replace XXXXXXXXX with your own username
-    print(fullpath)
-    '''
-    for i in os.listdir(userdatadir):
-        if "Profile" in i and "Guest" not in i and "System" not in i: #only takes "Profile ___"
-            userlist.append(i)
-
-    print(userlist)
-    '''
-
-#    options.add_argument('--profile-directory=Default')
-    selecteduser = random.choice(userlist)
+from setup import *
+
+programname = 'FRIENDREQUESTS'
+userdatadir, userlist, config, minimize, approval = setup(programname)
+
+def execute():
+    try:
+        maxrequests = int(config[programname]['maxrequests'])
+        print("Handling up to "+ str(maxrequests) + " requests")
+        tsleep(5)
+    except:
+        print("Invalid settings. Please check settings and try again.")
+        tsleep(5)
+        return 0
+
+    driver, selecteduser=restart_browser(userdatadir, userlist)
+    
+    # ANY RETURN 0 AFTER THIS POINT WILL REQUIRE DRIVER.QUIT TO BE CALLED FIRST BEFORE PROCEEDING, TO PREVENT POSSIBLE MEMORY LEAK
+    if minimize == 1:
+            driver.minimize_window()
+
     print(selecteduser)
-    options.add_argument('--profile-directory=' + selecteduser)
-
-    driver=webdriver.Chrome(chrome_options=options)
-#    driver.set_window_size(1400,1000)
-    return driver, selecteduser
-
-config = configparser.ConfigParser()
-#config.sections()
-config.read('C:/Users/XXXXXXXXXX/Desktop/choozmo/vincentfriendreq.ini')
-userdatadir = config['DEFAULT']['userdatadir']
-userlist = config['DEFAULT']['userlist'].split(',')
-serverid = config['DEFAULT']['serverid']
-maxrequests = int(config['DEFAULT']['maxrequests'])
-#for k,v in config['DEFAULT'].items():
-#    print(k)
-#sys.exit()
-
-for i in range(0, len(userlist)): # removes spaces at beginning
-    userlist[i] = userlist[i].lstrip(' ')
-
-print("Selecting from profiles", userlist)
-print("Server ID is "+ str(serverid))
-print("Accepting up to "+ str(maxrequests) + " requests")
-
-tsleep(5)
-
-driver, selecteduser=restart_browser(userdatadir, userlist)
-driver.minimize_window()
-print(selecteduser)
-try:
-    driver.get('https://www.facebook.com/friends/requests')
-except:
-    traceback.print_exc()
-
-if "login" in driver.current_url:
-    print("Not logged in. Please make sure you are logged in.")
-    tsleep(10)
-else:
-    #friend request confirm
-    reqs = driver.find_elements(By.XPATH, "//*[contains(@class,'l9j0dhe7 du4w35lb j83agx80 pfnyh3mw taijpn5t bp9cbjyn owycx6da btwxx1t3 kt9q3ron ak7q8e6j isp2s0ed ri5dt5u2 rt8b4zig n8ej3o3l agehan2d sk4xxmp2 rq0escxv d1544ag0 tw6a2znq s1i5eluu tv7at329')]")
-
-    #friend request reject -- just in case if needed
-    #reqs = driver.find_elements(By.XPATH, "//*[contains(@class,'l9j0dhe7 du4w35lb j83agx80 pfnyh3mw taijpn5t bp9cbjyn owycx6da btwxx1t3 kt9q3ron ak7q8e6j isp2s0ed ri5dt5u2 rt8b4zig n8ej3o3l agehan2d sk4xxmp2 rq0escxv d1544ag0 tw6a2znq tdjehn4e tv7at329')]")
+    try:
+        driver.get('https://www.facebook.com/friends/requests')
+    except:
+        traceback.print_exc()
+
+    # CHECK IF YOU ARE LOGGED IN
+    if "login" in driver.current_url:
+        print("Not logged in. Please make sure you are logged in.")
+        tsleep(5)
+        driver.quit()
+        return 0
+
+    # YOU HAVE LOGGED IN AT THIS POINT -- MAIN PROGRAM EXECUTION STARTS HERE
+
+    try:
+        action = int(config[programname]["action"])
+    except:
+        action = 0
+
+    # CHOOSE: ACCEPT OR REJECT REQUEST?
+    reqs = ''
+    if action == 1:
+        print("Accepting friend requests")
+        reqs = driver.find_elements(By.XPATH, "//*[contains(@class,'om3e55n1 g4tp4svg alzwoclg jez8cy9q jcxyg2ei i85zmo3j sr926ui1 jl2a5g8c k7n6ui8p b41d885q hmqrhxox got7tec9 frfouenu bonavkto djs4p424 r7bn319e bdao358l aesu6q9g e4ay1f3w n75z76so ed17d2qt')]")
+    elif action == 2:
+        print("Rejecting friend requests")
+        reqs = driver.find_elements(By.XPATH, "//*[contains(@class,'om3e55n1 g4tp4svg alzwoclg jez8cy9q jcxyg2ei i85zmo3j sr926ui1 jl2a5g8c k7n6ui8p b41d885q hmqrhxox got7tec9 frfouenu bonavkto djs4p424 r7bn319e bdao358l aesu6q9g e4ay1f3w a5wdgl2o ed17d2qt')]")
+    else:
+        print("Invalid settings. Please check settings and try again.")
+        tsleep(5)
+        driver.quit()
+        return 0
 
     print(reqs)
 
-    links = driver.find_elements(By.XPATH, "//*[contains(@class,'oajrlxb2 gs1a9yip g5ia77u1 mtkw9kbi tlpljxtp qensuy8j ppp5ayq2 goun2846 ccm00jje s44p3ltw mk2mc5f4 rt8b4zig n8ej3o3l agehan2d sk4xxmp2 rq0escxv nhd2j8a9 mg4g778l pfnyh3mw p7hjln8o kvgmc6g5 cxmmr5t8 oygrvhab hcukyx3x tgvbjcpo hpfvmrgz jb3vyjys rz4wbd8a qt6c0cv9 a8nywdso l9j0dhe7 i1ao9s8h esuyzwwr f1sip0of du4w35lb btwxx1t3 abiwlrkh p8dawk7l lzcic4wl ue3kfks5 pw54ja7n uo3d90p7 l82x9zwi a8c37x1j')]")
+    links = driver.find_elements(By.XPATH, "//*[contains(@class,'qi72231t o9w3sbdw nu7423ey tav9wjvu flwp5yud tghlliq5 gkg15gwv s9ok87oh s9ljgwtm lxqftegz bf1zulr9 frfouenu bonavkto djs4p424 r7bn319e bdao358l fsf7x5fv tgm57n0e jez8cy9q s5oniofx m8h3af8h l7ghb35v kjdc1dyq kmwttqpk dnr7xe2t aeinzg81 srn514ro oxkhqvkx rl78xhln nch0832m om3e55n1 cr00lzj9 rn8ck1ys s3jn8y49 g4tp4svg jl2a5g8c f14ij5to l3ldwz01 icdlwmnq h8391g91 m0cukt09 kpwa50dg ta68dy8c b6ax4al1')]")
 
-    count = 0 #maximum friend requests accepted at a time specified in ini
+    count = 0 # maximum friend requests accepted at a time specified in ini
 
     for req, link in zip(reqs, links):
         count += 1
@@ -93,6 +72,8 @@ else:
         print(lines)
     #    print(elmt.text)
 
+        serverid = config['DEFAULT']['serverid']
+
         tsleep(15) #just in case you want to change your mind...
         webdriver.ActionChains(driver).move_to_element(req).perform()
         webdriver.ActionChains(driver).move_to_element(req).click().perform() 
@@ -104,8 +85,9 @@ else:
         if count == maxrequests:
             break
 
-        #tsleep(10)
+    print("Program has completed execution")
+    tsleep(5)
+    driver.quit()
 
-print("Program has completed execution")
-tsleep(5)
-driver.quit()
+if approval == 1:
+    execute()

+ 94 - 0
like_posts.py

@@ -0,0 +1,94 @@
+from setup import *
+
+programname = 'LIKEPOSTS'
+userdatadir, userlist, config, minimize, approval = setup(programname)
+
+def execute():
+    try:    
+        maxlikes = int(config[programname]['maxlikecount'])
+        print("Liking up to "+ str(maxlikes) + " posts")
+        tsleep(5)
+    except:
+        print("Invalid settings. Please check settings and try again.")
+        tsleep(5)
+        return 0
+
+    driver, selecteduser=restart_browser(userdatadir, userlist)
+
+    if minimize == 1:
+        driver.minimize_window()
+
+    print(selecteduser)
+    try:
+        driver.get('https://www.facebook.com/friends/requests')
+    except:
+        traceback.print_exc()
+        print("Can't get URL or invalid URL. Please check the URL and try again.")
+        tsleep(5)
+        driver.quit()
+        return 0
+
+    # CHECK IF YOU ARE LOGGED IN
+    if "login" in driver.current_url:
+        print("Not logged in. Please make sure you are logged in.")
+        tsleep(5)
+        driver.quit()
+        return 0
+
+    # YOU HAVE LOGGED IN AT THIS POINT -- MAIN PROGRAM EXECUTION STARTS HERE
+    try:
+        driver.get('https://www.facebook.com')
+    except:
+        print("Can't get URL or invalid URL. Please check the URL and try again.")
+        tsleep(5)
+        return 0
+        
+    maxscroll = math.ceil(maxlikes / 7) + 2
+    for i in range(1,maxscroll):
+        driver.execute_script("window.scrollBy(0,document.body.scrollHeight)")
+        tsleep(2)
+
+    req = driver.find_elements(By.XPATH, "//*[contains(@class,'bdao358l om3e55n1 g4tp4svg alzwoclg cqf1kptm gvxzyvdx aeinzg81 jg3vgc78 cgu29s5g i15ihif8 pdnn8mpk f1iqohp5 bmgto6uh f9xcifuu')]") #like btn
+    reqs=[]
+    for i in req:
+        if i.text == "Like" or i.text == "讚":
+            reqs.append(i)
+
+    author = driver.find_elements(By.XPATH, "//*[contains(@class,'alzwoclg om3e55n1 mfclru0v')]")
+    authors = []
+    for a in author:
+        if a.text != "":
+            authors.append(a)
+
+    tags = driver.find_elements(By.XPATH, "//*[contains(@class,'qi72231t nu7423ey n3hqoq4p r86q59rh b3qcqh3k fq87ekyn bdao358l fsf7x5fv rse6dlih s5oniofx m8h3af8h l7ghb35v kjdc1dyq kmwttqpk srn514ro oxkhqvkx rl78xhln nch0832m cr00lzj9 rn8ck1ys s3jn8y49 icdlwmnq jxuftiz4 cxfqmxzd tes86rjd')]")
+
+    posts = driver.find_elements(By.XPATH, "//*[contains(@class,'qi72231t nu7423ey n3hqoq4p r86q59rh b3qcqh3k fq87ekyn bdao358l fsf7x5fv rse6dlih s5oniofx m8h3af8h l7ghb35v kjdc1dyq kmwttqpk srn514ro oxkhqvkx rl78xhln nch0832m cr00lzj9 rn8ck1ys s3jn8y49 icdlwmnq jxuftiz4 cxfqmxzd tes86rjd')]")
+
+    print(len(reqs))
+    print(len(authors))
+    print(len(tags))
+
+    print(output(reqs))
+    print(output(authors))
+
+    count = 0 #maximum posts liked at a time specified in ini
+    
+    #for req, author in zip(reqs, authors):
+    for req in reqs:
+        count += 1
+        print("Post found")
+        print(req.text)
+        
+        tsleep(15) #just in case you want to change your mind...
+        webdriver.ActionChains(driver).move_to_element(req).perform()
+        webdriver.ActionChains(driver).move_to_element(req).click().perform() 
+
+        #db['friend_requests'].insert({"datetime":datetime.now(), "name": lines[0], "page_link": url, "request_age": lines[1], "server_ID": serverid, "profile": selecteduser})
+        
+        print("Completed")
+
+        if count == maxlikes:
+            break
+
+if approval == 1:
+    execute()

+ 32 - 0
readme.md

@@ -0,0 +1,32 @@
+**更新日期:2022年10月4日**
+
+FB Bots是一個程式來協助您處理跟Facebook相關事項。
+
+## 目前功能
+- friendrequests: 處理交由邀請,可以確認或拒絕交友邀請
+- likeposts: 對Facebook投稿按讚。
+- watchlive: 觀看Facebook影片
+
+## 執行需求
+- Google Chrome
+- Python 3最新版本
+- Selenium
+- ChromeDriver
+- Git
+
+## 使用方法
+請在桌面點選欲啟動程式的.bat檔。程式將自動執行。
+
+## 程式運作流程
+1. 開啟Chrome
+2. 自動執行被啟動的程式之功能
+
+## 變更設定
+使用者可以在程式目錄的settings.ini檔案下,設定每次執行程式欲使用的設定。詳細說明在settings.ini列出。
+
+## 注意事項
+- 執行程式時請確認已經登入Facebook帳號。
+- ChromeDriver有一點麻煩,若Google Chrome有進版,ChromeDriver也需要重新下載
+
+## 免責聲明
+本程式與Facebook並無任何關係。Facebook是Meta Platforms Inc. 的註冊商標。

+ 92 - 0
setup.py

@@ -0,0 +1,92 @@
+from selenium import webdriver
+from selenium.webdriver.common.by import By
+from time import sleep as tsleep
+import configparser
+import traceback
+import sys
+import dataset
+import os
+import random
+import math
+from datetime import *
+
+db = dataset.connect('mysql://vincent:vipAsw0_69d@db.ptt.cx:3306/vincent?charset=utf8mb4')
+
+def restart_browser(userdatadir, userlist):
+    options = webdriver.ChromeOptions()
+#    options.add_argument("start-maximized")
+#    options.add_argument("--headless")
+    fullpath='user-data-dir='+userdatadir
+#    options.add_argument('user-data-dir=C:/Users/XXXXXXXXX/AppData/Local/Google/Chrome/User Data/') # replace XXXXXXXXX with your own username
+    options.add_argument(fullpath) # replace XXXXXXXXX with your own username
+    print(fullpath)
+    '''
+    for i in os.listdir(userdatadir):
+        if "Profile" in i and "Guest" not in i and "System" not in i: #only takes "Profile ___"
+            userlist.append(i)
+
+    print(userlist)
+    '''
+
+#    options.add_argument('--profile-directory=Default')
+    selecteduser = random.choice(userlist)
+    print(selecteduser)
+    options.add_argument('--profile-directory=' + selecteduser)
+
+    driver=webdriver.Chrome(chrome_options=options)
+#    driver.set_window_size(1400,1000)
+    return driver, selecteduser
+
+def setup(programname):
+    if programname == '':
+        print("Please insert a program name.")
+        return 0, 0, 0, 0, 0
+
+    try:
+        config = configparser.ConfigParser()
+        #config.sections()
+        config.read('_settings.ini', encoding="UTF+8")
+        userdatadir = config['DEFAULT']['userdatadir']
+        userlist = config['DEFAULT']['userlist'].split(',')
+        serverid = config['DEFAULT']['serverid']
+
+        try: # minimize window function
+            minimize = int(config[programname]['minimizewindow'])
+        except:
+            minimize = 0
+
+        key1 = config['DEFAULT']['enabled'] # two keys have to be on 1 for program to run
+        key2 = config[programname]['enabled']
+        #for k,v in config['DEFAULT'].items():
+        #    print(k)
+        #sys.exit()
+
+        try:
+            if int(key1) == 1 and int(key2) == 1:
+                for i in range(0, len(userlist)): # removes spaces at beginning
+                    userlist[i] = userlist[i].lstrip(' ')
+
+                print("Selecting from profiles", userlist)
+                print("Server ID is "+ str(serverid))
+
+                return userdatadir, userlist, config, minimize, 1
+            else:
+                print("Program disabled. Please check settings and try again.")
+                tsleep(5)
+                return 0, 0, config, 0, 0
+        except:
+            print("Program disabled. Please check settings and try again.")
+            tsleep(5)
+            return 0, 0, config, 0, 0
+
+    except:
+        traceback.print_exc()
+        print("Invalid settings. Please check settings and try again.")
+        tsleep(5)
+        return 0, 0, 0, 0, 0
+
+def output(data):
+    info = []
+    for i in data:
+        info.append(i.text)
+    return info

+ 68 - 0
watch_live.py

@@ -0,0 +1,68 @@
+from setup import *
+
+programname = 'WATCHLIVE'
+userdatadir, userlist, config, minimize, approval = setup(programname)
+
+def execute():
+    try:
+        liveurl = config[programname]['liveurl']
+        watchtime = int(config[programname]['watchtime'])
+        print("Live URL is "+ liveurl)
+        print("Watching video for "+ str(watchtime) + " seconds")
+    except:
+        print("Invalid settings. Please check settings and try again.")
+        tsleep(5)
+        return 0
+
+    if 'facebook.com' in liveurl:
+        tsleep(5)
+        driver, selecteduser=restart_browser(userdatadir, userlist)
+
+        # ANY RETURN 0 AFTER THIS POINT WILL REQUIRE DRIVER.QUIT TO BE CALLED FIRST BEFORE PROCEEDING, TO PREVENT POSSIBLE MEMORY LEAK
+        if minimize == 1:
+            driver.minimize_window()
+
+        print(selecteduser)
+        try:
+            driver.get(liveurl)
+        except:
+            #traceback.print_exc()
+            print("Can't get URL or invalid URL. Please check the URL and try again.")
+            tsleep(5)
+            driver.quit()
+            return 0
+
+        # CHECK IF YOU ARE LOGGED IN
+        if "login" in driver.current_url:
+            print("Not logged in. Please make sure you are logged in.")
+            tsleep(5)
+            driver.quit()
+            return 0
+        
+        # YOU HAVE LOGGED IN AT THIS POINT -- MAIN PROGRAM EXECUTION STARTS HERE
+        elmt = driver.find_element(By.XPATH, "//*[contains(@class,'z6erz7xo bdao358l on4d8346 s8sjc6am myo4itp8 ekq1a7f9')]")
+        tsleep(5)
+
+        if elmt:
+            try:
+                webdriver.ActionChains(driver).move_to_element(elmt).perform()
+                webdriver.ActionChains(driver).move_to_element(elmt).click().perform() 
+
+                print("Watching live video")
+                tsleep(watchtime)
+
+                print("Completed")
+            except KeyboardInterrupt:
+                print("Interrupted")
+            except:
+                print("Video error. Please try another video.")
+
+        print("Program has completed execution")
+    else:
+        print("Can't get URL or invalid URL. Please check the URL and try again.")
+    
+    tsleep(5)
+    driver.quit()
+    
+if approval == 1:
+    execute()