Python Selenium Detection Error? - python

Hi i've been trying to learn selenium.
The problem i am having is that an element isn't being detected. The html code i am working with is highlighted right here https://gyazo.com/a76608d4c4e9fc3bd29412436604c173. That line of code stopped my program and gave me the error https://gyazo.com/72fc72e6488578c9c2a50b71311602c5.
The code i am using to detect for the textarea class is
comment=driver.find_element_by_xpath("//form[#class='comment-form no-border-top']/div/*[1]") or driver.find_element_by_xpath("//form[#class='comment-form']/div/*[1]")
because sometimes it switches between comment-form no border and comment form.
My idea is to use a conditional assignment operator check for example if(comment!=none): do something, but to my understanding python doesn't allow this.
any suggestions on what to do and whether my xpath is a reliable method?

If the problem you're trying to solve is actually conditional assignment, there are two different things you might want to know.
The first is that you can do:
if(comment!=none)
you just have to do it like this:
comment = Foo()
if comment is None:
comment = Bar()
Second, maybe you want to try assigning comment if the first call throws an error rather than just being None. If so, try using try!
from selenium.common.exceptions import NoSuchElementException
try:
comment = driver.find_element_by_xpath("//form[#class='comment-form no-border-top']/div/*[1]")
except NoSuchElementException:
comment = driver.find_element_by_xpath("//form[#class='comment-form']/div/*[1]")

Related

How to force a test to fail with selenium and python?

I was searching for a way to do this a lot of times but I didn't find any solution.
I'll show you what I mean:
def test_288_try_this(self):
try:
do_something()
except NoSuchElementException:
self.assertTrue(False, "This test fails bigger than you.")
I'm doing it that way, Of course is working buy I feel is not the correct way. I'd like to know if there is any kind of "self.assertFail(fail_message)" or some like that.
Thanks!
Python:
If you want to verify whether the particular web element is present on a page after navigation. You can use the below method.
self.assertTrue(element, msg='Element name is not present after naviagting to x page')

Python keyword pass causing syntax errors, is this a bug in the language?

I was working with this KDE widget and was having hard time trying to access it with python, I figured out with some help that I was trying to do it right originally and if I patch the 2 files below in the widget to change the name from pass to say pypass or just add a copy of this pass feature under a new name I can use the new name no problem, is this a false positive in the syntax check or just a usage issue? is there a way to work around this issue?
plugin/DBusService.cpp (line 6: void DBusService::pass(QString data) {)
plugin/DBusService.hpp (line 16: void pass(QString data);)
These give a syntax error cause of the word pass
#!/bin/python3
from pydbus import SessionBus
diy=SessionBus().get("org.kde.plasma.doityourselfbar","/id_10")
diy.pass('|A|Label|Tooltip|notify-send hello world|')
#!/bin/python3
from dbus import SessionBus
diy=SessionBus().get_object("org.kde.plasma.doityourselfbar","/id_10")
diy.pass('|A|Label|Tooltip|notify-send hello world|')
I did try to set it like this but I just get a Key Error, so much for it behaving like JavaScript...
diy['pass]('string')
No, it's not "a bug in the language", you just can't do that, because pass is a language keyword. I don't know if pydbus provides a nice way for calling a method by name, bypassing its proxies, but if it doesn't, you should be able to do
getattr(diy, 'pass')('string')

Why is try: except: not working for this particular line of code with python Wikipedia API?

i am trying to execute this very short code that took out from my bigger code because i was having problems with it. I was able to reproduce the problem (it gave the exact same error).
BACKGROUND INFO: i am just trying to get the first sentence out of this wikipedia search. but because the word i am searching for (kip, means chicken in Dutch) has a wide variety of meanings or something i get an error. i want to bypass this error using try: except: but it keeps displaying the error message anyway.
here is the code that just doesnt seem to work:
import wikipedia
wikipedia.set_lang('nl')
try:
summry = wikipedia.summary('kip', sentences=1)
print(summry + "\n")
except:
print("error")
i have tried replacing except: with this
except wikipedia.exceptions.DisambiguationError:
but it still doesnt work :( it always displays the error code regradless and prints "error" afterwards
/opt/virtualenvs/python3/lib/python3.8/site-packages/wikipedia/wikipedia.py:389:
GuessedAtParserWarning: No parser was explicitly specified, so I'm using the best available HTML
parser for this system ("html5lib"). This usually isn't a problem, but if you run this code on
another system, or in a different virtual environment, it may use a different parser and behave
differently.
The code that caused this warning is on line 389 of the file
/opt/virtualenvs/python3/lib/python3.8/site-packages/wikipedia/wikipedia.py. To get rid of this
warning, pass the additional argument 'features="html5lib"' to the BeautifulSoup constructor.
lis = BeautifulSoup(html).find_all('li')
error
i am using repl.it to program this
if anyone has any idea about why it keeps displaying the error anyway please please let me know :D
First of all, thank you all for commenting :D it helped a lot
At the end the solution that worked for me was inspired from Askold Ilvento's comment
although
with warnings.catch_warnings(): warnings.simplefilter("ignore")
didn't work when i adapted it a little bit it did the job!
this is the code that solved the problem and allowed me to ignore what was actually a warning (not an exception) and stop displaying it
import warnings
warnings.catch_warnings()
warnings.simplefilter("ignore")
i just added this at the start of the script and it solved the problem :D
once again all the credit for this code goes to Askold Ilvento i just had to add a little bit to it to make it work

Selenium and Python using If statement

I am trying understand why an if else isn't working using Selenium and Python. I have tried several different variations, but I believe this should work and stubbornly, maybe blindly, keep coming back to it.
example:
if (self.driver.find_element_by_class_name('product')).text == "FEATURED PRODUCTS":
print "\nHome Pass"
else:
print "\nHome Fail"
Tried this as well
if self.driver.find_element_by_class_name("product-teaser-list").text in "Featured Products":
Each execution returns Fail and when using assert, below, the .text is found. So I know the text is found with this method.
assert "FEATURED PRODUCTS" in self.driver.find_element_by_class_name('product').text
try this following code.
if "FEATURED PRODUCTS" in self.driver.find_element_by_class_name('product').text
If this isn't working try to debug that. something white space creates an issue. however given the assert statement is passing, following should work.

Using conditional imports as a way to utilize different functions with the same namespace

I am a beginner python programmer, and I am working on a selenium project in python 2.7.
I have a generic scraper script, that basically outlines what I want to do with all the websites that I visit. However, because of the nature of the data that I want to grab, I can't run the same code on each site-- each site needs to run it's own individual code.
I have attempted to solve this by importing inside of an if statement, and this is the solution I came up with:
site = False
if source_website == "Website A":
from website_a import *
site = True
elif source_website == "Website B":
from website_b import *
site = True
else:
print "This is not an acceptable website!"
if site == True:
# main code block
driver = driver_setup(chrome)
driver.get(source_website_URL)
stuff_to_save = do_some_stuff(driver)
xml_file(stuff_to_save)
driver.quit()
where the website_a and website_b modules both have functions named do_some_stuff, and they do stuff specific to the website that they're on. Now, this seems to work, for the most part. I also seem to be able to extend functionality to any number of websites, given that I program a module called website_c with the function do_some_stuff, and add that to the conditional import.
So, my question is, is this a good idea? Is there a better way to do something like this?
I have literally never seen anyone wrap import statements inside of if statements like this-- and generally, if no one seems to do it, there's usually a good reason why.
In general, from somewhere import * is not a good idea due to namespace pollution. If you want the website-specific code in separate modules, why not do something like
import importlib
website_modules = {'Website A': 'website_a', 'Website B': 'website_b'}
# ...
website = importlib.import_module(website_modules[source_website])
# use with website.function_name
Explore the page object model pattern (http://code.google.com/p/selenium/wiki/PageObjects). You should model each page as a unique entity, then have some logic that determines what page type you are displaying (either explicitly by having you specify it or implicitly by inspecting the URL and the contents of the page) and then expose the methods to capture the data you need on those objects rather than working directly with the webdriver instance. You should ultimately aim for something like:
for page_identifier in ['page1', 'page2', 'page3']:
page = navigate_to(page_identifier)
extracted_data = page.get_data()
xml_file.write(extracted_data)

Categories

Resources