小編神器,從此不用發文發到死,selenium在FB上的實做

👉【行銷搬進大程式】給您更多實用文章與免費教學影片,附贈Python程式碼!

小編神器,從此不用發文發到死,selenium在FB上的實做

我曾經做過一陣子的小編,負責將粉絲團的文章廣發到各個社團,這個過程枯燥且乏味,就是一直不斷地按分享社團。我一天大約要分享70多個社團,因此每天得花一小時左右來做這項「機械式」的工作。

環境準備

這個過程大部分是與「小編神器,IG愛心大放送,selenium在IG上的實做」類似,因此若您已經讀過該篇文章,大多部分是可以沿用的。

Python環境

若您是Python的新手,建議可以下載Anaconda來搭建環境。以下兩個Anaconda的介紹:

Windwos&Mac Python初學者為什麼選擇Anaconda為開發環境呢? -入門系列

Python 入門必看!Windows 懶人搭建Anaconda Python 學習環境-入門系列

套件安裝

整個實作只需要用到Selenium套件,因此若是使用Anaconda,就直接在Anaconda prompt中輸入以下指令,若在系統環境中安裝python,則直接在Terminal貼上指令即可。

pip install selenium
打開Anaconda Prompt

下載phantomjs

phantomjs是Selenium的控制器,等於是將python程式碼變成機器人的工具。Selenium之所以能爬到許多爬蟲爬不到的網站,就是因為Selenium是模仿人的行為,真的打開一個瀏覽器,不像傳統的爬蟲,直接請求封包下來解析。當然這各有有缺點Selenium的執行效率相對就差很多,但面對IG這種「動態式」的網站,必須要用Selenium才能達的到。

不同系統,圖示可能會不太一樣,但不影響功能,讀者不必過度擔心。

點我下載phantomjs

下載chromedriver

chromedriver是專門給程式控制的瀏覽器。因此實作時,程式會幫您開啟一個chrome瀏覽器,並且按照程式自動按按鈕,當然也可以人工介入操作。chromedriver必須與您目前的chrome版本相同,若您不知道您chrome的版本,可以點這裡查看需下載的版本,確定後,即可點下方選擇下載檔案。

點我下載chromedriver

集合檔案

集合檔案

phantomjs與chromedriver下載完成後,都必須放到主程式的資料夾中(如上圖右),讓Python確保能抓到這兩個檔案。若系統為linux,可能會有使用chromedriver與phantomjs檔案權限問題,因此必須要輸入以下來打開權限(777為全開,若是覺得有安全疑慮者可以自行調整)。

linux系列的系統,必須要開起權限,windows的讀者可以忽略

發文專用的FB帳號

您可能會好奇,為何還要特別準備一個FB帳號?其實使用selenium發文是有一定風險的,若動作太過於機械式,會被FB禁止發文,少則三天,多則以星期計算,甚至到最後會不會停權都說不定。由此原因,還是建議個人使用的FB帳號不要拿來廣發,當然您現在讀本篇文章,並且進行短暫的實作練習,是不至於被FB禁止發文,但長時間使用,就會有帳號封鎖疑慮。

另一個原因是,公私盡量分明。因為在您的個人帳號中,都是你身邊的真實朋友,您所參加的社團,可能是您國小、國中、高中的班級社團,相信您知道在這些社團發送廣告文章,會造成甚麼反彈吧?

執行程式碼

完整程式碼

輸入帳密

請輸入您慾發文的帳號密碼。catch參數是輸入您待會想要分享的社團,而當然並不是打社團全名,而是用模糊搜尋的方式,因此如下範例中輸入「廣告|行銷」,因此待會若您加入的社團名稱中有「廣告」或是「行銷」,就會進行分享。

useEmail='您的FB帳號'
usePass='您的FB密碼'
catch ='廣告|行銷'
postURL = 'https://www.facebook.com/marketingliveincode/posts/pfbid02U3b4nmVMTsrH762aN715EoUiSscRFDoAkkLJ8gYoeTpUaNigm3cGKZW96qbZbddYl'

postURL參數非常好理解,就是您想要發文的該篇FB文章,而取得該篇FB文章的網址方式非常簡單,只需要點擊該文章的「時間」,即可取得該文章的網址。

取得FB文章網址

設定phantomjs

這個部分只需要注意,phantomjs與chromedriver這兩個檔案的擺放位置,確實是與程式碼在同一層目錄即可,並且工作目錄設定無誤。若以上皆無問題,那便可以直接順利執行過去,打開程式控制的瀏覽器。

# 設定基本參數
desired_capabilities = DesiredCapabilities.PHANTOMJS.copy()
#此處必須換成自己電腦的User-Agent
desired_capabilities['phantomjs.page.customHeaders.User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'# PhantomJS driver 路徑 似乎只能絕對路徑
driver = webdriver.PhantomJS(executable_path = 'phantomjs', desired_capabilities=desired_capabilities)# 關閉通知提醒
chrome_options = webdriver.ChromeOptions()
prefs = {'profile.default_content_setting_values.notifications' : 2}
chrome_options.add_experimental_option('prefs',prefs)
# 以下三個註解打開,瀏覽器就不會開啟
# chrome_options.add_argument(' — headless')
# chrome_options.add_argument(' — no-sandbox')
# chrome_options.add_argument(' — disable-dev-shm-usage')# 開啟瀏覽器
driver = webdriver.Chrome('chromedriver',chrome_options=chrome_options)
只有空白頁面

若您出現錯誤訊息:

WebDriverException: 'phantomjs' executable needs to be in PATH.
WebDriverException: ‘phantomjs’ executable needs to be in PATH.

代表電腦找不到您的phantomjs檔案,您必須重新確認檔案放置的位置是否正確。

若錯誤訊息是:

WebDriverException: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home
WebDriverException: ‘chromedriver’ executable needs to be in PATH. Please see …

則是找不到chromedriver檔案,一樣必須重新確認檔案放置的位置是否正確。

最後若錯誤訊息為:

SessionNotCreatedException: session not created: This version of ChromeDriver only supports Chrome version 76
SessionNotCreatedException: session not created: This version of ChromeDriver only supports Chrome version XX

則是代表您所下載的chromedriver與您的瀏覽器版本並不符合,請重新查看您的電腦版本,並且找到對應的下載檔案。

登入FB

由於正逢FB的改版時期,因此有些人的FB是舊版,有些則是新版,因此我將兩種版本介面的登入方式都寫上去。

####### 開始操作 輸入帳號密碼登入 到fb首頁 #######
driver.get('http://www.facebook.com')
time.sleep(1)
assert 'Facebook' in driver.title
try:
elem = driver.find_element_by_id('email')
elem.send_keys(useEmail)
elem = driver.find_element_by_id('pass')
elem.send_keys(usePass)
elem.send_keys(Keys.RETURN)
except:
driver.find_element_by_xpath('//*[@name="email"]')
elem.send_keys(useEmail)
elem = driver.find_element_by_xpath('//*[@name="pass"]')
elem.send_keys(usePass)
elem.send_keys(Keys.RETURN)
time.sleep(5)

若登入這裡有些不可抗拒因素,倒置無法自動化登入,也可以用手動打字的方式登入。本文張想要節省的時間,是後面重複發文的時間,因此前面的登入並無太大影響,除非要將這個機器人服務化。

其實也是可以直接用輸入的

取得您的個人ID

這個動作是為了等一會要轉跳您的所有社團頁面,進行抓取動作。這個ID其實就是您FB首頁網址中,最後面的那串數字,因此若您想要省略這兩行的步驟,也可以直接寫死這項參數yourID。

#取得帳號絕對ID
try:#舊版
getID = driver.find_element_by_xpath('//*[@title="個人檔案"]').get_attribute('href')
version='old'
except:#新版
getID = driver.find_element_by_xpath('//div[@data-pagelet="LeftRail"]/div/ul/li/div/a').get_attribute('href')
version='new'
yourID = getID[getID.find('id=')+3:]
取得個人FB的ID

這裡若您的帳號有修改過ID,將這些數字ID改成英文,那就不適用本文章的程式碼。

準備想發送的社團(程式72~95行)

當取得您的ID後,就會切換頁面到您所有的社團頁面,目的是為了抓取所有社團的名稱。

# 切換到自己的社團
driver.get('https://www.facebook.com/profile.php?id=' + yourID + '&sk=groups')

由於FB是動態式網頁,因此必須將頁面滾到底部後,才會產生新的資料、文章,因此這裡利用JavaScript的語法window.scrollTo,來自動滾動頁面,直到滾到底部為止。

# 滾動頁面
for i in range(30):
    driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")
    time.sleep(1)

首先先抓取所有社團。這裡一樣是因為新舊版的區別,而有不同的爬取方式。

# 取得所有社團
if len(driver.find_elements_by_xpath('//*[@data-hovercard]')) == 0:        #新版
    getallgroup = driver.find_elements_by_xpath('//a/span[@dir="auto"]')
else:
    #舊版
    getallgroup = driver.find_elements_by_xpath('//*[@data-hovercard]')

還記得我們先前有設定catch參數,若該社團名稱中,有出現catch所設定的關鍵字,就列入待會要發送的名單。這項功能一方面能避免您發送到一些私人、不想打廣告的社團,另一方面,則是可以依照不同的文章,進行不同種類的社團進行發送,譬如:金融類的文章,就設定股票、期貨相關的關鍵字社團發送。

get_groups = []
#檢查,若無要求就社團全部發
if len(catch) == 0:
    for groups in getallgroup:
        get_groups.append(groups.text)
else:
    for groups in getallgroup:
        if len("".join(re.findall(catch, groups.text))) >0:
            get_groups.append(groups.text)
程式開始發送文章到社團

這裡有一個小心得。不要小看發送到一些莫名其妙的廣告社團,這其實對一個粉絲團的成長,意外的有很大的作用。

發送到社團(程式104~145行)

這裡就是模仿人的步驟,點選分享、發送社團等。為了讓整個動作看起來「像人」,在每個動作都加上了time.sleep的延遲,並且是使用亂數的方式。

####### 開始分享 ####### 
# 切換到文章
driver.get(postURL)
if version == 'new':
    #新版
    for send in get_groups:
    # 按下分享
        driver.find_element_by_xpath('//*[@aria-label="寄送這個給朋友或張貼在你的動態時報中。"]').click()
        time.sleep(random.randint(3,5))
        # 按下分享到社團
        driver.find_element_by_xpath("//*[contains(text(), '分享到社團')]").click()
        time.sleep(random.randint(2,7))
        for send in get_groups:
            # 輸入社團名稱
            driver.find_element_by_xpath('//*[@aria-label="搜尋社團"]').send_keys(send)
            time.sleep(random.randint(2,7))
            driver.find_elements_by_xpath('//div[@aria-labelledby]')[-1].click()
 
            length = len(driver.find_element_by_xpath('//*[@aria-label="搜尋社團"]').get_attribute('value')) #抓到欲刪除的欄位數量
            driver.find_element_by_xpath('//*[@aria-label="搜尋社團"]').send_keys(length * Keys.BACKSPACE) #案幾次刪除
            time.sleep(random.randint(60,120))
else:
     #舊版
     for send in get_groups:
     # 按下分享
         driver.find_element_by_xpath('//*[@title="寄送這個給朋友或張貼在你的動態時報中。"]').click()
         time.sleep(random.randint(3,5))
         # 按下分享到社團
         driver.find_element_by_xpath('//*[contains(text(), "分享到社團")]').click()
         time.sleep(random.randint(2,7))
         # 輸入社團名稱
         driver.find_element_by_xpath('//input[@placeholder="社團名稱"]').send_keys(send)
         time.sleep(random.randint(2,7))
         # 按下向下建選擇第一個最相似的社團
         driver.find_element_by_xpath('//input[@placeholder="社團名稱"]').send_keys('\ue015')
         # 按下enter迴車建
         driver.find_element_by_xpath('//input[@placeholder="社團名稱"]').send_keys('\ue007')
         # 包含原始貼文打勾
         driver.find_element_by_class_name('_55sg').click()
         time.sleep(random.randint(7,15))
         # 發布
         driver.find_elements_by_xpath("//button[contains(text(), '發佈')]")[-1].click()
         time.sleep(random.randint(60,120))
driver.quit()

注意!
本文純屬學習性質,因此請您正當使用。

成果驗收

[图片上传失败...(image-63ba36-1661743969441)]

下載完整程式碼-請點我


👉想看更多Python實作教學影片【免費】👈

📌Python基礎課程

📌Line Bot 聊天機器人

📌行銷人轉職爬蟲王實戰|5大社群+2大電商

📌Telegram Bot 聊天機器人

📌實用工具

▶ 點此:https://marketingliveincode.com/

查看更多Python工具技巧、商業分析、教學影片

滿意我們餐點嗎?給點 Claps 吧👏👏

1. 我學習到了新的概念與工具 1–10+

2. 我理解了這篇內容所講述的工具與技巧 20–30+

3. 我可以將這篇的內容運用到學習和工作上20–30+

作者:楊超霆(行銷搬進大程式 創辦人)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容