I'm trying to make an attendance app, using Selenium; the script should read the names and click on a designated checkbox when a name is matched. What happens is that it keeps clicking on the first checkbox repeatedly. When I looked into it turns out that it only reads the first li only.
here's the HTML code
<div class="members">
<ul class="memberlist"></ul>
</div>
the li are generated via fetch API from the database
when I try these in python, it only reads the first li element over and over
for i in range(len(df)):
print(driver.find_element(By.XPATH,".//ul[#class='memberlist']/li/p").text)
for i in range(len(df)):
print(driver.find_element(By.CLASS_NAME,"name").text)
also, I tried the solution from this and I don't think this is the correct syntax
selenium python for loop printing only first element repeatedly
Update: as per dosas comment, this did list all the names instead of just one, then I wrote this to click on the checkboxes of the attendees.
for i in range(len(df)):
# match names of the sheet with the 'name' class in the webpage
if df['name'][i]==driver.find_elements(By.CLASS_NAME,"name")[i].text:
driver.find_elements(By.CLASS_NAME, week)[i].click()
print(driver.find_elements(By.CLASS_NAME,"name")[i].text)
else:
print('No match')
Now I have a different problem, the attendance excel sheet has to be in the same order as the list on the web page, otherwise, it'll show 'No match'. So how do I make it search the whole page for each particular name?
Related
I have logged onto a third party website where I have a page full of URLs to click. I was able to collect the elements as such:
for i in num_alphabets:
names = browser.find_elements(by=By.CLASS_NAME, value='client-name')
print(len(names)) # gives you the number of clients!!!
So now that I have this list called names, I want to know how I can click through all these elements. For now that would be enough, later on I want to have it store some information after clicking. I tried adding .click() at the end and it obviously won't work as names is a list.
Should I maybe create an array with only the first values of the list and then click through that? browser.click() isn't a valid attribute so I don't think that would work.
Here names is the list of WebElements with value as client-name. So to click on each of those WebElements you have to iterate through the list. Incase the page doesn't changes and the client-name sections are on the same page you can use the following code block:
for name in names:
name.click()
I am automating a script that selects a product quantity, but this particular site uses +/- click buttons and has no dropdown or input field for the quantities that are read from CSV.
Rather than emulating button presses of the +/- for the quantities, you can manually edit the HTML below with the desired number and click the add to cart for the same effect.
Is it possible to edit the HTML when there is no form to do so on the site?
Or do I have to emulate clicks for the desired quantity.
I am using Pandas to read the CSV and is working code from another project.
Thank you if you can help
https://www.matsukiyo.co.jp/store/online/p/4902888248269
<ul class="count">
<li>数量</li>
<li class="minus disable">-</li>
<li class="num" id="addToCartQty" data-code="99">1</li>
<li class="plus">+</li>
</ul>
You can change the data-code="99">1</li> from 1 to 99 and it will update but is this possible in Selenium as I cannot find the right selector to do so. I have a feeling this is not possible?
The current code I am trying is sending clicks but I am not able to send the number of clicks I want and am stuck for a solution either way.
How can I send the value from the CSV to dictate the number of clicks?
Or how can I write the value to the li HTML?
driver.get(web_url+str(UPC[i]))
try:
driver.find_element(By.LINK_TEXT, "+").click
# I want to add the number of clicks here(str(quantity[i]))
link = driver.find_element_by_css_selector("p.button.cart")
link.click()
except:
print("Product Number: "+str(UPC[i])+" Sold Out!")
As I can see the element containing the count is located by id='addToCartQty' so what you can do is simply
driver.find_element_by_css_selector('#addToCartQty').sendKeys("your value");
or
driver.find_element_by_css_selector('#addToCartQty').sendKeys("value", "your value");
or
element = driver.find_element_by_css_selector('#addToCartQty')
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].value='enter the value here';", element);
Don't forger to change "your value" or 'enter the value here' with a number you wish to input there.
It is possible to edit the html and execute the script using execute_script() method
script="document.getElementsByClassName('num')[0].value="+your_value+" ;"
driver.execute_script(script)
You can check this by running the script in your browser console,it will induce your required value to the html tag.
I am trying to get specific contents of the second "datadisplaytable" is the Schedule type and Instructors name. The line below:
datadisplaytable = soup.find(class_='datadisplaytable').text
gets me the whole class which contains all other 'datadisplaytable's which I intend to loop through for the specific data that I need.
Using "Xpath" in selenium only gets me the contents of the selected path. and trying to use a for loop in selenium returns "WebElement not iterable'
Which brings me to the question,
How do I get the schedule type and Instructor.
catalog = https://prod-ssb-01.dccc.edu/PROD/bwckschd.p_disp_dyn_sched
term and subject is any.
Use find_elements_by_xpath (‘<your xpath>) not find_element_by_xpath. See the difference one is with s.
Remember find_elements return a list of web elements which you can loop through where as find_element return a single web element.
I am trying to create code that will click multiple links on a webpage that will inturn download files. However, I have written an XPath that contains all the links. When trying to click I get this error: "click() takes 1 positional argument but 2 were given".
Is there any way to click all links in the desired XPath with .click() function in selenium?
This is what I am trying with 10 files:
browser.find_element_by_xpath("//a[starts-with(#href,'sys_attachment.do') and #class='linked formlink']").click('href')
Is there a better way to download all of these with the XPath? Thanks.
You should use find_elements_by instead of element so you can loop over the list of elements, and click on each one, ex:
clickList = browser.find_elements_by_xpath("//a[starts-with(#href,'sys_attachment.do') and #class='linked formlink']")
for count, elem in enumerate(clickList):
# I am refreshing the list in case the DOM is changed
currentList = browser.find_elements_by_xpath("//a[starts-with(#href,'sys_attachment.do') and #class='linked formlink']")
currentList[count].click()
If you want to find many elements then use find_elemenets_... with s in word elements and you get list with many elements. And then you have to use for-loop to use click() (without arguments) on every element separatelly.
all_items = browser.find_elements_by_xpath("//a[starts-with(#href,'sys_attachment.do') and #class='linked formlink']")
for item in all_items:
item.click()
Problem is when click changes page because then items stop exist and you would have to go back, find again all items and click next element on list - but you have to remeber index of previously clicked item.
Using Selenium to perform some webscraping. Have it log in to a site, where an HTML table of data is returned with five values at a time. I'm going to have Selenium scrape a particular bit of data off the table, write to a file, click next, and repeat with the next five.
New automation script. I've a myriad of variations of get_attribute, find_elements_by_class_name, etc. Example:
pnum = prtnames.get_attribute("title")
for x in prtnames:
print('pnum')
Here's the HTML from one of the returned values:
<div class="text-container prtname"><span class="PrtName" title="P011">P011</span></div>
I need to get that "P011" value. Obviously Selenium doesn't have "find_elements_by_title", and there is no HTML id for the value. The Xpath for that line of HTML is:
//*[#id="printerConnectTable"]/tbody/tr[5]/td/table/tbody/tr[1]/td[2]/div/span
But I don't see a reference to "title" or "P011" in that Xpath.
pnum = prtnames.get_attribute("title")
AttributeError: 'list' object has no attribute 'get_attribute'
It's like get_attribute doesn't exist, but there is some (albeit not much) documentation on it.
Fundamentally I'd like to grab that "P011" value and print to console, then I know Selenium is working with the right data.
P.S. I'm self-taught with all of this, I'm automating a sysadmin task.
I think the problem is that prtnames is a list of element, not a specific element. You can use a list comprehension if you want a list of the attributes of titles for the list of prtnames.
pnums = [x.get_attribute('title') for x in prtnames]