I'm trying to build a script, that can click on the Facebook group category "join" button, when certain conditions are met.
The script is already able to navigate "https://www.facebook.com/search/groups/?q=nature_lover" path using selenium.
Image: https://i.stack.imgur.com/3QJhy.png
After navigating to that path I used this code to handle, each group component data.
all_group_elements = self.driver.find_elements(By.CSS_SELECTOR, "div[role=article]")
for group_element in group_elements:
group_name = str(element.text.split('\n')[0])
group_button = str(element.text.split('\n')[-1])
if group_button=="Join":
group_button_target = f"Join Group {group_name}"
if group_button=="Follow Group":
group_button_target = f"Follow Group {group_name}"
# I used this code to target and click the "join" button.
self.driver.find_element(By.CSS_SELECTOR, f"div[aria-label={group_button_target}]").click()
I'm also using "WebDriverWait" in the script. What is the issue here?
Your issue is with f"div[aria-label={group_button_target}]"
That translates to something like "div[aria-label=Join Group NAME]"
That's a problem, because the value of the attribute contains spaces and you need quotes around the value if there are spaces.
Eg:
Bad: 'TAG[ATTRIBUTE=SOME VALUE]'
Good: 'TAG[ATTRIBUTE="SOME VALUE"]'
Those quotes are important if the value contains spaces. You may want to change that line to:
self.driver.find_element(By.CSS_SELECTOR, f'div[aria-label="{group_button_target}"]').click()
Related
So I'm trying to build a tool to transfer tickets that I sell. A sale comes into my POS, I do an API call for the section, row, and seat numbers ordered (as well as other information obviously). Using the section, row, and seat number, I want to plug those values into a contains (text) statement to in order to find and select the right tickets on the host site.
Here is a sample of how the tickets are laid out:
And here is a screenshot (sorry if this is inconvenient) of the DOM related to one of the rows above:
Given this, how should I structure my contains(text) statement so that it is able to find and select the correct seats? I am very new/inexperienced with automation. I messed around with it a few months ago with some success and have managed to get a tool that gets me right up to selecting the seats but the "div" path confuses me when it comes to searching for text that is tied to other text.
I tried the following structure:
for i in range(int(lowseat), int(highseat)):
web.find_element_by_xpath('//*[contains (text(), "'+section+'")]/following-sibling::[contains text(), "'+row+'")]/following-sibling::[contains text(), "'+str(i)+'")]').click()
to no avail. Can someone help me explain how to structure these statements correctly so that it searches for section, row, and seat number correctly?
Thanks!
Also, if needed, here is a screenshot with more context of the button (in cases its needed). Button is highlighted in sky blue:
you can't use text() for that because it's in nested elements. You probably want to map all these into dicts and select with filter.
Update
Here's an idea for a lazy way to do this (untested):
button = driver.execute_script('''
return [...document.querySelectorAll('button')].find(b => {
return b.innerText.match(/Section 107\b.*Row P.*Seat 10\b/)
})
''')
I have the following table set up using flask-table
class ScreeningTable(Table):
timedate = DatetimeCol('Date & Time', datetime_format='YYYY-MM-d, HH:MM')
tickets = Col('Tickets available')
I want to add a ButtonCol using a screeningID variable, where every button has the same text, but sends the user to a link based on the value of screeningID for each line of the table. How do I do that?
This is the line I came up with:
screeningID = ButtonCol("Buy Tickets", "purchase", url_kwargs=dict(id='screeningID'))
To clarify, the first variable is the title of the header, which will also be the text on the button. The second one is the endpoint, and the third is the keyword argument, what gets pass over as part of the URL.
The same rules apply with LinkCols, as they were written to work identically.
Ok, so I get two errors whenever I try to run this script: but before I get ahead of myself: lets get to my objective.
create two joint chains, names are unimportant: but essentially I know that you can use brackets to list and isolate joint chains with matching children names. Instead my script seems to be ignoring the brackets and giving me the error anyways. I've tried every different flag for list relatives: but all that seems to do is change the error to something else.
I know that if this script was properly working it would only work on one joint chain because of the hardcoded names: but the script I'm pulling it from has name prefexes tied to the GUI to avoid hardcoding and allow adaptive naming: I'm only using the hardcoded as an example for this script. My complaint is this script doesn't work on ANY joint chain because I keep getting the error "more than one object matches name."
To run the script,save the following code as a .py in your maya documents script folder, restart your copy of maya, then open a new python tab and run the first three lines of code above import maya.cmds
'''
import exampleScriptTemplate
reload (exampleScriptTemplate)
exampleScriptTemplate.gui()
'''
import maya.cmds as cmds
if cmds.window("buildWin", exists =True):
cmds.deleteUI("buildWin", window = True)
myWindow = cmds.window("buildWin",t='DS_pvFinder',rtf=1,w=100, h=100, toolbox=True)
column = cmds.columnLayout(adj=True)
def gui(*args):
cmds.columnLayout()
cmds.button(w=300,label='build placement curve',c=printMultiple)
cmds.showWindow(myWindow)
def printMultiple(*args):
root = cmds.ls(sl=True)[0]
child = cmds.listRelatives(root,ad=1,f=True,children=True,type='joint')
child.append(root)
child.reverse()
limbJnt = child
print (child)
armroot = []
for j in limbJnt:
wstJnt = cmds.rename(child[3], 'wrist_BIND')
elbJnt = cmds.rename(child[2], 'elbow_BIND')
sdrJnt = cmds.rename(child[1], 'shoulder_BIND')
clvJnt = cmds.rename(child[0], 'clavicle_BIND')
armroot.append(j)
return armroot
I know I'm in the right ballpark. I just need to know how to properly use the brackets to store the list of what i'm selecting instead of searching all of worldspace and breaking.
Thank you for your help
The code you provided is incomplete, no window is opening, so I tried only the printMultiple function which causes a Error: No object matches name in my case.
Your code cannot work like this since you mix hardcoded names with a loop which does nothing. I suppose your main problem is the order of your renamings. The child array contains absolute names like:
[u'joint1', u'|joint1|joint2', u'|joint1|joint2|joint3']
If you now rename child[0] to 'clavicle_BIND', all the remaining elements in the list become invalid because their real names in the scene now look like this:
[u'clavicle_BIND', u'|clavicle_BIND|joint2', u'|clavicle_BIND|joint2|joint3']
What results in an error at the second rename line. Inverting the order sovles this problem, first rename the leaf node, then the ones above.
I'm new in python, web driver in particular and I'm trying to find a text-box - the source code looks like this :
I've tried this :
box = driver.find_element_by_class_name('_3F6QL._2WovP')
though no success.
I'll be happy to add more information if needed - as I said I'm new here. appreciate the help
The problem you have, I think, is that the class is compound - comprises of two classes: _3F6QL and _2WovP.
Selenium doesn't allow for finding elements by a compound class name.
Try this:
box = driver.find_element_by_xpath("//*[contains(#class, '_3F6QL') and contains(#class, '_2WovP')]")
or:
box = driver.find_element_by_xpath("//*[contains(#class, '_3F6QL') and contains(#tabindex, '-1')]")
(Not sure about the latter, though).
Also this should work:
box = driver.find_element_by_xpath("//*[contains(#class, '_1Plpp')]/div")
I'm experimenting with wxPython,
I have a tabbed interface (notebook) and each tab is basically a file list view (yes, I'm trying to make a file manager)
The file list inherits from wx.ListCtrl, and the tabbed interface inherits from wx.Notebook
I'm just starting .. and I had it so double clicking on a folder will cd into that folder, but I want to also change the title of the tab.
How do I do that?
I have the object that represents the file list and the title I want to set it to,
[ EDIT Notebook.SetPageText() takes a number, so I can't pass the tab object directly to it ]
my current approach is to cycle through the tabs until one of them matches my tab:
for tab_id in range(self.GetPageCount()):
if self.GetPage(tab_id) == tab:
self.SetPageText(tab_id, title)
break
This seems rather naive though, isn't there a smarter approach?
I don't know wxPython, but I assume it wraps all the methods of the C++ classes.
There is wxNotebook::GetSelection() which returns wxNOT_FOUND or the index of the selected page, which can then be used to call wxNotebook::SetPageText().
Or use wxNotebook::GetPage() with this index to check whether it is equal to tab.
I think doing something like this helps :
notebook.get_tab_label(notebook.get_nth_page(your_page_number)).set_text("Your text")
If you want to have a reference to the current tab always, you must connect the "switch-page" signal, and save the page in a variable.
As .GetPage returns a wx.Window, I think tab.Label = title should work.