0

I know this question was already answered here but I wouldn't be typing this if it worked for me.

I'm making a bot that gets a random image from Bing and returns it's URL to later send it to Discord. Here's my code so far:

import random
from msedge.selenium_tools import EdgeOptions
from msedge.selenium_tools import Edge
from time import sleep

edge_options = EdgeOptions()
edge_options.use_chromium = True
edge_options.add_argument('headless')
edge_options.add_argument('disable-gpu')

driver = Edge(executable_path='PATH/TO/DRIVER', options=edge_options)

def Image(query):
    query.strip()
    query.replace(' ', '+')
    ImageUrl=f'http://www.bing.com/images/search?q={query}'

    driver.get(ImageUrl)
    #Wait for page to fully load
    sleep(5)
    all_images = driver.find_elements_by_class_name('mimg')
    random.choice(all_images).click()
    sleep(5)

    parent = driver.find_element_by_class_name('nofocus')
    source = parent.get_attribute('src')
    return source

print(Image('cat'))
driver.quit()

When runing the above code I get this:

Traceback (most recent call last):
  File "PATH/TO/FILE", line 52, in <module>
    print(Image('cat'))
  File "PATH/TO/FILE", line 27, in Image
    parent = driver.find_element_by_class_name('nofocus')
  File "C:\Users\axeld\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 413, in find_element_by_class_name
    return self.find_element(by=By.CLASS_NAME, value=name)
  File "C:\Users\axeld\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 750, in find_element
    return self.execute(Command.FIND_ELEMENT, {
  File "C:\Users\axeld\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 236, in execute
    self.error_handler.check_response(response)
  File "C:\Users\axeld\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 192, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"class name","selector":"nofocus"}
  (Session info: headless MicrosoftEdge=87.0.664.57)
  (Driver info: msedgedriver=87.0.664.55 (097391c0e48fdc4ded0e5c4367f7055dc71815ed),platform=Windows NT 10.0.19042 x86_64)

Exception ignored in: <function Service.__del__ at 0x0000021FD11A2820>
Traceback (most recent call last):
  File "PATH/TO.FO", line 163, in __del__
  File "C:\Users\axeld\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\common\service.py", line 139, in stop
  File "C:\Users\axeld\AppData\Local\Programs\Python\Python39\lib\site-packages\selenium\webdriver\common\service.py", line 110, in send_remote_shutdown_command
ImportError: sys.meta_path is None, Python is likely shutting down

What is happening?

Maypher
  • 121
  • 1
  • 2
  • 10
  • error shows that it can't find object with class `nofocus`. Did you check if your script gets HTML with object which has class `nofocus` ? Maybe server sends you different page - ie. page with warning for bots. You should display HTML or save it file to check what you get from server. And later you can use `try/except` to catch this problem and display some message for user. – furas Dec 08 '20 at 21:59
  • @furas You were right. Selenium was looking at another HTML. I got the correct one and it finds the class but there's another problem. I run the same command (`driver.find_element_by_class_name('nofocus')`) and I recive `
    Full screen
    ` It does have the word I'm looking for but it's not the exact same. Is there any way to search by exact class name?
    – Maypher Dec 08 '20 at 22:14
  • you can use `find_elements_by_class_name` with char `s` in word `elements` to get list with all elements which have class `nofocus` and later you can filter this list to get element which you need - ie. get second element on list. You can also use other functions to search - ie `find_element_by_xpath` or `find_element_by_css_selector` and then you can use more complex rule to get element. – furas Dec 08 '20 at 22:29
  • BTW: there is [Bing Image API](https://www.microsoft.com/en-us/bing/apis/bing-image-search-api) and it can be better idea then using Selenium. Normal page can make problems - ie. it can send `Captcha` to test if you are not bot/script - but API doesn't check it. And API should work faster – furas Dec 08 '20 at 22:36
  • BTW: Bing gives even example how to use Bing API in Python - [Quickstart: Use Python to call the Bing Web Search API](https://learn.microsoft.com/en-us/azure/cognitive-services/bing-web-search/quickstarts/python) and source code [BingWebSearchv7.py](https://github.com/Azure-Samples/cognitive-services-REST-api-samples/blob/master/python/Search/BingWebSearchv7.py) – furas Dec 08 '20 at 22:43
  • @furas Yes, i did learn about Azure but isn't it a paid Microsoft feature? – Maypher Dec 08 '20 at 22:43
  • it is free for 1000 images/month - see [prices](https://www.microsoft.com/en-us/bing/apis/pricing) - it gives ~34 images/day – furas Dec 08 '20 at 22:44
  • 1000 fells like enough, I'll try it out. Thank you – Maypher Dec 08 '20 at 22:47
  • 1
    correction: it is 1000 searches(transactions) per month - every search can gives list of results which you can use randomly many times. – furas Dec 08 '20 at 22:48

0 Answers0