Facebook account download automation with python? - python

As a regular task within my job role i often have to download full Facebook accounts from within a users account. I am trying to improve my workflow and automate this if i can.
I have tried searching for this topic on the site and although many cover the login part i am yet to locate a question that deals with the popup windows of Facebook. If i am wrong i apologise and please amend the post accordingly.
As a starting point i have decided to start learning python and am using this to script the process with a little help from selenium and Chrome Driver. I have managed to write the code to login and navigate to the correct page and click the initial link 'download a copy'. I am struggling however to get the script to locate and click the 'Start My Archive' button within the popup window.
Here is the code that i have used so far including the several alternative code blocks that i have tried commented out at the bottom:
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
#Global Variables
target = "john.doe.7"
username = "john#doe.com"
password = "Password"
sleep = 5
#Finds and locates the ChromeDriver
driver = webdriver.Chrome("C:\Python35-32\ChromeDriver\chromedriver.exe")
#Set Chrome Options
chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_setting_values.notifications": 2}
chrome_options.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(chrome_options=chrome_options)
#Directs browser to webpage
driver.get('http://www.facebook.com');
#code block to log in user
def logmein():
search_box = driver.find_element_by_name('email')
search_box.send_keys(username)
search_box = driver.find_element_by_name('pass')
search_box.send_keys(password)
search_box.submit()
#code to go to specific URL
def GoToURL(URL):
time.sleep(sleep) # Let the user actually see something!
driver.get(URL);
logmein()
GoToURL('https://www.facebook.com/'+'settings')
link = driver.find_element_by_link_text('Download a copy')
link.click()
#driver.find_element_by.xpath("//button[contains(., 'Start My Archive')]").click()
#driver.find_element_by_css_selector('button._42ft._42fu.selected._42gz._42gy').click()
#driver.find_element_by_xpath("//*[contains(text(), 'Start My Archive')]").click()
#driver.find_element_by_css_selector('button._42ft._42fu.layerConfirm.uiOverlayButton.selected._42g-._42gy').click()
#from selenium.webdriver.common.action_chains.ActionChains import driver
#buttons = driver.find_elements_by_xpath("//title[contains(text(),'Start My Archive')]")
#actions = ActionChains(self.driver)
#time.sleep(2)
#actions.click(button)
#actions.perform()

Just add this to your code and run if it is working or not. Always use CssSelector.
Look i ran the below code in eclipse with java and I'm not aware of python so if something is wrong in syntax , i apologies. Just Try this and see.
driver.implicitly_wait(10)
Startmyarchive = driver.find_element_by_css_selector("._42ft._42fu.selected._42gz._42gy")
Startmyarchive.click()
driver.implicitly_wait(10)
Acknowledge = driver.find_element_by_css_selector("._42ft._42fu.layerConfirm.uiOverlayButton.selected._42g-._42gy")
Acknowledge.click()
driver.implicitly_wait(10)
ClickOkay = driver.find_element_by_css_selector("._42ft._42fu.layerCancel.uiOverlayButton.selected._42g-._42gy")
ClickOkay.click()
Happy Learning :-) Do reply back for any query.

Related

Trying to sign into google using a selenium python script

I am using selenium to open and sign into google accounts as my first step. I have successfully opened and filled the email response although upon submitting I receive the error of
"This browser or app may not be secure. Learn more Try using a
different browser. If you’re already using a supported browser, you
can refresh your screen and try again to sign in." From google.
Is there any way to get around this? Here is my code below.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://accounts.google.com/")
print(driver.title)
search = driver.find_element_by_name("identifier")
search.send_keys("email goes here")
search.send_keys(Keys.RETURN)
Was having the same issue and i found this thread in GitHub.
The solution that worked for me was to use this driver: undetected_chromedriver instead of the normal ChromeDriver.
import undetected_chromedriver.v2 as uc
chrome_options = uc.ChromeOptions()
chrome_options.add_argument("--disable-extensions")
chrome_options.add_argument("--disable-popup-blocking")
chrome_options.add_argument("--profile-directory=Default")
chrome_options.add_argument("--disable-plugins-discovery")
chrome_options.add_argument("--incognito")
chrome_options.add_argument("user_agent=DN")
self.browser = uc.Chrome(options=chrome_options)
self.browser.delete_all_cookies()
# example of loggin in to youtube without getting that issue
self.browser.get('http://youtube.com')
login_button_init = self.browser.find_element_by_xpath("//a[#aria-label='Sign in']")
login_button_init.click()
# locate the login button
login_button = self.browser.find_element_by_xpath("//paper-button[#aria-label='Sign in']")
login_button.click()
# get email and set to email input box
email = self.browser.find_element_by_id("identifierId")
myemail = os.environ.get('YOUTUBE_EMAIL')
email.send_keys(myemail)
# click next button
email_next_button = self.browser.find_element_by_id("identifierNext")
email_next_button.click()
# get password and set to password input box
password = self.browser.find_element_by_name("password")
mypassword = os.environ.get('YOUTUBE_PASSWORD')
password.send_keys(mypassword)
sleep(2)
# click next button to log in
pass_next_button = self.browser.find_element_by_id("passwordNext")
pass_next_button.click()

Python Selenium "Unable to locate element"

I am trying to use Selenium to sign up an email account automatically whenever I need to. It's just a fun learning project for me. For the life of me I don't understand why it can't find the element. This code works fine on the sign-in page but not the sign-up page. I have tried all different Selenium commands and even tried using the ID and class name. Either is says it can't locate the element or that it is not reachable by keyboard.
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import time
options = Options()
driver = webdriver.Firefox(options=options, executable_path=r'geckodriver.exe')
driver.get("https://mail.protonmail.com/create/new?language=en")
time.sleep(10)
username_input = driver.find_element_by_id("username").send_keys("testusername")
Also here is the HTML code: https://i.imgur.com/ZaBMTzG.png
The username field is in iframe, you need to switch to iframe to make this work.
Below is the code that works fine :
driver.get("https://mail.protonmail.com/create/new?language=en")
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='Registration form'][class='top']"))
driver.find_element_by_id("username").send_keys("some string")
read more about iframe here
learn more about how to switch to iframe/frame/framset using Python
selenium Bindings here
Update :
wait = WebDriverWait(driver, 30)
driver.get("https://mail.protonmail.com/create/new?language=en")
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='Registration form'][class='top']"))
driver.find_element_by_id("username").send_keys("some string")
driver.switch_to.default_content()
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
sleep(5)
driver.switch_to.frame(driver.find_element_by_css_selector("iframe[title='Registration form'][class='bottom']"))
wait.until(EC.element_to_be_clickable((By.NAME, "submitBtn"))).click()
I'm not sure if I've seen enough code to diagnose, but I think the way you are defining username_input seems problematic. driver.find_element_by_id("username").send_keys("testusername") doesn't actually return anything so it seems like you are setting username_input = null.

Python selenium WhatsApp bot

I am trying to create a bot in WhatsApp but I keep running into
NoSuchElementException
My code is below :
from selenium import webdriver
Import time
Firefox_browser = webdriver.Firefox(executable_path="/usr/bin/geckodriver")
Firefox_browser.get('https://web.whatsapp.com/')
time.sleep(15)
firefox_browser.switch_to_frame(firefox_browser.find_element_by_name("WhatsAppBot"))
firefox_browser.find_element_by_xpath('//span[#title="WhatsAppBot"]).click()
There is no element with name attribute equals WhatsAppBot on that page
As the other answer has already pointed out, what you are trying to do in the last two lines does not make sense. The find element by xpath/name function expects to be pointed at a certain element on Whatsapp. There is no element called "WhatsAppBot" on the WhatsApp webpage.
Unfortunately you did not give a lot of info to work with, however, I think what you want to achieve might be similar to this tutorial. I used this myself when I tried to play around with sending automatic messages via Whatsapp.
The following code is what I used for my own small bot and largely follows the before mentioned tutorial:
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# SPECIFY PATH FOR CHROME DRIVER HERE
driverPath = 'D:chromedriver_win32\\chromedriver.exe'
# SPECIFY PATH FOR USER DIRECTORY (just change "TEST" to your WIN10 username)
userPath = "--user-data-dir=C:\\Users\\TEST\\AppData\\Local\\Google\\Chrome\\User Data"
# SPECIFY MESSAGES HERE
messages = ["Testmessage 1", "Testmessage 2"]
# bypass QR code login after first login
options = Options()
options.add_argument(userPath)
options.add_experimental_option('useAutomationExtension', False)
options.add_experimental_option("excludeSwitches", ["enable-automation"])
driver = webdriver.Chrome(driverPath, options=options)
# open specified whatsapp chat
driver.maximize_window()
driver.get('https://web.whatsapp.com')
time.sleep(10)
driver.find_element_by_xpath("//*[#title='INSERT NAME OF CHAT HERE']").click()
# Send message
driver.find_element_by_xpath('//*[#id="main"]/footer/div[1]/div/div/div[2]/div[1]/div/div[2]').send_keys(messages[0])
driver.find_element_by_xpath('//*[#id="main"]/footer/div[1]/div/div/div[2]/div[2]/button').click()
driver.close()
Note that this code uses the chrome driver instead.
In the future the whatsapp layout might change, meaning the given xpaths could produce errors similar to yours because the element arrangement has changed. In that case you will need to find the new xpath of the element you want to perform tasks on (i.e. click on it) and update it in your code. You can easily do that by pressing F12 while you are on Whatsapp Web, then hit Ctrl + Shift + C and click on the element. The element is then highlighted on the right of the screen and if you right click on it you will see the option "copy -> copy xpath". That's the path you will need to paste into the find_element_by_xpath function for it to work.

How to login to yahoo via Selenium python (tried multiple solutions)

I'm trying to login to my yahoo account via selenium. I'm simply learning at this point and have made programs for different websites in order to get more comfortable with Selenium overall.
I'm now trying to login to Yahoo and I haven't been able to figure it out.
URL: https://login.yahoo.com/
I've tried doing:
yahoologin1 = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, "#login-username"))).sendKeys("tester#yahoo.com")
yahoologin1 = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, "login-username"))).sendKeys("tester#yahoo.com")
yahoologin1 = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, "//input[#id='login-username']"))).sendKeys("tester#yahoo.com")
yahoologin1 = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, "/html[1]/body[1]/div[2]/div[1]/div[1]/form[1]/div[2]/input[1]"))).sendKeys("tester#yahoo.com")
Anything that I'm particularly missing? Would appreciate if someone told me how to get this login to work. Rather have that than a simple copy paste of code :) Thank you!
I've done some further testing and it works when on the main tab. However, I am opening a new tab with the yahoo login page it doesn't work. Do I have to do something differently to type on a new tab?
I used another approach without WebDriverWait to solve, hope it helps.
from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--window-size=1920x1080")
browser = webdriver.Chrome('./chromedriver', chrome_options=chrome_options)
# Opening yahoo page in a new tab
browser.execute_script("window.open('https://login.yahoo.com/');")
# Switch to new tab
browser.switch_to.window(browser.window_handles[-1])
# Selecting login-username and putting email
browser.find_element_by_id('login-username').send_keys('tester#yahoo.com')
Result:
Here is the sample script.
url = "https://login.yahoo.com/"
# Step 1 -navigate to the AUT
driver.get(url)
print ("Step 1 - Done")
# Step 2 - Enter the username
#wait for the user name to be displayed
userName = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'input#login-username')))
userName.send_keys("used css")
# Step 3 - click on Next
driver.find_element_by_xpath("//input[#id='login-signin']").click()
# Step 4 - Enter password
passWord = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"input[name='password']")))
passWord.send_keys("password")
# Step 5 - Click on Sign in
driver.find_element_by_id("login-signin").click()
Here is how you can do the script development quick and effectively.
Keep a break point after browser navigated to url
Get the element xpath using chrome devtools, refer here to how to get test and get the xpath
Go to Console > click on show python prompt to open the interactive console
Enter the code here and hit enter to check if that line works when you place it in your script
Make any necessary change and confirm the step works
Copy paste the step from interactive console to script

Python selenium scraper works perfect on windows but not on raspian raspbian

The purpose of this script is to scrape info from my work schedule. The full script works fine when I run it on my windows laptop but when I try to run on raspian it appears the click.() on the "display_but" variable is not doing its job.The page pulls up fine and logs with no problem, and it even selects an option from a dropdown with no problem. Only when clicking the display button does an error seem to occur. The object is being found as if I print it I get a selenium web object. There are not error messages. When I use drop.click() this appears to work as correct option from dropdown is being selected. I am lost
Below are the workarounds I have tried.
1. Using Keys module to tab to the button and then submitting.
- this results in the correct button being selected but when I "press enter" using keys nothing happens.
2. I tried waiting for element to be clickable using WebDriverWait, expected conditions, and By modules
- this method also works on my windows but not on raspian
3. I have tried adding implicit waits and time.sleep
- these methods did not seem to help
Below is my code
import time
from selenium import webdriver
driver = webdriver.Chrome(executable_path="/Users/Sanch/Desktop/Drivers/chromedriver")
url = 'website'
driver.get(url)
#logs into account
username_xpath = '//*[#id="usernameInputField"]'
password_xpath = '//*[#id="passwordInputField"]'
login_xpath = '//*[#id="submitButton"]/span/input'
user_name = driver.find_element_by_xpath(username_xpath)
user_name.send_keys('username')
password = driver.find_element_by_xpath(password_xpath)
password.send_keys('password')
password.submit()
#selects option from dropdown
drop_xpath ='/html/body/associate/div/view-userschedule/div/div/div[2]/div/div[1]/select/option[2]'
drop = driver.find_element_by_xpath(drop_xpath)
drop.click()
time.sleep(3)
#clicks display button
Clicks display button (shows whatever selected in dropdown)
display_but_xpath = '/html/body/associate/div/view-userschedule/div/div/div[2]/div/div[3]/button'
display_but = driver.find_element_by_xpath(display_but_xpath)
display_but.click()
You should probably do as much of that from the browser context as possible. For example:
driver.execute_script("document.querySelector('[id=usernameInputField]').value = 'user'")
driver.execute_script("document.querySelector('[id=passwordInputField]').value = 'password'")
driver.execute_script("document.querySelector('css-for-button').click()")
Solved the problem by running the script with headless chrome instead of regular chrome. Using the code below in place of "driver = webdriver.Chrome(executable_path="/Users/Sanch/Desktop/Drivers/chromedriver")" made it so that the script ran properly.
I am not sure if it was due to the lack of computing power with raspberry pi 3+ or some other factor but everything is working properly now. Maybe someone else can shed light on why headless would work but regular chrome wouldn't. Thanks for the help everyon!
#headless driver setup and launch
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--window-size=1920x1080")
chrome_driver = "your drivers path"
driver = webdriver.Chrome(chrome_options=chrome_options, executable_path=chrome_driver)

Categories