python selenium find_elements incorrect output - python-3.x

I am new to python+selenium. I am trying to return some stuff with find_elements* functions - see code below. When I ask on length of the list, I can see that the number of items is correct, however when I print the content of elements I can see that each element contains the same values and it should contains different values.
elems = browser.find_elements_by_xpath("//div[#class='some_class_name')]")
print(len(elems)) # returns correct number of items
for elem in elems:
print(elem.find_element_by_xpath("//span[#class='another_class_name']").text)
print(elem.find_element_by_xpath("//div[starts-with(#href, 'https://some_web_page_name.com/')]").get_attribute(
'data'))
print(elem.find_element_by_xpath("//div[#class='other_class_name']").text)

You should use . to reduce the scope of xpath to the current element children/grandchildren. In your case, the XPath is pointing to the first element on the page rather finding under the current elem
change code as show below
for elem in elems:
print(elem.find_element_by_xpath(".//span[#class='another_class_name']").text)
print(elem.find_element_by_xpath(".//div[starts-with(#href, 'https://some_web_page_name.com/')]").get_attribute(
'data'))
print(elem.find_element_by_xpath(".//div[#class='other_class_name']").text)

While looping or using find_element inside anther selector you have to add "." inside selector otherwise it will print same element multiple times
first_element = browser.find_elements_by_xpath("//div[#class='some_class_name')]")[0].find_element_by_xpath(".//span[#class='another_class_name']").text
In your case use following code
elems = browser.find_elements_by_xpath("//div[#class='some_class_name')]")
print(len(elems)) # returns correct number of items
for elem in elems:
print(elem.find_element_by_xpath(".//span[#class='another_class_name']").text)
print(elem.find_element_by_xpath(".//div[starts-with(#href, 'https://some_web_page_name.com/')]").get_attribute('data'))
print(elem.find_element_by_xpath(".//div[#class='other_class_name']").text)

Related

Python remove word from bigram in list without returning a new list

Just quick side question. Is there a way and if, how to remove/delete a specific word from a bigram in a list (must be the same list!) that also contains just words. E.g.
In:
x = ['Peter Parker', 'Hugo', 'Fischerman']
Task, delete Parker from that same list:
Expected output:
x as ['Peter', 'Hugo', 'Fischerman']
I tried to use xx = [x.replace('Parker, '') for x in xx]but it seems to give me a new list in the sack.
Any ideas?
list = ['Peter Parker', 'Hugo', 'Fischerman'] # initialize list
for item in range(len(list)): # loop
list[item] = list[item].replace("Parker", "").strip() # replace item nu=umber "item" with its fixed result, replacing "Parker" with nothing and stripping - this just does nothing if "Parker" is not in item number "item".
That should work, just omit the list initialization to add it wherever (and don't forget to fix the variable names!)

Remove sublist from DEEP nestedlist

I'm struggling with some NESTED LISTS.
Briefly, inside the list of lists I have some lists containing several value
biglist = [[['strings', '632'], ['otherstrings', 'hey']],[['blabla', '924'], ['histring', 'hello']]]
from this nested list, I'd like to remove the sublist in which 'hello' string appears.
I tried this:
for sub_line in big_list:
if 'hello' in sub_line:
big_list.remove(sub_line)
Now, if I print the new big_list outside the loop, I get the old list since I didn't assign the updated list to a new list. But if I assign to a new list like:
for sub_line in big_list:
if 'hello' in sub_line:
updated_list = big_list.remove(sub_line)
print(updated_list)
I get an AttributeError: 'NoneType' object has no attribute 'remove'.
So what's the problem with this?
I CANNOT use list indexing because my real list is huge and the target value is not always in the same place.
I've already check other questions but nothing is working.
Thank you all!
if you constantly have two levels of nesting (not what I would label DEEP), you could combine this answer from the dupe marking by #pault with list flattening:
biglist = [[['strings', '632'], ['otherstrings', 'hey']],[['blabla', '924'], ['histring', 'hello']]]
token = 'hello'
smalllist = [x for x in biglist if not token in [j for i in x for j in i]]
# smalllist
# Out[17]: [[['strings', '632'], ['otherstrings', 'hey']]]
Following works for me. You need to remove sub_line (not line) form the list.
big_list = [['strings', '632', 'otherstrings', 'hey'],['blabla', '924', 'histring', 'hello']]
print(big_list)
for sub_line in big_list:
if 'hello' in sub_line:
big_list.remove(sub_line)
print(big_list)
for sublist in biglist:
if 'hello' in sublist:
updated_list=biglist.remove(sublist)
print(updated_list)
The output of the above code is None because remove() does not return any value i.e, it returns None. So you should not assign return value of remove() in a list.
I think that might cause some problems whenever you will use updated_list.

Function to iterate through a nested list and append other lists isn't functioning properly

I am currently trying to write a function to iterate through a nested list and check if one item from the list, 'team', is already in a separate list 'teams'.
If it is not, I want to append a nested list, 'player_values' with a different item from the original nested list that was examined, in the form of a new list in the nested list.
If it is, I want to append the nested list 'player_values' with the item from the original nested list, but I want to add it to the most recent list in the nested list 'player_values' instead of creating a new list.
Currently, my code looks like this :
def teams_and_games(list, player, idx):
teams = []
player_values = []
x = 0
y = -1
for rows in list:
if player == list[x][BD.player_id] and list[x][BD.team] not in teams:
teams.append(list[x][BD.team])
player_values.append([list[x][idx]])
x += 1
y += 1
elif player == list[x][BD.player_id]:
player_values[y].append(list[x][idx])
x += 1
return player_values, teams
However, when I run the code in my main, using
values, teams = teams_and_games(NiceRow, name, BD.games)
print(values)
print(teams)
It only prints empty lists. The fact that it prints empty lists shows that it is returning the correct variables, but I can't figure out why the code in the function is failing to add anything to the lists. I have tried switching the .append with a more simple list += statement, but the result has been the same so far.
Ideally, I would be getting a nested list, containing an amount of lists equal to the number of items added to the other 'teams' list, and the list of teams in the order they were added.
The data I am working with is a nested list pulled from a .csv file, which has been formatted slightly using the .strip() and .split() commands. Each number has been converted to an int, and strings left as they are. The .CSV file it is from has 19 columns and ~80,000 rows, with each column always being either a string or an int.

Find a specific item from a list using python

I have a list of 20000 Products with their Description
This shows the variety of the products
I want to be able to write a code that searches a particular word say 'TAPA'
and give a output of all the TAPAs
I found this Find a specific word from a list in python , but it uses startswith which finds only the first item for example:
new = [x for x in df1['A'] if x.startswith('00320')]
## output ['00320671-01 Guide rail 25N/1660', '00320165S02 - Miniature rolling table']
How shall i find for the second letter, third or any other item
P.S- the list consists of strings, integers, floats
You can use string.find(substring) for this purpose. So in your case this should work:
new = [x for x in df1['A'] if x.find('00320') != -1]
The find() method returns the lowest index of the substring found else returns -1.
To know more about usage of find() refer to Geeksforgeeks.com - Python String | find()
Edit 1:
As suggested by #Thierry in comments, a cleaner way to do this is:
new = [x for x in df1['A'] if '00320' in x]
You can use the built-in functions of Pandas to find partial string matches and generate lists:
new = df1['A'][df1['A'].astype(str).str.contains('00320')]['A'].tolist()
An advantage of pandas str.contains() is that the use of regex is possible.

Python add a single string to a list

I have the following Problem:
I have a list of items, in which the first Word represents the type of something e. .g:
Wall DXU76542
Table Uxitr
Wall rT4
Mobile Tr2
.
.
.
I would like to create another list analogous to this list, extract the single letters at the beginning of every row and add them to the corresponding row of the second list until the space letter " " appears. Thus I can create a second list out of the first list with only types of the items. Here is part of the code in Python (the list: "elements" is a flat list):
for Element in elements:
list1.Add(Element.Name)
list2=[]
list2.append([])
for i in xrange(0,len(list1)):
for j in xrange(0,len(list1[i])):
l=0
while not (list1[i][l]==" "):
list2[i][j].append(list1[i][l])
l = l+1
Output=list2
Does anybody have any idea, why I get the error:
AttributeError: 'str' object has no attribute 'append'
Thank you.

Resources