Trying to read data from Kaspersky website with MechanicalSoup or Selenium - python

Currently, I'm trying to scrape data from a Website (https://account.kaspersky.com/). Before I can read the data I need to login to the website.
But for some reason, it is not working. I read through the internet to get it to work, but unfortunately, I wasn't able to solve the issue.
import mechanicalsoup
import csv
import xlsxwriter
from time import sleep
# create stateful browser
browser = mechanicalsoup.StatefulBrowser(
soup_config={'features': 'lxml'},
raise_on_404=True,
user_agent='MyBot/0.1: mysite.example.com/bot_info',
)
# use browser to open link
browser.open("https://account.kaspersky.com/")
sleep(2)
# check url
print(browser.get_url())
# get first form available
form = browser.select_form()
browser.submit()
# check url
print(browser.get_url())
The script always ends at the selct_form() method. No matter what I try I always get the same error. Even when I specify it.
Traceback (most recent call last):
File "c:\Python\Cloud.Kaspersky\read_from_website_mechanicalsoup.py", line 23, in <module>
form = browser.select_form()
File "C:\Users\dw.FROMMEDV\AppData\Local\Programs\Python\Python39\lib\site-packages\
mechanicalsoup\stateful_browser.py", line 220, in select_form
raise LinkNotFoundError()
mechanicalsoup.utils.LinkNotFoundError
After a few hours of trying, I wanted to try a different tool. Selenium. But I have kind of the same problem here as well. But here I can't submit the login. Selenium can't find the button.
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get("https://account.kaspersky.com/")
file = open('login.txt', 'r')
username_file = file.readline()
password_file = file.readline()
time.sleep(1)
username = driver.find_element_by_id("EMail")
username.clear()
username.send_keys(username_file)
time.sleep(1)
password = driver.find_element_by_name("Password")
password.clear()
password.send_keys(password_file)
time.sleep(2)
driver.find_element_by_class_name("assets-button primary").click()
Is it possible that this website is protected or something? Or is anyone seeing my issue?
Here the Error Message with Selenium:
Traceback (most recent call last):
File "c:\Python\Cloud.Kaspersky\read_from_website_selenium.py", line 26,
in
<module>
driver.find_element_by_class_name("assets-button primary").click()
File "C:\Users\dw.FROMMEDV\AppData\Local\Programs\Python\Python39
\lib\site-
packages\selenium\webdriver\remote\webdriver.py", line 564, in
find_element_by_class_name
return self.find_element(by=By.CLASS_NAME, value=name)
File "C:\Users\dw.FROMMEDV\AppData\Local\Programs\Python\Python39
\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 976, in
find_element
return self.execute(Command.FIND_ELEMENT, {
File "C:\Users\dw.FROMMEDV\AppData\Local\Programs\Python\Python39
\lib\site-
packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Users\dw.FROMMEDV\AppData\Local\Programs\Python\Python39
\lib\site-
packages\selenium\webdriver\remote\errorhandler.py", line 242, in
check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to
locate
element: .assets-button primary

Try using the following identifiers. The last line is the error using Java instead of Python and multiple class names instead of singular.
driver.find_element_by_class_name("assets-button").click()
driver.find_element_by_xpath("//button[#class='assets-button primary']").click()
You could also try
from selenium.webdriver.common.keys import Keys
password.send_keys(Keys.ENTER)

Related

Updating facebook post using Selenium: error- element not found but i can find in my browser

i am trying to post on facebook wall using selenium in python. I am able to login but after login it cant find class name of status box which i copied from browser
here is my code-
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
user_name = "email"
password = "password"
msg = "hi i am new here"
driver = webdriver.Firefox()
driver.get("https://www.facebook.com")
element = driver.find_element_by_id("email")
element.send_keys(user_name)
element = driver.find_element_by_id("pass")
element.send_keys(password)
element.send_keys(Keys.RETURN)
time.sleep(5)
post_box = driver.find_element_by_class_name("a8c37x1j ni8dbmo4 stjgntxs l9j0dhe7")
post_box.click()
time.sleep(5)
post_box.send_keys(msg)
the snapshot of code i copied from browser is attached as image here
here is error i recived-
Traceback (most recent call last):
File "C:/Users/rosha/Desktop/facebook bot.py", line 17, in <module>
post_box = driver.find_element_by_class_name("a8c37x1j ni8dbmo4 stjgntxs l9j0dhe7")
File "C:\ProgramData\Anaconda3\envs\facebook bot.py\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 564, in find_element_by_class_name
return self.find_element(by=By.CLASS_NAME, value=name)
File "C:\ProgramData\Anaconda3\envs\facebook bot.py\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 976, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "C:\ProgramData\Anaconda3\envs\facebook bot.py\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\ProgramData\Anaconda3\envs\facebook bot.py\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: .a8c37x1j ni8dbmo4 stjgntxs l9j0dhe7
try to find element by Xpath for example:
driver.find_element(By.XPATH, '//button[text()="Some text"]')
to find the xpath from the browser, just right click on something in the webpage and press inspect after that right click, a menu will appear, navigate to copy then another menu will appear, press copy fullpath.
check this https://selenium-python.readthedocs.io/locating-elements.html
The problem is that driver.find_element_by_class_name() can be used for one class, and not multiple classes as you have: a8c37x1j ni8dbmo4 stjgntxs l9j0dhe7 which are multiple classes separated by spaces.
Refer to the solution suggested here, it suggests using find_elements_by_xpath or find_element_by_css_selector.

unable to find element by id with selenium

I'm trying to automate the sign in for a website and below is the code I used.
from selenium import webdriver
chromedriver = "C:/Lujing/chromedriver.exe"
browser = webdriver.Chrome(chromedriver)
browser.get("https://community-pm.p.cloud.sabrehospitality.com/pms-web-ui/login")
browser.implicitly_wait(10)
userElem = browser.find_element_by_id("spark-input_1")
userElem.send_keys("input user name") #enter user name in the quote
passwordElem = browser.find_element_by_id("spark-input_2")
passwordElem.send_keys("input password") #enter password in the quote
signin = browser.find_element_by_class_name('login-button spark-btn spark-btn--md spark-btn--primary spark-block--lte-sm spark-margin-bottom--md spark-pull-right--gte-sm')
type(signin)
signin.click()
I've also tried to use find_element_by_xpath("//*[#id='spark-input_1']"), but I keep getting below error message.
Traceback (most recent call last):
File "C:\Lujing\Python Scripts\PMS_report_downloads.py", line 9, in <module>
userElem=browser.find_element_by_id("spark-input_1")
File "C:\Users\Lujing.gao\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 360, in find_element_by_id
return self.find_element(by=By.ID, value=id_)
File "C:\Users\Lujing.gao\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 976, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "C:\Users\Lujing.gao\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Users\Lujing.gao\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="spark-input_1"]"}
(Session info: chrome=80.0.3987.163)
Here is a screenshot of the source codes in the webpage
Could anyone help me with this?
The following is a working solution to enter values for the username field. You can figure out how to do the password field and the submit button. Note I had issues with geckodriver. I am not sure if it works for you, but it works with Chromedriver for me.
As I mentioned in my comment to your post, the reason you cannot find the element is because of the shadowDOM. You can use some javascript to get passed that. Note in future pages of the website, you may run into a nested shadowDOM which will require a similar solution to below, but recursive.
browser = webdriver.Chrome()
browser.get("https://community-pm.p.cloud.sabrehospitality.com/pms-web-ui/login")
shadow_root = browser.execute_script('return arguments[0].shadowRoot', browser.find_element_by_tag_name("sabre-shs-login"))
userElem = shadow_root.find_element_by_id('spark-input_1')
userElem.send_keys("input user name") #enter user name in the quote

Attempting to select a field for username and password using Selenium in Python

I'm trying to figure out how to select an ID in a website that has a username and password using selenium so that I can login using a python script. The problem is the fields on the website don't seem to have IDs for their username and password fields in the HTML code and I'm not really sure as to how to get the fields I need.
from selenium import webdriver
import time
#from selenium.webdriver.common.keys import Keys
link = "https://logistics.vendini.com/"
login = "e-mail"
password = "pass"
chromedriver = "D:\Downloads\chromedriver"
driver = webdriver.Chrome(chromedriver)
driver.get(link)
username = driver.find_element_by_class_name('form-control')
print(username)
I tried this just to see if finding it by class would work but all I get is the webpage opening and then I get this error
DevTools listening on ws://127.0.0.1:64343/devtools/browser/8a74989c-0f07-442c-ba50-077d3ec005bc
Traceback (most recent call last):
File "d:/marko/Programming/RavensHouseCup/webscrape.py", line 13, in <module>
username = driver.find_element_by_class_name('form-control')
File "D:\Program Files (x86)\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 564, in find_element_by_class_name
return self.find_element(by=By.CLASS_NAME, value=name)
File "D:\Program Files (x86)\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 976, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "D:\Program Files (x86)\Python\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "D:\Program Files (x86)\Python\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".form-control"}
(Session info: chrome=79.0.3945.88)
If you go to the website that is in the link variable and inspect the email address and password fields is there something I'm missing as to how I'd be able to access them?
So I added an explicit wait of 10 seconds which seems to allow me to input the email, but for some reason the password isn't working. The code I'm using is as follows
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "/html/body/div/div/div/div/div/form/div[1]/input"))
)
username = driver.find_element_by_xpath("/html/body/div/div/div/div/div/form/div[1]/input")
password = driver.find_element_by_xpath("/html/body/div/div/div/div/div/form/div[2]/input")
username.send_keys(login)
password.send_keys(password)
The e-mail gets entered correctly, but the password is giving me an error saying
File "d:/marko/Programming/RavensHouseCup/webscrape.py", line 24, in <module>
password.send_keys(password)
File "D:\Program Files (x86)\Python\lib\site-packages\selenium\webdriver\remote\webelement.py", line 478, in send_keys
{'text': "".join(keys_to_typing(value)),
File "D:\Program Files (x86)\Python\lib\site-packages\selenium\webdriver\common\utils.py", line 150, in keys_to_typing
for i in range(len(val)):
TypeError: object of type 'WebElement' has no len()
When the page first loads the element is not present, there appears to be some JS that loads the form. You need to wait for the element to be present
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
username = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'form-control')))
print(username)
I am the stupidest coder alive. I realized my mistake, I had 2 different variables both named password, sorry everyone, I'm a moron. I changed the actual password to the website to be password2 and it all works!

Python, Variables in 2 files and selenium

I’ve created the main.py and the login.py, then I tried to link the 2 files together. I don’t know how to correctly link these 2 files.
I’m using selenium and the program works, but it opens 2 chrome windows (When I want to open just one) then, the second one goes ahead and works perfectly but when it stops to do the login file suddently this error comes:
Traceback (most recent call last):
File "C:/Users/alebu/PycharmProjects/selenium/Main.py", line 9, in <module>
Login.login()
File "C:\Users\alebu\PycharmProjects\selenium\Login.py", line 6, in login
Main.browser.find_element_by_link_text('Log in').click()
File "C:\Users\alebu\PycharmProjects\selenium\venv\lib\site-
packages\selenium\webdriver\remote\webdriver.py", line 419, in
find_element_by_link_text
return self.find_element(by=By.LINK_TEXT, value=link_text)
File "C:\Users\alebu\PycharmProjects\selenium\venv\lib\site-
packages\selenium\webdriver\remote\webdriver.py", line 955, in find_element
'value': value})['value']
File "C:\Users\alebu\PycharmProjects\selenium\venv\lib\site-
packages\selenium\webdriver\remote\webdriver.py", line 312, in execute
self.error_handler.check_response(response)
File "C:\Users\alebu\PycharmProjects\selenium\venv\lib\site-
packages\selenium\webdriver\remote\errorhandler.py", line 242, in
check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element:
Unable to locate element: {"method":"link text","selector":"Log in"}
(Session info: chrome=64.0.3282.167)
(Driver info: chromedriver=2.35.528161
(5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 10.0.16299
x86_64)
Process finished with exit code 1
probably I’ve done something wrong with the variables
the main.py
from selenium import webdriver
import Login
driver_location = "C:\webDrivers\chromedriver.exe"
options = webdriver.ChromeOptions()
options.add_argument('--lang=en')
browser = webdriver.Chrome(executable_path=driver_location,
chrome_options=options)
Login.login()
the login.py
def login():
import Main
from time import sleep
Main.browser.get('https://www.instagram.com')
Main.browser.find_element_by_link_text('Log in').click()
Main.browser.find_element_by_name('username').send_keys('*******')
Main.browser.find_element_by_name('password').send_keys(********')
Main.browser.find_element_by_xpath('//form/span/button[text()="Log
in"]').click()
sleep(3)
Main.browser.find_element_by_link_text('Not Now').click()
sleep(2)
print("Logged In")
The weird thing is: before the program was in one unique file and it worked perfectly.
I would suggest you read some material on how import works in python here.
to get what you have working properly quickly, you should not import Main in your login function. Try passing the driver as an argument in your login function as so (Note: after passing the browser as an argument and not importing Main, you will no longer need to use Main.browser, just browser):
from time import sleep
def login(browser):
browser.get('https://www.instagram.com')
Then when you go to call login from your main, you will want to pass browser as an argument:
Login.login(browser)
This should fix the problem you were having with two browsers opening. If the issue is still occurring with the Log in link not found please read this and ask a new question if you have a clear understanding of how it works and require more help.

How can I find object with Selenium?

Thats my code, I was changing, fixing, trying another modules, but still can not get a respond with my div text extracted.
import selenium
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://www.helloworld.com/')
element = driver.find_element_by_id('main')
WebElement = driver.findElement(By.xpath("//div[#class='main']"));
webElement.getText();
I was trying with bs4 package but there is a big problem, becouse the data what i want is possible to get only when i am loged in on the website, and in bs4 respond was like from guest account, without login in.
Here is a Traceback what i got usint that code with Selenium:
Traceback (most recent call last):
File "D:/Python27/get text value div.py", line 8, in <module>
WebElement = driver.findElement(By.xpath("//div[#class='main']"));
AttributeError: 'WebDriver' object has no attribute 'findElement'
Aftter a small fix, I am using this:
import selenium
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://www.helloworld.com/')
element = driver.find_element_by_id('main')
main_text = element.text
The respond after print element.text in shell is:
Traceback (most recent call last):
File "<pyshell#20>", line 1, in <module>
element.text
File "D:\Python27\lib\selenium\webdriver\remote\webelement.py", line 50, in text
return self._execute(Command.GET_ELEMENT_TEXT)['value']
File "D:\Python27\lib\selenium\webdriver\remote\webelement.py", line 228, in _execute
return self._parent.execute(command, params)
File "D:\Python27\lib\selenium\webdriver\remote\webdriver.py", line 165, in execute
self.error_handler.check_response(response)
File "D:\Python27\lib\selenium\webdriver\remote\errorhandler.py", line 152, in check_response
raise exception_class(message, screen, stacktrace)
WebDriverException: Message: u'\'[JavaScript Error: "a is null" {file: "file:///c:/dokume~1/tomek/lokale%20einstellungen/temp/tmpupvgr2/extensions/fxdriver#googlecode.com/components/command_processor.js" line: 7623}]\' when calling method: [nsICommandProcessor::execute]'
Where did you get the following from? Looks like Java to me.
WebElement = driver.findElement(By.xpath("//div[#class='main']"));
webElement.getText();
Try:
import selenium
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://www.helloworld.com/')
element = driver.find_element_by_id('main')
print element.text #There's no text under div main, what would you expect?
footer = driver.find_element_by_id('footer')
print footer.text
# Should print out "Copyright ©2013 helloworld.com. All Rights Reserved. About Us | Privacy Policy "
If the information you want is inside a div with an id of botloc then you need to grab that element.
import selenium
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://www.helloworld.com/')
bot_location = driver.find_element_by_id('botloc').text
print bot_location

Categories

Resources