123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571 |
- # coding: utf-8
- from selenium import webdriver
- from selenium.common.exceptions import NoSuchElementException
- from selenium.webdriver.common.keys import Keys
- from selenium.webdriver import ChromeOptions
- from datetime import datetime as dt
- from time import sleep
- import time
- import os
- import json
- import re
- import operator
- CREDS = {'user': 'deeejas@yandex.com', 'pass': 'TB1984_li'}
- selfProfile = "https://mbasic.facebook.com/profile.php?fref=pb"
- self_name = 'Levente Marton'
- def count_down(t, d_type, up_down, max_count=None):
- if up_down == 'down':
- _one = -1
- _OPERAND = operator.ge
- max_count = 0
- finish = 'count%s finished' % up_down
- elif up_down == 'up':
- _one = 1
- _OPERAND = operator.le
- finish = 'count%s finished' % up_down
- max_count = max_count
- while _OPERAND(t, max_count):
- if d_type == 'm':
- mins, secs = divmod(t, 60)
- tf = '{0:2d}:{1:2d}'.format(mins, secs)
- print(tf, end='\r')
- time.sleep(1)
- t += _one
- elif d_type == 'h':
- hour, rem = divmod(t, 60)
- _, secs = divmod(rem, 60)
- hours, mins = divmod(hour, 60)
- tf = '{0:02d}:{1:02d}:{2:02d}'.format(hours, mins, secs)
- print(tf, end='\r')
- time.sleep(1)
- t += _one
- else:
- print(finish)
- def mfacebookToBasic(url):
- '''Reformat a url to load mbasic facebook instead of regular facebook, return the same string if
- the url don't contains facebook'''
- if "m.facebook.com" in url:
- return url.replace("m.facebook.com", "mbasic.facebook.com")
- elif "www.facebook.com" in url:
- return url.replace("www.facebook.com", "mbasic.facebook.com")
- else:
- return url
- class Person():
- '''Basic class for people's profiles'''
- def __init__(self):
- self.name = ""
- self.profileLink = ""
- self.addLink = ""
- def __str__(self):
- s = ""
- s += self.name + ":\n"
- s += "Profile Link: " + self.profileLink
- if self.addLink != "":
- s += "Addlink ->: " + self.addLink
- return s
- def __repr__(self):
- self.__str__()
- class Post():
- '''Class to contain information about a post'''
- def __init__(self):
- self.posterName = ""
- self.text = ""
- self.numLikes = 0
- self.time = ""
- self.privacy = ""
- self.posterLink = ""
- self.linkToComment = ""
- self.linkToLike = ""
- self.linkToLikers = ""
- self.linkToReport = ""
- self.groupLink = ""
- self.linkToShare = ""
- self.linkToMore = ""
- self.numComents = 0
- def toDict(self):
- return self.__dict__.copy()
- def fromDict(self, d):
- self.__dict__ = d.copy()
- def from_json(self, j):
- self.fromDict(json.loads(j))
- def from_json_file(self, f):
- self.fromDict(json.loads(open(f, "rt").read()))
- def to_json(self):
- return json.dumps(self.toDict())
- def __str__(self):
- s = "\nPost by " + self.posterName + ": "
- s += self.text + "\n"
- s += "Likes: " + str(self.numLikes) + " - "
- s += "Comments: " + str(self.numComents) + " - "
- s += self.time + " "
- s += " - Privacy: " + self.privacy + "\n-"
- s += "\n Comment -> " + self.linkToComment + "\n"
- return s
- def __repr__(self):
- return self.__str__()
- class FacebookBot(webdriver.Chrome):
- '''Main class for browsing facebook'''
- def __init__(self, executable_path='chromedriver', visible=False):
- '''relativePhatomJs = "\\phantomjs.exe"
- service_args = None
- if images == False:
- service_args = ['--load-images=no', ]
- if pathToPhantomJs == None:
- path = self, os.getcwd() + relativePhatomJs
- else:
- path = pathToPhantomJs
- webdriver.PhantomJS.__init__(self, path, service_args=service_args)
- '''
- self.visible = visible
- self.executable_path = executable_path
- self.chrome_options = ChromeOptions()
- self.chrome_options.add_argument('--disable-infobars')
- self.chrome_options.add_argument('--no-sandbox')
- self.chrome_options.add_argument('--disable-dev-shm-usage')
- self.chrome_options.add_argument('--disable-gpu')
- if self.visible is False:
- self.chrome_options.add_argument('--headless')
- webdriver.Chrome.__init__(self, executable_path=self.executable_path, options=self.chrome_options)
- def get(self, url):
- '''The make the driver go to the url but reformat the url if is for facebook page'''
- super().get(mfacebookToBasic(url))
- def login(self, email, password):
- '''Log to facebook using email (str) and password (str)'''
- url = "https://mbasic.facebook.com"
- self.get(url)
- email_element = self.find_element_by_name("email")
- email_element.send_keys(email)
- pass_element = self.find_element_by_name("pass")
- pass_element.send_keys(password)
- pass_element.send_keys(Keys.ENTER)
- try:
- confirm_element = self.find_element_by_xpath('//*[@id="root"]/table/tbody/tr/td/div/form/div/input')
- confirm_element.click()
- except NoSuchElementException:
- print('No confirm element found')
- try:
- self.find_element_by_name("xc_message")
- print("Logged in")
- return True
- except NoSuchElementException as dummy:
- print("Fail to login")
- return False
- def logout(self):
- '''Log out from Facebook'''
- url = "https://mbasic.facebook.com/logout.php?h=AffSEUYT5RsM6bkY&t=1446949608&ref_component=mbasic_footer&ref_page=%2Fwap%2Fhome.php&refid=7"
- try:
- self.get(url)
- print('logged out')
- return True
- except Exception as e:
- print("Failed to log out ->\n", e)
- return False
- def postTextToURL(self, text, url):
- '''Post text(str) to url (str), url can be a group, fan page or profile'''
- try:
- self.get(url)
- textbox = self.find_element_by_name("xc_message")
- textbox.send_keys(text)
- submit = self.find_element_by_name("view_post")
- submit.click()
- return True
- except Exception as e:
- print("Failed to post in ", url, "->\n", e)
- return False
- def postTextToTimeline(self, text):
- '''Shortcut to post in your own timeline'''
- url = "https://mbasic.facebook.com/"
- return self.postTextToURL(text, url)
- def newMessageToFriend(
- self,
- friendname,
- message,
- image1=None,
- image2=None,
- image3=None):
- '''Send message(str) to friend name (str), images doesn work in phantomjs'''
- url = "https://mbasic.facebook.com/friends/selector/?return_uri=%2Fmessages%2Fcompose%2F&cancel_uri=https%3A%2F%2Fm.facebook.com%2Fmessages%2F&friends_key=ids&context=select_friend_timeline&refid=11"
- self.get(url)
- q = self.find_element_by_name("query")
- q.send_keys(friendname)
- q.send_keys(Keys.ENTER)
- id = self.page_source.split(
- "/messages/compose/?ids=")[1].split('"><span>')[0].split('"><span>')[0]
- url = "https://mbasic.facebook.com/messages/compose/?ids=" + id
- self.get(url)
- t = self.find_element_by_name("body")
- t.send_keys(message)
- t.send_keys(Keys.ENTER)
- f1 = self.find_element_by_name("file1")
- f2 = self.find_element_by_name("file2")
- f3 = self.find_element_by_name("file3")
- if image1 is not None:
- f1.send_keys(image1)
- if image2 is not None:
- f2.send_keys(image2)
- if image3 is not None:
- f3.send_keys(image3)
- send = self.find_element_by_name("Send")
- send.send_keys(Keys.ENTER)
- return True
- def getPostInGroup(self, url, deep=2, moreText="no more posts"):
- '''Get a list of posts (list:Post) in group url(str) iterating deep(int) times in the group
- pass moreText depending of your language, i couldn't find a elegant solution for this'''
- self.get(url)
- ids = [4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f']
- posts = []
- for n in range(deep):
- # print("Searching, deep ",n)
- for i in ids:
- # print(i)
- post = Post()
- try:
- p = self.find_element_by_id("u_0_" + str(i))
- # print(p.get_attribute('id'))
- # print(p.text)
- a = p.find_elements_by_tag_name("a")
- post.posterName = a[0].text
- try:
- post.numLikes = int(a[4].text.split(" ")[0])
- # post.numLikes = int(a[2].text.split(" ")[0])
- except ValueError:
- post.numLikes = 0
- post.text = p.find_element_by_tag_name("p").text
- post.time = p.find_element_by_tag_name("abbr").text
- # p.text.split("· ")[1].split("\n")[0]
- post.privacy = self.title
- post.posterLink = a[0].get_attribute('href')
- # p.find_element_by_class_name("du").get_attribute('href')
- # post.linkToComment = a[4].get_attribute('href')
- post.linkToComment = a[2].get_attribute('href')
- # post.linkToLike = a[2].get_attribute('href')
- post.linkToLike = a[4].get_attribute('href')
- try:
- post.numComents = int(a[4].text.split(" ")[0])
- # post.numComents = int(a[5].text.split(" ")[0])
- except ValueError:
- post.numComents = 0
- # post.linkToShare = a[5].get_attribute('href')
- post.linkToLikers = a[1].get_attribute('href')
- # post.linkToMore = a[6].get_attribute('href')
- if post not in posts:
- posts.append(post)
- except Exception as dummy:
- # print(str(exc))
- # print(exc.args)
- # print(exc)
- continue
- try:
- more = self.find_element_by_partial_link_text(
- moreText).get_attribute('href')
- self.get(more)
- # self.find_element_by_partial_link_text(moreText)
- except Exception as dummy:
- # print(e)
- print("no more posts")
- return posts
- def postInGroup(self, groupURL, text):
- '''Post text(str) in a group'''
- self.get(groupURL)
- try:
- tf = self.find_element_by_name("xc_message")
- except NoSuchElementException:
- print(" Group url doesn't exist or you don't have permissions to see it")
- return False
- tf.send_keys(text)
- self.find_element_by_name("view_post").send_keys(Keys.ENTER)
- print('new post created')
- return True
- def postImageInGroup(self, url, text, image1, image2="", image3=""):
- '''Post image(str) in a group(url:str) with the text(str), doesn't work in phantomJS'''
- self.get(url)
- v = self.find_element_by_name("view_photo")
- v.send_keys(Keys.ENTER)
- self.save_screenshot("debug.jpg")
- i1 = self.find_element_by_name("file1")
- i2 = self.find_element_by_name("file2")
- i3 = self.find_element_by_name("file3")
- i1.send_keys(image1)
- i2.send_keys(image2)
- i3.send_keys(image3)
- filter = self.find_element_by_name("filter_type")
- filter.value_of_css_property(0)
- pre = self.find_element_by_name("add_photo_done")
- pre.click()
- m = self.find_element_by_name("xc_message")
- m.send_keys(text)
- vp = self.find_element_by_name("view_post")
- vp.click()
- return True
- def commentInPost(self, postUrl, text):
- '''Comment a text(str) in a post(str)'''
- try:
- self.get(postUrl)
- tb = self.find_element_by_name("comment_text")
- tb.send_keys(text)
- tb.send_keys(Keys.TAB, Keys.ENTER)
- # _enter = self.find_element_by_xpath('//*[@id="u_0_3"]/tbody/tr/td[2]/div/input').click()
- return
- except Exception as e:
- print("Can't comment in ", postUrl, "\n->", e)
-
- def goToPost(self, postUrl):
- '''go to post in a group'''
- try:
- self.get(postUrl)
- # tb = self.find_element_by_name("comment_text")
- # tb.send_keys(text)
- # tb.send_keys(Keys.TAB, Keys.ENTER)
- return
- except Exception as e:
- print("Can't comment in ", postUrl, "\n->", e)
-
- def goToGroup(self, groupurl):
- try:
- self.get(groupurl)
- print('go to group: ', groupurl)
- except Exception as e:
- print(str(e))
-
- def getComments(self, postUrl):
- self.get(postUrl)
- gc = []
- for i in self.find_elements_by_tag_name('div'):
- if i not in gc:
- gc.append(i)
- return gc[0].text.splitlines()
-
- def getGroupMembers(self, url, deep=3, start=0):
- '''Return a list of members of a group(url) as a list:Person iterat deep(int) times'''
- seeMembersUrl = url + "?view=members&refid=18"
- groupId = url.split("groups/")[1]
- step = 28
- r = "https://mbasic.facebook.com/browse/group/members/?id=$GROUPID$&start=$n$"
- rg = r.replace("$GROUPID$", groupId)
- members = []
- for d in range(start, start + deep):
- url = rg.replace("$n$", str(d * 30))
- self.get(url)
- # print(self.current_url)
- p = self.find_elements_by_class_name("p") # BK cada profile
- for b in p:
- person = Person()
- h3 = b.find_elements_by_tag_name("h3")
- person.name = h3[0].text
- person.profileLink = h3[0].find_element_by_tag_name(
- "a").get_attribute('href')
- try:
- person.addLink = b.find_elements_by_tag_name(
- "a")[1].get_attribute('href') # puede haber error
- except Exception:
- # print("No Addlink")
- pass
- members.append(person)
- # more = self.find_element_by_id("m_more_item").find_element_by_tag_name("a").get_attribute('href')
- # self.get(more)
- # print(more)
- # print(len(members))
- return members
- def sendFriendRequest(self, url):
- '''Send a friend request to a profile(str)'''
- self.get(url)
- try:
- bz = self.find_element_by_class_name("bz")
- l = bz.get_attribute('href')
- self.get(l)
- return True
- except Exception:
- # print("Can't add friend")
- return False
- def messageToUrl(self, url, text):
- '''Message a profile/fanpage (str) with text(str)'''
- self.get(url)
- name = self.title
- try:
- mb = self.find_elements_by_class_name("bx")
- except NoSuchElementException:
- print("Can't message to ", name)
- return False
- mm = None
- for m in mb:
- if "messages" in m.get_attribute('href'):
- mm = m.get_attribute('href')
- break
- self.get(mm)
- b = self.find_element_by_name("body")
- b.send_keys(text)
- self.find_element_by_name("Send").click()
- return True
- def getGroups(self):
- '''
- Return a list of url of the groups your account belong to'''
- url = "https://m.facebook.com/groups/?seemore"
- # g = {"name": ("url", 0)}
- g = dict()
- self.get(url)
- br = self.find_elements_by_class_name("br")
- for b in br:
- try:
- notis = int(b.text[-2:])
- group_name = b.text[:-2]
- except ValueError:
- group_name = b.text
- notis = 0
- try:
- link = b.find_element_by_tag_name("a").get_attribute('href')
- g[group_name] = (mfacebookToBasic(link), notis)
- except Exception as dummy:
- print("Can't get group link")
- return g
- def getSuggestedGroups(self, sendrequest=False):
- '''
- Return a list of suggested groups and optionally send a request to join'''
- url = "https://m.facebook.com/groups/"
- g = dict()
- self.get(url)
- bq = self.find_elements_by_class_name("bq")[-1]
- li = bq.find_elements_by_tag_name("li")
- for l in li:
- nombre = l.find_elements_by_tag_name(
- "td")[0].find_elements_by_tag_name("a")[0].text
- description = l.find_elements_by_tag_name(
- "td")[0].find_elements_by_class_name("bx")[0].text
- linkToGroup = l.find_elements_by_tag_name(
- "td")[0].find_element_by_tag_name("a").get_attribute('href')
- linkToRequest = l.find_elements_by_tag_name(
- "td")[-1].find_element_by_tag_name("a").get_attribute('href')
- g[nombre] = (description, linkToGroup, linkToRequest)
- if sendrequest:
- for r in g:
- try:
- self.get(g[r][2])
- print("Request to group: ", r)
- except Exception:
- print("Fail to send request to: ", r)
- return g
- def getPostInProfile(
- self,
- profileURL,
- deep=100,
- moreText="Mostrar",
- sharedText=(
- "shared",
- "comparti",
- "compartio")):
- '''Return a list of Posts in a profile/fanpage , setup the "moreText" using your language, theres not elegant way to handle that'''
- pList = list()
- self.get(profileURL)
- # DEEP1
- n = 0
- for d in range(deep):
- try:
- for i in (3, 4, 5, 6, 7):
- try:
- e = self.find_element_by_id("u_0_" + str(i))
- tU = str(e.text)
- except Exception:
- continue
- try:
- tspl = tU.split(self.title)[1].split("\n")[:-3]
- except IndexError:
- continue
- tFi = ""
- for k in tspl:
- tFi += k
- if sharedText[0] in tFi or sharedText[1] in tFi or sharedText[2] in tFi:
- continue
- if tFi not in pList:
- pList.append(tFi)
- n += 1
- print(n, "-\n", tFi)
- else:
- continue
- # press more
- al = self.find_element_by_partial_link_text(moreText)
- link = al.get_attribute('href')
- self.get(link)
- except BaseException:
- pass
- return pList
- #-------------------------------------------------------------------------------
- # if __name__ == '__main__':
- # bot = FacebookBot()
- # try:
- # bot.login('deeejas@gmail.com', 'italotrance')
- # # _posts = bot.getPostInGroup('https://mbasic.facebook.com/groups/106321362854637?refid=18&__tn__=C-R', deep=2
- # # _posts = bot.getPostInGroup('https://mbasic.facebook.com/groups/2121044018158040?refid=27', deep=2)
- # # bot.postInGroup('https://mbasic.facebook.com/groups/2121044018158040?refid=27', 'foci november 22')
- # _comment = True
- # gr_url = 'https://mbasic.facebook.com/groups/106321362854637?refid=18&__tn__=C-R'
- #
- # while True:
- # if not _comment: print('I : comment was inserted')
- # if dt.today().weekday() == 0 and _comment:
- # print('verifying post')
- # bot.refresh()
- # sleep(1)
- # _posts = bot.getPostInGroup(gr_url, deep=1)
- # sleep(2)
- # for i in _posts:
- # if re.search('jus[a-z]*|min[a-z]*|hr[a-z]*', i.time): # and re.search('foc[a-z]*', i.text):
- # print(i.posterName, i.time, i.text, i.numComents)
- # # pc = bot.getComments(i.linkToComment)
- # # print(pc)
- # # for i in pc:
- # # print(i.text)
- # bot.commentInPost(i.linkToComment, '+1')
- # print('post commented')
- # _comment = False
- # count_down(60, 'm', 'down')
- # else:
- # print('I : check on next monday')
- # count_down(3600, 'h', 'down')
- # except KeyboardInterrupt:
- # bot.logout()
- #-------------------------------------------------------------------------------
|