0

i write this code for download image from google from .txt file that has list of strings.

If try with only string into code work.

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(service=Service(r'C:\Users\Desktop\Temp\images\chromedriver.exe'))
driver.get('https://www.google.it/imghp?hl=it&authuser=0&ogbl')

time.sleep(10)

with open("file.txt") as file:
    for row in file.readlines():
        box = driver.find_element("xpath", '/html/body/div[1]/div[3]/form/div[1]/div[1]/div[1]/div/div[2]/input')
        box.send_keys(row)
        box.send_keys(Keys.ENTER)
        time.sleep(3)

        for i in range(1, 3):
            try:
                driver.find_element("xpath", '//*[@id="islrg"]/div[1]/div['+str(i)+']/a[1]/div[1]/img').screenshot(r'C:\Users\Desktop\Temp\images\downloads ('+str(i)+').png')
                time.sleep(3)
            except:
                pass

when execute the script:

  • open chrome
  • search image

but when try to download image the application crash, with this messages:

Traceback (most recent call last):
File "C:\Users\Angelo\Desktop\Temp\images\try.py", line 16, in <module> box.send_keys(Keys.ENTER)
File "C:\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 223, in send_keys self._execute(Command.SEND_KEYS_TO_ELEMENT,
File "C:\Python310\lib\site-packages\selenium\webdriver\remote\webelement.py", line 396, in _execute return self._parent.execute(command, params)
File "C:\Python310\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 428, in execute self.error_handler.check_response(response)
File "C:\Python310\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 243, in check_response raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document (Session info: chrome=105.0.5195.102)
Stacktrace:
Backtrace:
Ordinal0 [0x0076DF13+2219795]
Ordinal0 [0x00702841+1779777]
Ordinal0 [0x0061423D+803389]
Ordinal0 [0x00616D04+814340]
Ordinal0 [0x00616BC2+814018]
Ordinal0 [0x00616E50+814672]
Ordinal0 [0x00643A4B+997963]
Ordinal0 [0x00643B21+998177]
Ordinal0 [0x0063C1D4+967124]
Ordinal0 [0x0065E7FC+1107964]
Ordinal0 [0x006394B4+955572]
Ordinal0 [0x0065EA14+1108500]
Ordinal0 [0x0066F192+1175954]
Ordinal0 [0x0065E616+1107478]
Ordinal0 [0x00637F89+950153]
Ordinal0 [0x00638F56+954198]
GetHandleVerifier [0x00A62CB2+3040210]
GetHandleVerifier [0x00A52BB4+2974420]
GetHandleVerifier [0x00806A0A+565546]
GetHandleVerifier [0x00805680+560544]
Ordinal0 [0x00709A5C+1808988]
Ordinal0 [0x0070E3A8+1827752]
Ordinal0 [0x0070E495+1827989]
Ordinal0 [0x007180A4+1867940]
BaseThreadInitThunk [0x772BFA29+25]
RtlGetAppContainerNamedObjectPath [0x778A7A9E+286]
RtlGetAppContainerNamedObjectPath [0x778A7A6E+238]

UPDATE: file.txt example:

popo
mumu
fiat
bmw
audi
Rock
  • 33
  • 8
  • this means the DOM is changing somewhere between find and method (findelement and send keys) OR between the two send keys methods. You might just try using one send keys method. So box.send_keys(row + Keys.ENTER)... using webdriverwaits would be good too. – pcalkins Sep 14 '22 at 20:38

1 Answers1

1

By performing the search, the input element is changing.
You can use another, better locator to overcome this issue.
Also, using absolute XPaths or CSS Selectors is never a good idea since these locators are extremally fragile.
Try this:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(service=Service(r'C:\Users\Desktop\Temp\images\chromedriver.exe'))
driver.get('https://www.google.it/imghp?hl=it&authuser=0&ogbl')

time.sleep(10)

with open("file.txt") as file:
    for row in file.readlines():
        box = driver.find_element("xpath", "//input[@name='q']")
        box.send_keys(row)
        box.send_keys(Keys.ENTER)
        time.sleep(3)

        for i in range(1, 3):
            try:
                driver.find_element("xpath", '//*[@id="islrg"]/div[1]/div['+str(i)+']/a[1]/div[1]/img').screenshot(r'C:\Users\Desktop\Temp\images\downloads ('+str(i)+').png')
                time.sleep(3)
            except:
                pass

Also it is always preferably to use WebDriverWait explicit waits, not hardcoded sleeps whenever it is possible.
UPD
I have tested the following code and it worked correctly including creating the screenshots

import time

from selenium import webdriver
from selenium.webdriver import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("start-maximized")


webdriver_service = Service('C:\webdrivers\chromedriver.exe')
driver = webdriver.Chrome(service=webdriver_service, options=options)
url = "https://www.google.it/imghp?hl=it&authuser=0&ogbl"
driver.get(url)
lines = ["kuku", "mumu", "popo"]
time.sleep(10)


for line in lines:
    box = driver.find_element("xpath", "//input[@name='q']")
    box.clear()
    box.send_keys(line)
    box.send_keys(Keys.ENTER)
    time.sleep(3)

    for i in range(1, 3):
        try:
            driver.find_element("xpath", '//*[@id="islrg"]/div[1]/div['+str(i)+']/a[1]/div[1]/img').screenshot(r'C:\Users\****\Desktop\downloads ('+str(i)+').png')
            time.sleep(3)
        except:
            pass
Prophet
  • 32,350
  • 22
  • 54
  • 79
  • I tried, you just changed this right? box = driver.find_element ("xpath", "// input [@ name = 'q']") but the same thing always happens – Rock Sep 14 '22 at 10:15
  • can you give me a sample of `file.txt` so i will be able to debug this? – Prophet Sep 14 '22 at 10:17
  • I have tried it and it works correctly. See the updated answer – Prophet Sep 14 '22 at 10:48
  • with your example work, but if i use file.txt not work. Now i update the ask with file.txt example – Rock Sep 14 '22 at 13:18
  • So, your problem is probably not with my code but with specific input data in your file. For what input it fails? – Prophet Sep 14 '22 at 13:39
  • open chrome, go to search, search first string and after crash with error in question. I don't know – Rock Sep 14 '22 at 13:58
  • I re-tested it with the inputs you provided. Nothing crashed. Works almost correctly: images are not saved correctly, but this is another issue – Prophet Sep 14 '22 at 14:03
  • i try create file.txt in different way with different software, but not work. I don't know, for save images bug, i see. UPD: if into the file.txt write only one string work. – Rock Sep 14 '22 at 14:21
  • What tool you using for creating the file.txt? maybe it is adding some invisible signs there? like notepad does? try notepad++. anyway, seems your problem is with input, not with selenium code. Try using a list of string in the selenium file itself as I do, not an external file. If it will work - and it should - the problem is with file.txt, not with Selenium code as mentioned – Prophet Sep 14 '22 at 14:30
  • yes with notepad++, visual code, bloc notes, etc... ok close the question, thanks. but not work – Rock Sep 14 '22 at 14:48