from selenium import webdriver
from time import sleep
filename = "log.txt"
myfile = open(filename, 'w')
class Search(object):
def __init__(self):
self.driver = webdriver.Chrome('chromedriver.exe')
# "This will open a new chrome instance without being logged in to the site"
self.driver.get("Site2")
sleep(2)
self.driver.find_element_by_xpath("/html/body/div[1]/div[4]/div/div/div[3]/div/div/div[2]/div[2]/div[2]/div/div[4]/div[1]/div[2]/div[1]/a").click()
sleep(2)
Texto = self.driver.find_element_by_xpath("/html/body/div[1]/div[4]/div/div/div[4]/div/div/div[1]/div[3]/div/article[1]/div/div[2]/div/div/div/article/div[1]").text
print(Texto)
myfile.write(Texto)
myfile.close()
sleep(10)
import re
Id = re.compile('[0-9]{9}')
Id2 = re.compile('[0-9]{4}')
DobMonth = re.compile('[0-9]{2}')
DobYear = re.compile('[0-9]{2}')
if Id.match(Texto) and Id2.match(Texto) and DobMonth.match(Texto) and DobYear.match(Texto):
print ("Matches")
else:
print("Not match")
sleep (20)
Search()
class BasicBot(object):
def __init__(self, username, pw):
self.driver = webdriver.Chrome('chromedriver.exe')
self.driver.get("site1")
sleep(2)
self.driver.find_element_by_xpath("/html/body/div[1]/div[1]/div/div/div/div[1]/a[1]/span").click()
sleep(2)
self.driver.find_element_by_xpath("//input[#name=\"login\"]")\
.send_keys(username)
self.driver.find_element_by_xpath("//input[#name=\"password\"]")\
.send_keys(pw)
self.driver.find_element_by_xpath('/html/body/div[4]/div/div[2]/div/form/div[1]/dl/dd/div/div[2]/button').click()
sleep(2)
Search()
BasicBot('username',"password")
So the script runs BasicBot(usr,psswd) logs in to the site, and is supposed to go to a different site while logged in, then searches if X post matches the criteria given, if it does that's it if it does not, I should refresh the site and check again.
In the Search class, you start with creating a new chromedriver instance: self.driver = webdriver.Chrome('chromedriver.exe'), this is why it opens another window with a fresh state.
Instead, modify your Search class to
take an existing instance of webdriver.
open a new window by using script window.open instead of get:
class Search:
def __init__(self, driver):
self.driver = driver
# Open a new window
self.driver.execute_script("window.open('https://site2')")
sleep(2) # visually check to make sure it opened
# Switch to new window
self.driver.switch_to.window(self.driver.window_handles[-1])
# After this you can start doing self.driver.find_element_by_xpath and the rest
In the class BasicBot, modify the last line to pass the driver:
Search(self.driver)
Lastly, you can use refresh to refresh your site2:
else:
print("Not match")
sleep(20)
self.driver.refresh()
Hope, it helps. Good luck!
Related
Hi I want to click on a button and then go to next page using selenium python. but instead it get close doesnot show the next tab at all
import time
from Base_Class import *
class Majestic_Domain:
def capture_domain():
web_driver_conn = base_class.web_driver()
web_driver_conn.get("https://tranco-list.eu/")
CSV_Download = web_driver_conn.find_element(By.XPATH, '//body/main/div/div/a')
time.sleep(10)
CSV_Download.click()
#web_driver_conn.execute_script("arguments[0].click();", CSV_Download)
Majestic_Domain.capture_domain()
This is the code I used
Base class
def web_driver():
driver_conn = webdriver.Chrome()
return driver_conn
Add some wait time after the click() action:
def capture_domain():
web_driver_conn = base_class.web_driver()
web_driver_conn.get("https://tranco-list.eu/")
CSV_Download = web_driver_conn.find_element(By.XPATH, '//body/main/div/div/a')
time.sleep(1)
CSV_Download.click()
time.sleep(5)
I'm trying to build a program which opens Chrome pages one by one.
I'm using Selenium library.
My idea is to have different IP every time I open a new page.
I read about proxies but I'm not able to manage them.
Can you help me?
This is my code:
class myClass:
def __init__(self):
self.options = Options()
self.options.add_argument('--allow-running-insecure-content')
self.options.add_argument('--ignore-certificate-errors')
self.driver = webdriver.Chrome('./chromedriver',options = self.options)
def openBrowser(self):
self.chrome.get("http://whatismyipaddress.com")
def closeBrowser(self):
driver = self.driver
driver.close()
driver.quit()
if __name__ == "__main__":
#create object list
object = [myClass(i) for i in range(10)]
for i in range(10):
#open Chrome page
object[i].openBrowser()
# here I want to change IP and then I close the page before opening a new one
#close Chrome page
object[i].closeBrowser()
I am trying to open two different urls side by side.
First if opens url1 does some checks
Then it should open url2 and do some checks
Then it should closee both url1 and url2 after doing the tests
I have been able to open two url1 and url2 but the tearDown is closing only url2.
I want my tearDown to close both urls.
This is the code I have tried
class Login(unittest.TestCase):
site_url1 = "https://www.google.com/"
site_url2 = "https://www.facebook.com/"
def setUp(self):
# create a new Firefox session
self.browser = webdriver.Firefox()
browser = self.browser
browser.get(self.site_url1)
def more_loggin(self):
# create a new Firefox session
self.browser = webdriver.Firefox()
browser = self.browser
browser.get(self.site_url2)
def tearDown(self):
self.browser.quit()
Above code is only closing site_url2, I want it to close the other url as well.
Seems like the self.browser has value of site_url2 and hence is not able to close the other one.
How can I resolve it?
this is because you set self.browser every time you call setUp or more_loggin.
this means that if you call one function, let's say setUp() and then you call more_loggin, you lose the instance of Firefox which was created by setUp, and self.browser gets a new instance, created at the start of more_loggin.
when you call tearDown, only the last instance which is stored in self.browser will close, and all of the others will remain open.
I suggest you save all of the instances in a list, defined at the class-level, and then tearDown should iterate over every instance and close it.
class Login(unittest.TestCase):
instances = []
site_url1 = "https://www.google.com/"
site_url2 = "https://www.facebook.com/"
def openFirefox(self):
# create a new Firefox session
firefox = webdriver.Firefox()
# save session in instances
self.instances.append(firefox)
# return the session
return firefox
def setUp(self):
browser = self.openFirefox()
browser.open(self.site_url1)
def more_loggin(self):
browser = self.openFirefox()
browser.open(self.site_url2)
def tearDown(self):
for browser in self.instances:
# close every instance in instances
browser.quit()
The code I've written successfully does its part in crawling through a website with the appropriate date and time formatted in the URL, grabbing the table from the underlying HTML source code, and appending the results to a cache.
This python file gets run several dozen times (there are many agent IDs whose info I need to grab); after the script runs, however, dozens of chrome.exe and chromedriver.exe instances still appear in the computer's memory (this is visible in the computer's "Resource Monitor.")
Below is my code. I've used driver.quit() as well as driver.close() and even both together (with driver.close() coming first).
Isn't the driver.quit() supposed to close the instances in the computer's system? Why are they appearing in the memory? Is there a solution to this issue?
Please let me know if I can provide any further information. Thank you in advance.
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from datetime import datetime, timedelta
import credentials_page
def get_updated_url(agent_id_num):
now = datetime.utcnow()
today = datetime(now.year, now.month, now.day)
yesterday = today - timedelta(days=1)
previous_date_string = str(yesterday)[:10]
return 'https://examplewebsite.com/agentId/'+agent_id_num+'/orderBy/ASC/startDate/'+previous_date_string+'%204:00%20AM/endDate/'+previous_date_string+'%2010:30%20PM'
def login_entry(username, password, browser): # logs into website
login_email = browser.find_element_by_id('UserName')
login_email.send_keys(username)
login_password = browser.find_element_by_id('Password')
login_password.send_keys(password)
submit_elem = browser.find_element_by_xpath("//button[contains(text(), 'Log in')]")
submit_elem.click()
def get_element(xpath, browser): # grabs element, turns it into needed table in raw HTML format
table_of_interest = browser.find_element_by_xpath(xpath)
# this has a type of <class 'selenium.webdriver.remote.webelement.WebElement'>
return str('<table>'+table_of_interest.get_attribute('innerHTML')+'</table>')
def record_source_code(destination_cache, get_element_html): # takes element HTML and writes it to cache
code_destination = open(destination_cache, 'w')
code_destination.write(repr(get_element_html))
code_destination.close()
def main_function(agent_id):
driver = webdriver.Chrome()
# figure out strings for start_date, end_date
url = get_updated_url(agent_id)
driver.get(url)
#login
login_entry(credentials_page.website_username, credentials_page.website_password, driver)
# first test to see if "not found"
if len(driver.find_elements_by_xpath("//*[text()='Not Found']"))>0:
logoff_elem = driver.find_element_by_xpath("//*[contains(text(), 'Log off')]")
logoff_elem.click()
driver.quit()
return False
else:
#grab table needed
WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH,'/html/body/div/div/div[2]/div[2]/table/tbody')))
table_html = get_element('/html/body/div/div/div[2]/div[2]/table/tbody', driver)
driver.quit()
record_source_code('results_cache.html', table_html)
return True
I think the root cause is your code doesn't handle an exception. So when an exception occurs, it won't quit. Try/catch should help.
def main_function(agent_id):
driver = webdriver.Chrome()
# figure out strings for start_date, end_date
url = get_updated_url(agent_id)
try:
driver.get(url)
#login
login_entry(credentials_page.website_username, credentials_page.website_password, driver)
# first test to see if "not found"
if len(driver.find_elements_by_xpath("//*[text()='Not Found']"))>0:
logoff_elem = driver.find_element_by_xpath("//*[contains(text(), 'Log off')]")
logoff_elem.click()
driver.quit()
return False
else:
#grab table needed
WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH,'/html/body/div/div/div[2]/div[2]/table/tbody')))
table_html = get_element('/html/body/div/div/div[2]/div[2]/table/tbody', driver)
driver.quit()
record_source_code('results_cache.html', table_html)
return True
except:
drier.quit() #<-- Try/catch and close it
I used Selenium to navigate to a URL (i.e. URL_1) with a login/password and provided the login credentials. I'm logged in and the URL (i.e. URL_2) has changed as expected. I don't know how to navigate URL_2 because the driver still refers to URL_1.
Thanks in advance.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
user_name = 'xyz'
password = 'xyz'
def login_process():
driver = webdriver.Firefox()
driver.get("URL_1")
#successfully navigated to URL_1
elem = driver.find_element_by_name("username")
elem.clear()
elem.send_keys(user_name)
elem = driver.find_element_by_name("password")
elem.clear()
elem.send_keys(password)
driver.find_element_by_id("submit").click()
#successfully entered URL_2
def query():
HOW DO I CHANGE THE DRIVER TO URL_2?
#elem = driver.find_element_by_class_name(ticker_box) #this doesn't work, references URL_1 driver
#elem.clear()
#elem.send_keys('xyz')
Instead of having independent functions, create a class with driver instance as an instance variable. Then, use self.driver.get() to navigate to a different URL:
class MyTest(object):
def __init__(self):
self.driver = webdriver.Firefox()
def login_process(self):
self.driver.get("URL_1")
#successfully navigated to URL_1
elem = self.driver.find_element_by_name("username")
elem.clear()
elem.send_keys(user_name)
elem = self.driver.find_element_by_name("password")
elem.clear()
elem.send_keys(password)
self.driver.find_element_by_id("submit").click()
#successfully entered URL_2
def query(self):
self.driver.get("URL2")
# do smth
test = MyTest()
test.login_process()
test.query()
After navigating to the new page if you want to do something on that new page
newURl = driver.window_handles[0]
driver.switch_to.window(newURl)
After doing this you can do something in the new url without getting "no such element exceptions"
First you can assign the url variable as a global:
global url;
url = "firstURL"
At the end of your first function you can change the value of the variable to the new URL:
url = driver.current_url
And then you can get the new url at the beginning of your second function:
driver.get(url)