Comment Spam YouTube

Stato
Discussione chiusa ad ulteriori risposte.

Notte

Utente Electrum
11 Luglio 2012
363
13
93
141
Semplice script in python che permette di commentare in tempo reale l'ultimo video uscito(negli ultimi 5 minuti) per ogni canale di una lista passata. E' scritto in python3(ci vuole poco ad adattarlo per il 2.7) e si può utilizzare su qualsiasi OS. Ottimo se si vuole sponsorizzare il proprio canale con utenti veri.

Dipendenze:
1)Selenium
2)PhantomJS

Funzionamento:
1)Inserire una lista di canali nel file channels.txt
2)Inserire una lista di commenti nel file comments.txt separati da: [BREAK]
3)Creare un file videos.log(dove vengono salvati i video già commentati)
4)Avviare il bot da linea di comando con nome utente, password e percorso PhantomJS(obbligatorio su Windows e facoltativo su altri sistemi)

Python:
#!/usr/bin/python3
# -*- coding: utf-8 -*-

# Prerequisites
# 1]https://pypi.python.org/pypi/selenium
# 2]http://phantomjs.org/download.html

#browser.save_screenshot('screen.png')

import os
import time
import random
import argparse
from urllib.parse import urlparse
try:
    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.common.exceptions import NoSuchElementException
except ImportError:
    print('Install selenium!')

def read_log():
    try:
        f = open('videos.log', 'r', encoding="utf-8")
        urls = f.read().split('@')
        f.close()
        return urls
    except IOError:
        print('File videos.log not exists!')
        quit()

def write_log(video_id):
    try:
        f = open('videos.log', 'a', encoding="utf-8")
        f.write(video_id + '@')
        f.close()
    except IOError:
        print('File videos.log not exists!')
        quit()

def get_comments():
    try:
        f = open('comments.txt', 'r', encoding="utf-8")
        comments = f.read()
        f.close()
        return comments.split('[BREAK]')
    except IOError:
        print('File comments.txt not exists!')
        quit()

def get_urls():
    try:
        f = open('channels.txt', 'r', encoding="utf-8")
        urls = f.read().splitlines()
        f.close()
        return urls
    except IOError:
        print('File channels.txt not exists!')
        quit()

def last_video(browser, url):
    try:
        browser.get(url + '/videos?sort=dd&view=0&flow=list')
        last_time = browser.find_element_by_css_selector('.yt-lockup-meta-info > li:nth-child(1)').text
        if 'second' in last_time or ('minut' in last_time and int(last_time.split(' ')[0]) <= 5):
            video_id = browser.find_element_by_class_name('yt-lockup-video').get_attribute('data-context-item-id')
            return video_id
        else:
            return None
    except Exception:
        return None

def check_exists_by_id(browser, id):
    try:
        browser.find_element_by_id(id)
    except NoSuchElementException:
        return False
    return True

def post_comment(browser, email, password, video_id, comment):
    try:
        browser.get('https://accounts.google.com/ServiceLogin?continue=http%3A%2F%2Fwww.youtube.com%2Fsignin%3Fnext%3D%252Fwatch%253Fv%253D' + video_id + '%26app%3DNone%26action_handle_signin%3Dtrue%26hl%3Dit&passive=true&service=youtube&uilel=3&hl=it#identifier')
       
        parsed = urlparse(browser.current_url)
        if parsed.hostname == 'accounts.google.com':
            browser.find_element_by_id('Email').send_keys(email)
            browser.find_element_by_id('next').click()
            WebDriverWait(browser, 10).until(EC.visibility_of_element_located((By.ID, "Passwd")))
            browser.find_element_by_id('Passwd').send_keys(password)
            browser.find_element_by_id('signIn').click()
            return post_comment(browser, email, password, video_id, comment)
        else:
            if not check_exists_by_id(browser, 'movie_player'):
                return None
           
            if check_exists_by_id(browser, 'comments-disabled-message'):
                return None
           
            browser.set_window_size(1280, 930)
            WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, 'comment-simplebox-renderer')))
            browser.find_element_by_class_name('comment-simplebox-renderer-collapsed-content').click()
            WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, 'comment-simplebox-text')))
            browser.find_element_by_class_name('comment-simplebox-text').send_keys(comment)
            WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, "comment-simplebox-submit")))
            browser.find_element_by_class_name('comment-simplebox-submit').click()
            WebDriverWait(browser, 10).until(EC.invisibility_of_element_located((By.CLASS_NAME, 'comment-simplebox-loading')))
            return True
        return None
    except Exception:
        return None

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('email', help='Google username/email')
    parser.add_argument('password', help='Google password')
    if os.name == 'nt':
        parser.add_argument('browser', help='Browser driver path')
    else:
        parser.add_argument('-b', '--browser', help='Browser driver path')
    args = parser.parse_args()
    email = args.email
    password = args.password
    browser = args.browser
   
    if browser != None:
        browser = webdriver.PhantomJS(browser)
        #browser = webdriver.Firefox('PATH')
    else:
        browser = webdriver.PhantomJS()
        #browser = webdriver.Firefox()

    browser.implicitly_wait(1)

    print('########################')
    print('# COMMENT BOT by Notte #')
    print('########################')
    print('Loading urls')
    urls = get_urls()
    print('Loading comments')
    comments = get_comments()
    print('Loading videos')
    videos = read_log()

    print('Scanning urls...')
    while True:
        for url in urls:
            video_id = last_video(browser, url)
            if video_id != None:
                if not video_id in videos:
                    comment = random.choice(comments)
                    result = post_comment(browser, email, password, video_id, comment)
                    print('Video found: ' + video_id)
                    if result != None:
                        videos.append(video_id)
                        write_log(video_id)
                        print('Video commented: ' + video_id)
            time.sleep(1)
        time.sleep(3)
 
  • Mi piace
Reazioni: Viip
Il codice in alcune parti dà obbrobrio. Tra l'altro per ogni singolo commento che devi postare ti metti a fare un nuovo login invece di agire con la gestione dei cookie (https://www.seleniumeasy.com/selenium-tutorials/how-to-handle-cookies-in-selenium-webdriver).

Ma poi spammare di commenti certi video? A che scopo? Poi (ovviamente) ci lamentiamo che Youtube Italia è una me.rda piena di gente che adopera il clickbaiting o lo spam.

OUT OF SCOPE.
 
Il codice in alcune parti dà obbrobrio. Tra l'altro per ogni singolo commento che devi postare ti metti a fare un nuovo login invece di agire con la gestione dei cookie (https://www.seleniumeasy.com/selenium-tutorials/how-to-handle-cookies-in-selenium-webdriver).

Ma poi spammare di commenti certi video? A che scopo? Poi (ovviamente) ci lamentiamo che Youtube Italia è una me.rda piena di gente che adopera il clickbaiting o lo spam.

OUT OF SCOPE.
Il codice è sicuramente migliorabile ma vedo che la tua ignoranza va di pari passo con le tue critiche. Non faccio assolutamente il login ogni volta che richiedo un video poichè grazie al comodo redirect offerto dalla pagina di login di Google posso controllare che l'utente sia collegato in maniera indiretta senza dover andare ogni volta a controllare i cookies.

YouTube italia non è certo una merd* per colpa di canali emergenti che devono farsi pubblicità. Con spam certo ma in maniera trasparente senza comprarsi visualizzazioni e likes a pacchi.
 
Caro @Notte, puoi affibbiare qualsiasi tipo di insulto nei miei confronti (ignorante, e molto altro), ma io critico quello che vedo - questa condizione:
Python:
if parsed.hostname == 'accounts.google.com':
            browser.find_element_by_id('Email').send_keys(email)
            browser.find_element_by_id('next').click()
            WebDriverWait(browser, 10).until(EC.visibility_of_element_located((By.ID, "Passwd")))
            browser.find_element_by_id('Passwd').send_keys(password)
            browser.find_element_by_id('signIn').click()
            return post_comment(browser, email, password, video_id, comment)
sarà sempre soddisfatta (e quindi il login verrà ripetutamente attuato) perchè Selenium apre un profilo di un browser (Firefox, Chrome, o quello che vuoi) dove i cookie non sono mai abilitati. Quindi il tuo "controllo" è inutile, perchè del motivo già spiegato e questo processo decelererebbe di buona parte il tuo "spammer".
E comunque, anche se dovessi utilizzare i cookies, Google (e anche YouTube) utilizza i cookie persistenti. Dal momento che scadono dopo moolto tempo di inattività, e in quanto il tuo tempo medio di inattività è massimo 1/2 secondi, non dovresti nemmemo allarmarti a fare ulteriori controlli.
 
Ehm no, non è sempre verificata poichè la richiesta GET della pagina viene eseguita in modo sincrono così da permettere al programma di eseguire prima il redirect e poi controllare l'hostname. Inoltre Selenium apre un profilo con i cookies puliti ma il bot stesso utilizza sempre gli stessi cookies fino alla sua chiusura.

Conosco i cookies persistenti ma non utilizzando metodi asincroni e multithreading non sono poi così necessari visto lo scarso utilizzo di risorse del bot.

Comunque il bot è stato testato e funziona per quanto ammetta che sia scritto male.
 
Ehm no, non è sempre verificata poichè la richiesta GET della pagina viene eseguita in modo sincrono così da permettere al programma di eseguire prima il redirect e poi controllare l'hostname
Ok, mi sembrava un po' strano quando ho riletto ora per la seconda volta il codice. Siccome non ho mai lavorato con Selenium se non in Java, e PhantomJS non lo conosco, mi sono documentato. Il vero motivo perchè non è sempre verificata non è questo, ma il fatto che tu utilizzi PhantomJS che ti attiva i cookies di default.
Non lo sapevo e il codice mi sembrava infatti un po' incredibile dato che senza PhantomJS l'handling dei cookies di solito si adopera manualmente con il dumping dei cookie, ed un browser.add_cookie(cookie) sotto un loop che itera tutti i cookies dumpati.
Quindi, dopo il primo login, ti basta caricare fare un browser.get("http://youtube.com/videoID") invece di tutto questo:
Python:
browser.get('https://accounts.google.com/ServiceLogin?continue=http%3A%2F%2Fwww.youtube.com%2Fsignin%3Fnext%3D%252Fwatch%253Fv%253D' + video_id + '%26app%3DNone%26action_handle_signin%3Dtrue%26hl%3Dit&passive=true&service=youtube&uilel=3&hl=it#identifier')
e mi aspetterei un miglioramento dal punto di vista di prestazione (perchè quando sei loggato, quel link reindirizza semplicemente al video youtube).
Conosco i cookies persistenti ma non utilizzando metodi asincroni e multithreading non sono poi così necessari visto lo scarso utilizzo di risorse del bot.
Credo tu non abbia capito. I cookies persistenti sono già utilizzati da Google e Youtube, quel controllo non ti serve a nulla (ti basta fare il login una sola volta, alla fine avvii il processo di spam: carichi i video e posti commenti in continuazione).
In breve, quei cookies possono scadere pure dopo settimane o mesi, dipende dal tuo tempo di inattività nell'uso di Google/Youtube, ma ribadisco che dal momento in cui spammi - il tuo tempo di inattività sarà max. di 1/2s.
 
Ho capito cosa intendi, e non ho usato i cookies per 2 motivi:
1)Perchè al riavvio del programma dovrei salvarli da qualche parte(PhantomJS non ha cache)
2)Per una gestione più pulita del programma

Si perde qualche secondo a fare il redirect ma per un programma così leggero risulta accettabile. In ogni caso ho rilasciato il sorgente proprio per permetterne la personalizzazione.
 
Ho capito cosa intendi, e non ho usato i cookies per 2 motivi:
1)Perchè al riavvio del programma dovrei salvarli da qualche parte(PhantomJS non ha cache)
2)Per una gestione più pulita del programma
No. Tu li stai già utilizzando, e a quanto pare nemmeno tu lo sapevi. L'handling dei cookies lo fa già PhantomJS, non dovresti preoccuparti di fare il dumping dei cookie e di aggregarli un secondo tempo al webdriver (se non avessi utilizzato PhantomJS, avresti dovuto farlo così - che è il classico metodo manuale per farlo).

Siccome non lo sapevi, ti ho consigliato di esercitare la filosofia DWAI (Don't Worry About It :asd:), all'inizio del programma fai il login su questo link, dopo modifichi post_comment così:
Python:
def post_comment(browser, email, password, video_id, comment):
    try:
        browser.get('https://youtube.com/' + video_id)

        parsed = urlparse(browser.current_url)
        if not check_exists_by_id(browser, 'movie_player'):
            return None

        if check_exists_by_id(browser, 'comments-disabled-message'):
            return None

        browser.set_window_size(1280, 930)
        WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, 'comment-simplebox-renderer')))
        browser.find_element_by_class_name('comment-simplebox-renderer-collapsed-content').click()
        WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, 'comment-simplebox-text')))
        browser.find_element_by_class_name('comment-simplebox-text').send_keys(comment)
        WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, "comment-simplebox-submit")))
        browser.find_element_by_class_name('comment-simplebox-submit').click()
        WebDriverWait(browser, 10).until(EC.invisibility_of_element_located((By.CLASS_NAME, 'comment-simplebox-loading')))
        return None
    except Exception:
        return None
a primo occhio dovrebbe funzionare, testalo (non so se l'ho indentato bene).
 
A saperlo lo sapevo ma ripeto, quanto beneficio darebbe questa cosa ad un programma così? Qualche secondo in meno al massimo per il redirect?
 
@Notte non credo sapevi che tu stesso stavi interagendo con i cookies:
non ho usato i cookies per 2 motivi
ma bando alle ciance, praticamente sì, ti salva non molti secondi, ma dato che utilizzi Selenium ne vale la pena. In sintesi, ho rimediato con un altro consiglio dato che l'altro era dovuto ad una svista, forse un po' più basilare.
Probabilmente è il più gran miglioramento che si può fare dal punto di vista di prestazione, e rimuovi pure qualche riga di codice eccessiva.
 
Stato
Discussione chiusa ad ulteriori risposte.