How to find the last element in python selenium - python

I'm creating a web scraper for discord after logging in the bot should extract the last sent message in a discord channel and print it out. The last sent message however is dynamic. It always has a different path. It doesn't have an ID either. It only has a class name of embedFooterText-28V_Wb. As you know selenium returns the first element that has that class. In this case, it's the first message ever sent. How can I reverse it so it gets the last message sent? This is what I have written so far:
text = driver.find_element_by_class_name('embedFooterText-28V_Wb').get_attribute('innerHTML')
print(text)
This code returns the first message sent and I'd like to get the last message sent

you can find all of the elements the get last one with:
el1 = driver.find_elements_by_xpath("//*[contains(#class, 'embedFooterText-28V_Wb')]")[-1]
but better to get last one already with xpath functionality

Use (//*[contains(#class,'embedFooterText-28V_Wb')])[last()]
I used Java syntax however in Python it will be quite similar

Related

how to Automate the process of Checking twitter profile have option of sending message or not

i want to check list of certain profile whether it profile has message function or not
so is it possible with selenium with the help python and requests
You can just use try-else to find that element and get value based on this:
try:
button = driver.find_element(...)
send_button = 1
else:
send_button = 0
You can expand this structure to a loop and store values in a nicer way like an array, column...
Be sure to carefully verify if the else statement triggers only when there is no button, e.g. by loading error.

How to use the most recently printed line as an input?

I am trying to create a Twitter bot that posts a random line from a text file. I have gone as far as generating the random lines, which print one at a time, and giving the bot access to my Twitter app, but I can't for the life of me figure out how to use a printed line as a status.
I am using Tweepy. My understanding is that I need to use api.update_status(status=X), but I don't know what X needs to be for the status to match the most recently printed line.
This is the relevant section of what I have so far:
from random import choice
x = 1
while True:
file = open('quotes.txt')
content = file.read()
lines = content.splitlines()
print(choice(lines))
api.update_status(status=(choice(lines)))
time.sleep(3600)
The bot is accessing Twitter no problem. It is currently posting another random quote generated by (choice(lines)), but I'd like it to match what prints immediately before.
I may not fully understand your question, but from the very top, where it says, "How to use the most recently printed line as an input", I think I can answer that. Whenever you use the print() command, store the argument into a string variable that overwrites its last value. Then it saves the last printed value.
Instead of directly printing a choice:
print(choice(lines))
create a new variable and use it in your print() and your api.update_status():
selected_quote = choice(lines)
print(selected_quote)
api.update_status(status=selected_quote)

Click on a specific email from gmail inbox Python

Im trying to get an specific email from a gmail address (or subject).
Im using selenium because can't use imaplib for this gmail account.
Im stck here:
driver.find_element_by_id("identifierId").send_keys('MYEMAIL')
driver.find_element_by_id("identifierNext").click()
time.sleep(5)
driver.find_element_by_name("password").send_keys('PSWRD')
driver.find_element_by_id("passwordNext").click()
time.sleep(15)
email = driver.find_elements_by_css_selector("div.xT>div.y6")
for emailsub in email:
if "someone#gmail.com" in emailsub: #Error line
emailsub.click()
break
Error: argument of type 'WebElement' is not iterable
Idk why I'm using find_elements.
Your for is loop being done correctly and they way you call driver.find_elements_by_css_selector is fine. Inside of your for loop you are dealing with INDIVIDUAL instances of WebElement. The error you get is due to the use of the in statement, I would check this post on using IN in a IF statement and furter understand what you are looking for in your in statement.
I suspect plainly iterating over the WebElement class is throwing this error, and you need to further define what the `in' applies to.

Python Selenium - How to Extract/Exclude specific tags or elements in forum posts?

I have built a web crawler for a forum game in which players use specific keywords in [b] bold [/b] tags to issue their commands. The bot's job is to traverse through the thread and keep a record of all player's commands, however I'm running into a problem where if player A quotes a post from player B, the bot reads the command of player B in the quote and updates the table for player A.
I have found the specific class name of the quote box, but I cannot figure out how to remove the class from the entire post body.
I tried converting the post to text using the get_attribute('innerHTML') and successfully removed it using regex, however the code I wrote to extract the bold tags (find_attribute_by_tag_name) becomes invalid.
I have two questions for the geniuses that post here:
Is there a way I can delete a specific element from the post body? I searched throughout google and could not find a working solution
Otherwise, is there a way I can convert the HTML I get from get_attribute('innerHTML') back to an element?
def ScrapPosts( driver ):
posts=driver.find_elements_by_class_name("postdetails")
print("Total number of posts on this page:", len(posts))
for post in posts:
#print("username:",post.find_element_by_tag_name("Strong").text)
username=post.find_element_by_tag_name("Strong").text.upper()
#remove the quote boxes before sending to check command?
post_txt=post.find_element_by_class_name("content")
CheckCommand(post_txt, username)
Selenium doesn't have a built in method for deleting elements. However, you can execute some javascript code that can remove the quote box elements. See related question at: https://stackoverflow.com/a/22519967/7880461
This code will delete all elements with the class name quoteBox which I think would work for you if you just change the class name.
driver.execute_script('''
var element = document.getElementsByClassName("quoteBox"), index;
for (index = element.length - 1; index >= 0; index--) {
element[index].parentNode.removeChild(element[index]);
}
''')
Same answer- no built in way of doing that but you can use javascript. This approach would probably a lot more complicated than the first one.

Check if send_keys is sending the key?

I am trying to set-up a condition where the script checks whether a web element is present or not. If present, actions.send_keys(Keys.ESCAPE).
if len(str(driver.find_element_by_class_name("blnewform_wrapper"))) >0:
actions.send_keys(Keys.ESCAPE)
print("I sent escape")
else:
print("Didn't find the form")
print(count)
I get an output:
I sent escape
But the form is still in the forefront. When I click escape on the page it exits. So I am just wondering how exactly to check whether the ESCAPE key is being sent or not.
You have not performed the actions, replace:
actions.send_keys(Keys.ESCAPE)
with:
actions.send_keys(Keys.ESCAPE).perform()
As far as making sure it was sent - send_keys() would throw an error if an element you are sending keys to is not interactable (usually that means not visible or disabled). You may also recheck the visibility of the form after sending the keys.

Categories

Resources