2
votes

I'm fairly new to Selenium, but this bug is just knocking my knickers! I'm trying to code a bot to click the like button on the first 10 photos in my Instagram feed. I just copied and pasted the XPath of the like button from Chrome, but this XPath won't work for some reason.

Here's the code:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep, strftime
from random import randint


sleep(3)    
for x in range(1,10):
    button_like = webdriver.find_element_by_xpath('//*[@id="react-root"]/section/main/section/div[2]/div[1]/div/article[{}]/div[2]/section[1]/span[1]/button/span'.format(x))
    button_like.click()
    sleep(randint(2,3))

And here's the HTML of the section with the buttons I'm trying to click.

<section class="ltpMr Slqrh">
    <span class="FY9nT fr66n">
        <button class="dCJp8 afkep _0mzm-">
            <span class="glyphsSpriteHeart__filled__24__red_5 u-__7" aria-label="Unlike"></span>
        </button>
    </span>
    <span class="_15y0l">
        <button class="dCJp8 afkep _0mzm-">
            <span class="glyphsSpriteComment__outline__24__grey_9 u-__7" aria-label="Comment"></span>
        </button></span>
    <span class="_5e4p">
        <button class="dCJp8 afkep _0mzm-">
            <span class="glyphsSpriteShare__outline__24__grey_9 u-__7" aria-label="Share Post"></span>
        </button>
    </span>
    <span class="wmtNn">
        <button class="dCJp8 afkep _0mzm-">
            <span class="glyphsSpriteSave__outline__24__grey_9 u-__7" aria-label="Save"></span>
        </button>
    </span>
</section>

And here's the error message I get:

Traceback (most recent call last): File "/Users/JoshSong/Desktop/Liking Your Friend's Photos.py", line 33, in button_like = webdriver.find_element_by_xpath('//[@id="react-root"]/section/main/section/div[2]/div[1]/div/article[{}]/div[2]/section[1]/span[1]/button/span'.format(x)) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 394, in find_element_by_xpath return self.find_element(by=By.XPATH, value=xpath) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 978, in find_element 'value': value})['value'] File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute self.error_handler.check_response(response) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//[@id="react-root"]/section/main/section/div[2]/div[1]/div/article[1]/div[2]/section[1]/span[1]/button/span"} (Session info: chrome=76.0.3809.100)

2
try this //*[@id="react-root"]/section/main/section/div[2]/div[1]/div/article/div[2]/section[1]/span[1]/button/spanEd Bangga
ah that got the same error unfortunatelyJoshua Song
you need to share the xml/htmlEd Bangga
I shared the html of the button above. Do you want me to share more of the html?Joshua Song
yes, from section/mainEd Bangga

2 Answers

-1
votes

I have similar issues when trying to use paths with indices. I would suggest using this: //span[@aria-label='Like'] . I haven't used selenium with python but I'd assume that there is a find method that takes an index as parameter. So you could use that to hit the first like element, then the 2nd, and so on (but from what it seems like on instagram website only 7 are detectable at a time)

0
votes

We need more of the HTML to be able to answer the question adequately. For example, with what you provided, one solution would be:

like_button = driver.find_element_by_xpath("//span[@class='FY9nT fr66n']/button")
like_button.click()

Based on the provided HTML, this would click the first button (which is actually an Unlike button from what you provided, but I'm assuming the Like button WAS there). If the span elements surrounding each of the Like buttons you want has the same class, this would only require minor modification:

like_buttons = driver.find_elements_by_xpath("//span[@class='FY9nT fr66n']/button")
#create maxIndex of the lesser of the length, or the max index you want to press
maxIndex = MIN(9, len(like_buttons))
for i in range (0, maxIndex):
    like_buttons[i].click()

This solution should work, assuming the span elements surrounding each Like button are the same AND that that class is not reused on other span elements on the page that are not wrapping Like buttons. If you update the HTML and these assumptions are violated, I would be happy to review a new solution