No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Realizar una prueba t茅cnica

23/24
Recursos

Aportes 49

Preguntas 19

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

Para utilizar location, condition y higher_price cambie el c贸digo. El mensaje de Selenium fue 鈥淓lement click intercepted鈥.

# Anterior 
location.click()
# Nuevo
driver.execute_script("arguments[0].click();", location)

Con eso logre realizar el test.

Este es mi implementaci贸n antes de ver el v铆deo, mi intenci贸n era generalizarlo lo mas posible para cualquier variaci贸n como pa铆s, b煤squeda, filtro, localidad y orden.

mercado_libre_page.py

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class MercadoLibrePage(object):

  def __init__(self, driver):
    self._driver = driver
    self._url = 'http://mercadolibre.com/'

  @property
  def is_loaded(self):
    WebDriverWait(self._driver, 10).until(
      EC.presence_of_element_located((By.CLASS_NAME, 'ml-site-list'))
      or EC.presence_of_element_located((By.NAME, 'as_word'))
    )
    return True

  @property
  def keyword(self):
    input_field = self._driver.find_element_by_name('as_word')
    return input_field.get_attribute('value')

  def open(self):
    self._driver.get(self._url)

  def type_search(self, keyword):
    input_field = self._driver.find_element_by_name('as_word')
    input_field.send_keys(keyword)

  def click_submit(self):
    input_field = self._driver.find_element_by_name('as_word')
    input_field.submit()

  def search(self, keyword):
    self.type_search(keyword)
    self.click_submit()

  def order_data(self, elements):
    obj = {}
    for element in elements:
      obj[element.text.lower()] = element
    return obj

  def get_contries(self):
    contries = self._driver.find_elements_by_class_name('ml-site-link')
    return self.order_data(contries)

  def choise_contry(self, contry):
    contry_item = self.get_contries()[contry.lower()]
    contry_item.click()

  def get_filters(self):
    filters = WebDriverWait(self._driver, 10).until(EC.visibility_of_any_elements_located((By.CLASS_NAME, 'ui-search-filter-name')))
    return self.order_data(filters)

  def choise_filter(self, keyword):
    self.get_filters()[keyword.lower()].click()

  def get_orders(self):
    list_buttom = WebDriverWait(self._driver, 5).until(EC.presence_of_element_located((By.CLASS_NAME, 'andes-dropdown__trigger')))
    list_buttom.click()
    orders = self._driver.find_elements_by_class_name('andes-list__item-primary')
    return self.order_data(orders)

  def choise_order_by(self, keyword):
    self.get_orders()[keyword.lower()].click()

  def get_top_5_elements_result(self):
    WebDriverWait(self._driver, 10).until(EC.presence_of_all_elements_located((By.CLASS_NAME, 'ui-search-layout__item')))
    data = [[None, None]] * 5
    for i in range(5):
      data[i][0] = self._driver.find_element_by_xpath(f'//*[@id="root-app"]/div/div/section/ol/li[{i+1}]/div/div/div[2]/div[1]/a/h2').text
      data[i][1] = self._driver.find_element_by_xpath(f'//*[@id="root-app"]/div/div/section/ol/li[{i+1}]/div/div/div[2]/div[2]/div/div/span[1]/span[2]').text
    return data

test_mercado_libre.py

import unittest
from selenium import webdriver
from mercado_libre_page import MercadoLibrePage

class CompareProducts(unittest.TestCase):

  @classmethod
  def setUpClass(cls):
    cls.driver = webdriver.Chrome(executable_path = r'./chromedriver.exe')
    cls.driver.maximize_window()

  def test_mercado_libre(self):
    mcl = MercadoLibrePage(self.driver)
    mcl.open()
    self.assertTrue(mcl.is_loaded)
    mcl.choise_contry('colombia')
    mcl.search('playstation 4')
    mcl.choise_filter('nuevo')
    mcl.choise_filter('Bogot谩 D.C.')
    mcl.choise_order_by('Mayor precio')
    print(mcl.get_top_5_elements_result())

  @classmethod
  def tearDownClass(cls):
    cls.driver.close()

if __name__ == "__main__":
  unittest.main(verbosity=2)

Mucho cuidado con el bot贸n de cookies. Como bien es sabido, el chromedriver ejecuta en inc贸gnito. Cuando t煤 est谩s revisando mucho ojo, porque cuando exploras, lo haces hasta con tu cuenta ya ingresada, y claro, con las cookies ya guardadas. Pero es muy diferente, cuando ingresas en inc贸gnito, porque all铆 te pide que o aceptes o rechaces las cookies, por ser la 鈥減rimera vez鈥 que ingresas.

Para ello, debes poner este c贸digo dentro del ejercicio de la clase:

Despu茅s de buscar el playstation y antes de hacer el filtro de ubicaci贸n:

cookies_in = driver.find_element_by_xpath("/html/body/div[2]/div[1]/div[2]/button[1]")
cookies_in.click()
sleep(3)

Y eso es todo, te funcionar谩 perfecto.

++Consejo: ++ Al hacer un script de automatizaci贸n y que vayas haciendo la exploraci贸n de la p谩gina web, realiza la exploraci贸n en inc贸gnito, pues as铆 garantizas el comportamiento normal que se tendr铆a con el chromedriver, que es una especie de inc贸gnito.

Espero les sirva鈥

Marzo-2021. Sale este error: Message: Element <span class=鈥渦i-search-filter-name鈥> is not clickable at point (113,643) because another element <div id=鈥渃ookieDisclaimerBanner鈥 class=鈥渘av-cookie-disclaimer鈥> obscures it.
Parece que usaron alguna cookie para bloquear busquedas automatizadas con Selenium (por ejemplo), F. De todas maneras gran curso

Este es mi c贸dgio por si le sirve a alguien. Luego de unos arreglos que no me funcionaban algunos clicks y encontre la soluci贸n en los comentarios.

import unittest
from selenium import webdriver
from time import sleep
 
class TestingMercadoLibre(unittest.TestCase):

	def setUp(self):
		self.driver = webdriver.Chrome(executable_path = r'./chromedriver.exe')
		driver = self.driver
		driver.maximize_window()
		driver.get('https://www.mercadolibre.com')

	def test_search_PS4(self):
		driver = self.driver

		country = driver.find_element_by_id("CO")
		country.click()

		search_field = driver.find_element_by_name("as_word")
		search_field.click()
		search_field.clear()
		search_field.send_keys('playstation 4')
		search_field.submit()
		sleep(3)

		location = driver.find_element_by_xpath("//div/div/aside/section[2]/dl[9]/dd[1]/a")
		driver.execute_script("arguments[0].click();", location)
		sleep(3)

		condition = driver.find_element_by_xpath("//div/div/aside/section[3]/dl[6]/dd[1]/a")
		driver.execute_script("arguments[0].click();", condition)
		sleep(3)

		order_menu = driver.find_element_by_class_name("andes-dropdown__trigger")
		order_menu.click()

		higher_price = driver.find_element_by_xpath("//div/div/aside/section[2]/div[2]/div[1]/div/div/div/ul/li[3]/a")
		driver.execute_script("arguments[0].click();", higher_price)
		sleep(3)

		articles = []
		prices = []

		for i in range(5):
			article_name = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[1]/a').text
			articles.append(article_name)
			article_price = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[2]/div[1]/div[1]/div/div/span[1]/span[2]').text
			prices.append(article_price)

		print(articles, prices)


	def tearDown(self):
		self.driver.close()

if __name__ == "__main__":
	unittest.main()

Me toco modificar algunos click

import unittest
from selenium import webdriver
from api_data_mock import ApiDataMock
from selenium.webdriver.support.ui import Select # Modulo para poder seleccionar del dropdown
from time import sleep
from selenium.webdriver.common.by import By #Hacer referencia a un elemento del sitio web, para interactuar
from selenium.webdriver.support.ui import WebDriverWait # Modulo para  manejo de esperas explicitas
from selenium.webdriver.support import expected_conditions as EC #esperas explicitas




class TestingMercadoLibre(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome(executable_path = r'./chromedriver.exe')
        driver = self.driver
        driver.maximize_window()
        driver.get('**********') # adiconar la pagina


    def test_search_xbox(self):
        driver = self.driver

        country = driver.find_element_by_id('CO')
        country.click()
        sleep(2)
        search_field = driver.find_element_by_name('as_word')
        search_field.clear()
        search_field.send_keys('xbox')
        search_field.submit()
        sleep(2)
        
        location = driver.find_element_by_xpath('/html/body/main/div/div/aside/section[2]/dl[8]/dd[1]/a/span[1]')
        driver.execute_script("arguments[0].click();", location)
        # location.click()
        sleep(2)
        condition = driver.find_element_by_partial_link_text('Nuevo')
        driver.execute_script("arguments[0].click();", condition)
        # condition.click()
        sleep(2)
        order_menu = driver.find_element_by_class_name('andes-dropdown__trigger')
        order_menu.click()
        higher_price = driver.find_element_by_css_selector('li.andes-list__item:nth-child(3) > div:nth-child(1) > div:nth-child(1) > a:nth-child(1)')
        higher_price.click()
        sleep(2)

        articles = []
        prices = []

        for i in range(5):
            article_name = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[1]/a/h2').text
            price_article = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[2]/div/div/span[1]/span[2]').text
            articles.append(article_name)
            prices.append(price_article)
        
        print(articles,prices)

        

    def tearDown(self):
        self.driver.implicitly_wait(5)
        self.driver.close()


if __name__ == '__main__':
    unittest.main(verbosity=2)

Creo que es mejor usar un diccionario en vez de dos listas

 products = {}

        for i in range(5):
            article_name = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div[2]/div/h2/a/span').text
            price = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div[2]/div/div[1]/div/span[2]').text
            products[article_name] = price

Con la ayuda de los comentarios y unas modificaciones m谩s porque el sitio cambia constantemente aqu铆 el c贸digo funcional para la fecha 09-10-2021

import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from time import sleep

class MercadoLibre(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Chrome(executable_path='/usr/bin/chromedriver')
        driver = cls.driver
        driver.get('https://www.mercadolibre.com/')
        driver.maximize_window()

    def test_search_ps4(self):
        driver = self.driver
        choose_country = driver.find_element_by_id('CO')
        choose_country.click()

        search_bar = driver.find_element_by_class_name('nav-search-input')
        search_bar.click()
        search_bar.clear()
        search_bar.send_keys('playstation 4')
        search_bar.submit()
        driver.implicitly_wait(3)

        pick_news = driver.find_element_by_partial_link_text('Nuevo')
        driver.execute_script("arguments[0].click();", pick_news)
        driver.implicitly_wait(3)

        pick_location = driver.find_element_by_partial_link_text('Bogot谩 D.C.')
        driver.execute_script("arguments[0].click();", pick_location)
        driver.implicitly_wait(3)

        pick = driver.find_element_by_class_name('andes-dropdown__trigger')
        driver.execute_script("arguments[0].click();", pick)
        driver.implicitly_wait(10)

        pick_expensive_price = driver.find_elements_by_class_name('andes-list__item-primary')
        pick_expensive_price[2].click()

        articles = []
        prices = []

        for i in range(5):
            article_name = driver.find_element_by_css_selector(f'#root-app > div > div > section > ol > li:nth-child({i+1}) > div > div > div.ui-search-result__content-wrapper > div.ui-search-item__group.ui-search-item__group--title > a > h2').text
            articles.append(article_name)
            article_price = driver.find_element_by_css_selector(f'#root-app > div > div > section > ol > li:nth-child({i+1}) > div > div > div.ui-search-result__content-wrapper > div.ui-search-result__content-columns > div.ui-search-result__content-column.ui-search-result__content-column--left > div.ui-search-item__group.ui-search-item__group--price > a > div > div > span.price-tag.ui-search-price__part > span.price-tag-amount > span.price-tag-fraction').text
            prices.append(article_price)
        for x in range(len(articles)):
            print(prices[x]+' -> '+articles[x])

    @classmethod
    def tearDownClass(cls):
        cls.driver.close()

if __name__ == '__main__':
    unittest.main(verbosity=2, testRunner=HTMLTestRunner(output = 'reportes', report_name = 'ML_report'))

Esta es mi implementacion

test_mercadolibre:

from selenium import webdriver
import unittest
from mercadolibre_page import MercadoLibrePage
from time import sleep

class testMercadoLibre(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Chrome(executable_path=r'C:/chromedriver.exe')
        cls.driver.maximize_window()

    def test_search(self):
        mercadolibre = MercadoLibrePage(self.driver)
        mercadolibre.open()
        mercadolibre.select_country('Colombia')
        
        self.assertEqual(mercadolibre.current_url, 'https://www.mercadolibre.com.co/#from=homecom')

        mercadolibre.type_search('playstation 4')
        mercadolibre.click_submit()

        self.assertEqual('playstation 4', mercadolibre.keyword)

        mercadolibre.acept_cookies()

        mercadolibre.add_filter('Nuevo')

        self.assertEqual(mercadolibre.last_filter, 'Nuevo')

        mercadolibre.add_filter('Bogot谩 D.C.')

        self.assertEqual(mercadolibre.last_filter, 'Bogot谩 D.C.')

        mercadolibre.open_price_filter_window()
        
        mercadolibre.add_price_filter('Menor precio')

        self.assertEqual(mercadolibre.current_order, 'Menor precio')

        mercadolibre.get_information(60)

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()


if __name__ == '__main__':
    unittest.main(verbosity=2)

mercadolibre_page:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException 
import csv
import time

class MercadoLibrePage(object):

    def __init__(self, driver):
        self._driver = driver
        self._url = 'https://www.mercadolibre.com'
        self._search_locator = 'as_word'
        self._price_filter_locator = '//div[@class="andes-widther"]//button[@class="andes-dropdown__trigger"]'
        self._filters = []

    @property
    def is_loaded(self):
        WebDriverWait(self._driver, 10).until(EC.presence_of_element_located((By.NAME, self._search_locator)))
        return True

    @property
    def keyword(self):
        search_field = self._driver.find_element_by_name(self._search_locator)
        return search_field.get_attribute('value')

    @property
    def current_url(self):
        return self._driver.current_url

    @property
    def last_filter(self):
        return self._filters[len(self._filters)-1 ]
    
    @property
    def current_order(self):
        return WebDriverWait(self._driver, 10).until(EC.element_to_be_clickable((By.XPATH, self._price_filter_locator))).text

    def open(self):
        self._driver.get(self._url)

    def acept_cookies(self):
        try:
            location_window = self._driver.find_element_by_xpath('//div[@class="onboarding-cp"]')
            location_window.find_element_by_class_name('andes-tooltip-button-close').click()
        except NoSuchElementException:
            pass
        try:
            self._driver.find_element_by_id('cookieDisclaimerButton').click()
        except:
            pass

    def select_country(self, country):
        self._driver.find_element_by_link_text(country).click()
    
    def type_search(self, keyword):
        search_field = WebDriverWait(self._driver, 10).until(EC.presence_of_element_located((By.NAME, self._search_locator)))
        search_field.send_keys(keyword)

    def  click_submit(self):
        search_field = self._driver.find_element_by_name(self._search_locator)
        search_field.submit()

    def add_filter(self, filter_keyword):
        WebDriverWait(self._driver, 10).until(EC.element_to_be_clickable((By.XPATH, f'//section[@class="ui-search-filter-groups"]//span[text()="{filter_keyword}"]'))).click()
        self._filters.append(filter_keyword)

    def open_price_filter_window(self):
        WebDriverWait(self._driver, 10).until(EC.element_to_be_clickable((By.XPATH, self._price_filter_locator))).click()

    #the option filter are: [M谩s relevantes, Menor precio, Mayor precio]
    def add_price_filter(self, filter_keyword):
        self._driver.find_element_by_xpath(f'//ul[@class="andes-list andes-list--size-compact andes-list--dropdown andes-list--selectable"]//div[text()="{filter_keyword}"]').click()

    def get_information(self, product_quantity):
        #get information of all products that you need
        products = self._driver.find_elements_by_class_name('ui-search-layout__item')
        data = [[] for i in range(0, 2)]
        print()

        if products:
            n_products = 0
            i = 0
            while True:
                try:
                    name = products[i].find_element_by_class_name('ui-search-item__title')
                    price = products[i].find_element_by_class_name('price-tag-fraction')
                    data[0].append(name.text)
                    data[1].append(price.text)
                    print(f'name: {name.text} \nprice: {price.text}\n')
                    i += 1
                    n_products += 1
                    if n_products == product_quantity:
                        print(f'Se han encontraron los {n_products} productos.\n')
                        break
                except IndexError:
                    i = 0
                    try:
                        self._driver.find_element_by_xpath('//div[@class="ui-search-pagination"]//li//span[text()="Siguiente"]').click()
                        self._driver.implicitly_wait(10)
                        products = self._driver.find_elements_by_class_name('ui-search-layout__item')
                    except NoSuchElementException:
                        print(f'Solo se encontraron {n_products} productos.\n')
                        break
            self._save_data(data)
        else:
            print('\nNo se encontraron productos\n')


    def _save_data(self, data):
        #save data on csv file
        date = time.strftime('%d_%m_%Y', time.localtime())
        filename = f'products_data_{date}.csv'
        headers = ['name', 'price']

        with open(filename, mode= 'w+', encoding='utf-8', ) as f:
            writer = csv.writer(f)
            writer.writerow(headers)
            
            for i in range(0, len(data[0])):
                row = [data[0][i], data[1][i]]
                writer.writerow(row)

El class_name de la variable Order_menu hoy 26 julio es andes-dropdown__trigger y no ui-dropdown__link buen curso

Un selector de css m谩s corto li.ui-list__item:nth-child(3) > a:nth-child(1) para la variable higher_price

Excelente profe, aplicar todo y muy util ejemplo.

As铆 lo hice yo

from itertools import product
import unittest
from selenium import webdriver
from time import sleep

class PruebaTecnica(unittest.TestCase):
    
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path=r'E:\Descargas\chromedriver.exe')
        driver = self.driver
        driver.implicitly_wait(50)
        driver.maximize_window()
        #driver.get('https://www.mercadolibre.com')
        driver.get('https://www.google.com')

    def test_mercado_libre(self):
        
        input_field = self.driver.find_element_by_name('q')
        search_page = 'Mercado libre'
        input_field.send_keys(search_page)
        input_field.submit()

        find_option = self.driver.find_element_by_partial_link_text('Mercado Libre Colombia - Env铆os Gratis en el da')
        find_option.click()
        
        #country = self.driver.find_element_by_id('CO')
        #country.click()

        #search_product = self.driver.find_element_by_class_name('nav-search-input')
        search_product = self.driver.find_element_by_name('as_word')
        name_product = 'Playstation 4'
        search_product.send_keys(name_product)
        search_product.submit()

        #condition = self.driver.find_element_by_css_selector('#root-app > div > div.ui-search-main.ui-search-main--exhibitor.ui-search-main--only-products > aside > section > div:nth-child(3) > ul > li:nth-child(1) > a > span.ui-search-filter-name')
        state_product = self.driver.find_element_by_partial_link_text('Nuevo')
        state_product.click()
        sleep(5)

        #city = self.driver.find_element_by_link_text('#root-app > div > div.ui-search-main.ui-search-main--exhibitor.ui-search-main--only-products > aside > section.ui-search-filter-groups > div:nth-child(3) > ul > li:nth-child(1) > a > span.ui-search-filter-name')
        city = self.driver.find_element_by_partial_link_text('Bogot谩 D.C.')
        city.click()
        sleep(5)

        order_menu = self.driver.find_element_by_class_name('andes-dropdown__display-values')
        order_menu.click()
        sleep(5)

        order_price = self.driver.find_element_by_css_selector('#andes-dropdown-ms-relevantes-list-option-price_desc > div > div > span')
        order_price.click()
        sleep(5)

        #name_article = self.driver.find_element_by_class_name('ui-search-item__title')
        #name_article.click()

        #vamos a colocar los productos dentro de una lista
        articles = []
        prices = []

        for i in range(5):
            article_name = self.driver.find_element_by_xpath(f'//*[@id="root-app"]/div/div[2]/section/ol/li[{i+1}]/div/div/div[2]/div[1]/a/h2').text
            articles.append(article_name)
            article_price = self.driver.find_element_by_xpath(f'//*[@id="root-app"]/div/div[2]/section/ol/li[{i+1}]/div/div/div[2]/div[2]/div[1]/div[1]/div/div/div/span[1]/span[2]/span[2]').text
            prices.append(article_price)
        print(articles, prices)
    def tearDown(self):
        self.driver.close()

if __name__ == '__main__':
    unittest.main(verbosity=2)

Realice la recolecci贸n de todos los datos mendiante CSS_SELECTOR y converti la data en un diccionario con los art铆culos y sus precios.

    def test_search_ps4(self):
        driver = self.driver
        country = driver.find_element(By.ID, 'CO')
        country.click()
        accept_cookie_button = driver.find_element(
            By.XPATH, '/html/body/div[2]/div[1]/div[2]/button[1]')
        accept_cookie_button.click()
        sleep(2)
        search_input = driver.find_element(By.NAME, 'as_word')
        search_input.click()
        search_input.clear()
        search_input.send_keys('playstation 4')
        search_input.submit()
        sleep(2)
        location = driver.find_element(By.PARTIAL_LINK_TEXT, 'Bogot谩 D.C.')
        location.click()
        sleep(2)
        condition = driver.find_element(By.PARTIAL_LINK_TEXT, 'Nuevo')
        condition.click()
        sleep(2)
        order_menu = driver.find_element(
            By.CLASS_NAME, 'andes-dropdown__trigger')
        order_menu.click()
        higher_price = driver.find_element(
            By.CSS_SELECTOR, '#andes-dropdown-m谩s-relevantes-list-option-price_desc')
        higher_price.click()

        article_elements = driver.find_elements(
            By.CSS_SELECTOR, 'div.ui-search-result__content-wrapper h2.ui-search-item__title')
        price_elements = driver.find_elements(
            By.CSS_SELECTOR, 'div.ui-search-result__content-wrapper div.ui-search-price--size-medium div.ui-search-price__second-line span.price-tag-fraction')
        item_count = len(article_elements)
        data = [{'article': article_elements[i].text, 'price': price_elements[i].text}
                for i in range(item_count)]
        print(f'\nFound {item_count} items.')
        print('\nData: ', data)

Es el segundo curso que veo de Hector Vega , y la verdad hay temas que quedan claros por que son sencillos , pero no porque explique bien , ; en general el no explica nada bien ,solo hace y hace c贸digo , da ganas de dormirse antes que ver el curso , no se sabe incluso ni que va hacer , pesimo curso. sobre 10 , le doy un 6/10

21/03/22

Dado que hubo ajustes en la pagina realice los siguientes cambios para que fue posible llevar a cabo el c贸digo por parte de H茅ctor.

  1. para location, condition cambie los find_element_by_partial_link_text por find_element_by_css_selector()

  2. para order_menu cambien el find_element_by_class_name() por find_element_by_css_selector()

  3. por utlimo y con el aporte dejado por por @Arnaldo Martinez se hizo el cambio en la opci贸n de .click() en location, condition y higher_price por driver.execute_script(鈥渁rguments[0].click();鈥,location)
    driver.execute_script(鈥渁rguments[0].click();鈥,lcondition)
    driver.execute_script(鈥渁rguments[0].click();鈥,hirgher_price)

Una actualizaci贸n al codigo (con ubuntu y chrome92)

import unittest
from selenium import webdriver
from time import sleep
 
class TestingMercadoLibre(unittest.TestCase):

	def setUp(self):
		self.driver = webdriver.Chrome(executable_path = r'./chromedriver92')
		driver = self.driver
		driver.maximize_window()
		driver.get('https://www.mercadolibre.com')

	def test_search_PS4(self):
		driver = self.driver

		country = driver.find_element_by_id("CO")
		country.click()

		search_field = driver.find_element_by_name("as_word")
		search_field.click()
		search_field.clear()
		search_field.send_keys('playstation 4')
		search_field.submit()

		location = driver.find_element_by_xpath('//*[@id="root-app"]/div/div/aside/section/dl[18]/dd[1]/a')
		driver.execute_script("arguments[0].click();", location)
		sleep(1)

		condition = driver.find_element_by_xpath('//*[@id="root-app"]/div/div/aside/section[2]/dl[16]/dd[1]/a')
		driver.execute_script("arguments[0].click();", condition)
		sleep(1)

		order_menu = driver.find_element_by_class_name("andes-dropdown__trigger")
		order_menu.click()

		higher_price = driver.find_element_by_xpath('//*[@id="root-app"]/div/div/section/div[1]/div/div/div/div[2]/div/div/div/ul/li[3]/a')
		driver.execute_script("arguments[0].click();", higher_price)
		sleep(1)

		articles = []
		prices = []

		for i in range(5):
			article_name = driver.find_element_by_css_selector(f'#root-app > div > div > section > ol > li:nth-child({i+1}) > div > div > div.ui-search-result__content-wrapper > div.ui-search-item__group.ui-search-item__group--title > a > h2').text
			articles.append(article_name)
			article_price = driver.find_element_by_css_selector(f'#root-app > div > div > section > ol > li:nth-child({i+1}) > div > div > div.ui-search-result__content-wrapper > div.ui-search-result__content-columns > div.ui-search-result__content-column.ui-search-result__content-column--left > div.ui-search-item__group.ui-search-item__group--price > a > div > div > span.price-tag.ui-search-price__part > span.price-tag-amount > span.price-tag-fraction').text
			prices.append(article_price)
		for x in range(len(articles)):
			print(prices[x]+' ...... '+articles[x])


	def tearDown(self):
		self.driver.close()

if __name__ == "__main__":
	unittest.main()
import unittest
from selenium import webdriver
from time import sleep

class SearchMercadolibre(unittest.TestCase):

    def setUp (self):
        self.driver = webdriver.Chrome(executable_path = r'G:\Augusto\Selenium\chromedriver.exe')
        driver = self.driver
        driver.implicitly_wait(30)
        driver.maximize_window()
        driver.get("http://www.mercadolibre.com")

    def test_search_ps4(self):
        driver = self.driver

        country = driver.find_element_by_id('CO')
        country.click()

        search_field = driver.find_element_by_name('as_word')
        search_field.click()
        search_field.clear()
        search_field.send_keys('playstation 4')
        search_field.submit()
        sleep(3)

        locatation = driver.find_element_by_partial_link_text('Bogot谩 D.C.')
        locatation.click()
        sleep(3)

        condition = driver.find_element_by_partial_link_text('Nuevo')
        condition.click()
        sleep(3)

        order_menu = driver.find_element_by_class_name('ui-dropdown__link')
        order_menu.click()
        
        higher_price = driver.find_element_by_css_selector('#inner-main > aside > section.view-options > dl > div > div > div > div > ul > li.ui-list__item.ui-list__item--selected > span')
        higher_price.click()
        sleep(3)

        articles = []
        prices = []

        for i in range(5):
            article_name = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div[2]/div/h2/a/span').text
            articles.append(article_name)
            article_price = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div[2]/div/div[1]/div/span[2]').text
            prices.append(article_price)

        print(articles, prices)
            

    def tearDown(self):
        self.driver.close()

if __name__ == "__main__":
    unittest.main(verbosity = 2)```

Me sale el error: selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".ui-dropdown__link"}
  (Session info: chrome=83.0.4103.116)

No se que esta mal, alguien me ayuda pls

El Xpath que menciona el profe, no me sirvi贸 dado que cambia un poco la estructura de la lista de producto en la web de mercado libre, para eso hice un xpath m谩s flexible, que captura los productos a pesar de los cambios en cada recarga

        for i in range(8):
            article_name = driver.find_element(By.XPATH, f'//li[{i + 1}]//h2').text
            articles.append(article_name)
            article_price = driver.find_element(By.XPATH, f'//li[{i + 1}]//span[contains(@class, "andes-money-amount__fraction")]').text
            prices.append(article_price)

        for i in range(8):
            print(articles[i], "| Precio:", prices[i])

Les comparto mi c贸digo aplicando POM y al momento de hacer scrapping find_elements para obtener todos los items de forma m谩s dinamica y no depende del xpath:

**Primero el c贸digo del objeto de la pagina: **

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


class MercadoLibrePage(object):
    def __init__(self, driver=webdriver.Chrome()):
        self._driver = driver
        self._url = "https://mercadolibre.com"

    @property
    def is_loaded(self):
        WebDriverWait(self._driver, 10).until(EC.presence_of_element_located((By.NAME, 'q')))
        return True

    @property
    def get_first_five_items(self):
        items_dict = {}

        WebDriverWait(self._driver, 10).until(
            EC.presence_of_element_located((By.CLASS_NAME, 'andes-dropdown__trigger')))

        items_elements = self._driver.find_elements(By.CLASS_NAME, 'ui-search-result__content-wrapper')

        for item_element in items_elements:
            item_name = item_element.find_elements(By.TAG_NAME, 'a')[0].get_attribute('title')
            item_price = item_element.find_element(By.CLASS_NAME, 'price-tag-fraction').text
            items_dict[item_name] = item_price

            if len(items_dict) == 5:
                break

        return items_dict

    def type_search(self, keyword):
        input_field = self._driver.find_element(By.CLASS_NAME, 'nav-search-input')
        input_field.send_keys(keyword)

    def click_submit(self):
        input_field = self._driver.find_element(By.CLASS_NAME, 'nav-search-btn')
        input_field.submit()

    def search(self, keyword):
        self.type_search(keyword)
        self.click_submit()

    def click_custom(self, by_condition, by_value):
        location = self._driver.find_element(by_condition, by_value)

        self._driver.execute_script("arguments[0].click();", location)

    def select_country(self, country_id):
        self.click_custom(By.ID, country_id)

    def filter_by_new_condition(self):
        xpath_value = '//*[@id="root-app"]/div/div[2]/aside/section/div[7]/ul/li[1]/a/span[1]'
        WebDriverWait(self._driver, 10).until(EC.presence_of_element_located((By.XPATH, xpath_value)))

        self.click_custom(By.XPATH, xpath_value)

    def filter_by_bogota_ubication(self):
        xpath_value = '//*[@id="root-app"]/div/div[2]/aside/section/div[11]/ul/li[1]/a/span[1]'
        WebDriverWait(self._driver, 10).until(EC.presence_of_element_located((By.XPATH, xpath_value)))

        self.click_custom(By.XPATH, xpath_value)

    def expand_button_to_order(self):
        self.click_custom(By.CLASS_NAME, 'andes-dropdown__trigger')

    def order_from_higher_price_to_lower_price(self):
        WebDriverWait(self._driver, 10).until(
            EC.presence_of_element_located((By.CLASS_NAME, 'andes-dropdown__trigger')))
        self.expand_button_to_order()
        self.click_custom(By.XPATH, '//*[@id="andes-dropdown-m谩s-relevantes-list-option-price_desc"]/div/div/span')

    def open(self):
        self._driver.get(self._url)
        self._driver.maximize_window()

**Y ahora el c贸digo del caso de prueba haciendo uso del objeto de la p谩gina: **

import unittest
from selenium import webdriver

from SeleniumTestsPlatzi.mercado_libre_page import MercadoLibrePage


class MercadoLibreTests(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome(executable_path='./chromedriver')

    def test_mercado_libre_flow(self):
        mercado_libre = MercadoLibrePage(self.driver)

        mercado_libre.open()
        mercado_libre.select_country('CO')
        mercado_libre.search('playstation 4')
        mercado_libre.filter_by_new_condition()
        mercado_libre.filter_by_bogota_ubication()
        mercado_libre.order_from_higher_price_to_lower_price()
        items = mercado_libre.get_first_five_items

        print(items)

    def tearDown(self):
        self.driver.close()


if __name__ == "__main__":
    unittest.main(verbosity=2)

Mi c贸digo con demoras explicitas:

import unittest

from pyunitreport import HTMLTestRunner
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait


class TestingMercadoLibre(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path="./usr/bin/chromedriver")
        driver = self.driver
        driver.get("https://www.mercadolibre.com")
        driver.maximize_window()

    def test_search_ps4(self):
        driver = self.driver

        country = driver.find_element(By.ID, "CO")
        country.click()

        cookie_button = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable(
                (By.XPATH, "/html/body/div[2]/div[1]/div[2]/button[1]")
            )
        )
        cookie_button.click()

        search_field = WebDriverWait(driver, 10).until(
            EC.presence_of_element_located((By.NAME, "as_word"))
        )
        search_field.click()
        search_field.clear()
        search_field.send_keys("playstation 4")
        search_field.submit()

        location = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable(
                (
                    By.XPATH,
                    '//*[@id="root-app"]/div/div[2]/aside/section/div[10]/ul/li[1]/a/span[1]',
                )
            )
        )
        location.click()

        condition = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, "Nuevo"))
        )
        condition.click()

        order_menu = driver.find_element(
            By.CLASS_NAME, "andes-dropdown__display-values"
        )
        order_menu.click()

        higher_price = WebDriverWait(driver, 10).until(
            EC.element_to_be_clickable(
                (
                    By.CSS_SELECTOR,
                    "#andes-dropdown-m谩s-relevantes-list-option-price_desc > div > div > span",
                )
            )
        )
        higher_price.click()

        products = {}

        for i in range(5):
            article_name = driver.find_element(
                By.XPATH,
                f"/html/body/main/div/div[2]/section/ol/li[{i + 1}]/div/div/div[2]/div[1]/a/h2",
            ).text

            article_price = driver.find_element(
                By.XPATH,
                f"/html/body/main/div/div[2]/section/ol/li[{i + 1}]/div/div/div[2]/div[2]/div[1]/div[1]/div/div/div/span[1]/span[2]/span[2]",
            ).text
            products[article_name] = article_price

        print(products)

    def tearDown(self):
        self.driver.close()


if __name__ == "__main__":
    unittest.main(
        verbosity=2,
        testRunner=HTMLTestRunner(output="reports", report_name="mercadolibre"),
    )

Mi c贸digo 20/01/2023 con selenium versi贸n 4.7.2. y HtmlTestRunner

Archivo test_mercado_libre.py

import unittest
from selenium import webdriver
from HtmlTestRunner import HTMLTestRunner
# submodulo  para usar el dropdown
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
# Herramienta para seleccionar elementos de la web con sus selectores
from selenium.webdriver.common.by import By

# Herramienta para hacer uso de las expected conditions y esperas explicitas
from selenium.webdriver.support.ui import WebDriverWait


# Importar esperar explicitas
from selenium.webdriver.support import expected_conditions as EC

from time import sleep
from mercado_libre_page import MercadoLibrePage


class GoogleTest(unittest.TestCase):

    # Realiza todo lo necesario antes de empezar la prueba
    @classmethod  # Decorador para que las distintas paginas corran en una sola pesta帽a
    def setUpClass(cls):
        cls.driver = webdriver.Chrome(
            service=Service(ChromeDriverManager().install()))
        driver = cls.driver
        # esperamos 10 seg antes de realizar la siguiente accion
        driver.implicitly_wait(5)
        driver.maximize_window()

    def test_search(self):
        ml = MercadoLibrePage(self.driver)
        ml.open_page()
        ml.select_country('CO')
        ml.accept_coockies()
        ml.ignore_location()
        ml.search('Playstation 4')
        ml.select_product_condition('Nuevo')
        ml.select_product_location('BogotD.C.')
        ml.order_by('Mayor precio')
        products = ml.get_products(5)
        print(products)

    @classmethod
    def tearDownClass(cls):
        # Cerramos el navegador una vez terminadas las pruebas
        cls.driver.quit()


if __name__ == "__main__":
    unittest.main(verbosity=2, testRunner=HTMLTestRunner(
        output='reports/MercadoLibreTest', report_name='MercadoLibreTest_report'))
 

Archivo mercado_libre_page.py

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select


class MercadoLibrePage(object):
    def __init__(self, driver):
        self._driver = driver
        self._url = 'https://mercadolibre.com/'
        self.search_locator = 'cb1-edit'
        self.cookie_acept_locator = '/html/body/div[2]/div[1]/div[2]/button[1]'
        self.ignore_location_locator = '/html/body/div[3]/div/div/div[2]/div/div/div[2]/button[1]'
        self.filters_locator = 'ui-search-filter-name'
        self.order_menu_locator = '//*[@id="root-app"]/div/div[2]/section/div[1]/div/div/div/div[2]/div/div/button'
        self.oder_by_options_locator = 'andes-list__item-primary'
        self.product_name_locator = '//*[@id="root-app"]/div/div[2]/section/ol/li/div/div/div[2]/div/a/h2'
        self.product_price_locator = '//*[@id="root-app"]/div/div[2]/section/ol/li/div/div/div[2]/div[2]/div[1]/div[1]/div/div/div/span[1]/span[2]/span[2]'
        self.products_locator = '//*[@id="root-app"]/div/div[2]/section/ol'

    @property
    def keyword(self):
        input_field = self._driver.find_element(By.NAME, self.search_locator)
        return input_field.get_attribute('value')

    def select_country(self, country_id):
        country = WebDriverWait(self._driver, 10).until(
            EC.presence_of_element_located(
                (By.XPATH, f'//a[@id="{country_id}"]'))
        )
        country.click()

    def open_page(self):
        self._driver.get(self._url)

    def type_search(self, keyword):
        input_field = WebDriverWait(self._driver, 10).until(
            EC.presence_of_element_located(
                (By.ID, self.search_locator))
        )
        input_field.clear()
        input_field.send_keys(keyword)

    def click_submit(self):
        input_field = self._driver.find_element(By.ID, self.search_locator)
        input_field.submit()

    def search(self, keyword):
        self.type_search(keyword)
        self.click_submit()

    def accept_coockies(self):
        cookies_accept = WebDriverWait(self._driver, 10).until(
            EC.presence_of_element_located((By.XPATH, self.cookie_acept_locator)))
        cookies_accept.click()

    def ignore_location(self):
        location = WebDriverWait(self._driver, 10).until(
            EC.presence_of_element_located((By.XPATH, self.ignore_location_locator)))
        location.click()

    def get_condition_filters(self):
        filters = WebDriverWait(self._driver, 10).until(
            EC.visibility_of_any_elements_located((By.CLASS_NAME, self.filters_locator)))

        filters_dictionary = {}

        # Creamos un diccionario de filtros
        for element in filters:
            filters_dictionary[element.text] = element
        return filters_dictionary

    def select_product_condition(self, condition):

        filters = self.get_condition_filters()
        print(filters[condition])

        filters[condition].click()

    def select_product_location(self, location):
        try:
            filters = self.get_condition_filters()
            filters[location].click()
        except Exception as e:
            print(e)
            print("Error at tryint to select the product location")

    def get_order_by_filters(self):
        order_by_menu = WebDriverWait(self._driver, 10).until(
            EC.presence_of_element_located((By.XPATH, self.order_menu_locator)))
        order_by_menu.click()

        orders_by_options = WebDriverWait(self._driver, 10).until(
            EC.visibility_of_any_elements_located((By.CLASS_NAME, self.oder_by_options_locator)))

        filters_dictionary = {}

        # Creamos un diccionario de filtros
        for element in orders_by_options:
            filters_dictionary[element.text] = element
        return filters_dictionary

    def order_by(self, order):
        filters = self.get_order_by_filters()
        filters[order].click()

    def get_products(self, quantity):
        products = WebDriverWait(self._driver, 10).until(
            EC.presence_of_element_located(
                (By.XPATH, self.products_locator))
        )
        products_names = products.find_elements(
            By.XPATH, self.product_name_locator)[:quantity]
        products_prices = products.find_elements(
            By.XPATH, self.product_price_locator)[:quantity]

        print(f"- Total products: {len(products_names)}")

        products_dictionary = {
            products_names[i].text: products_prices[i].text for i in range(quantity)}
        return products_dictionary

Me he tomado una buena cantidad de tiempo para hacer el c贸digo, para agregarle varias cositas:

  • Busqueda de Productos con cualquier cantidad y filtros
  • Ingresar los productos usando ddt y un archivo .csv
  • Una semi metolodog铆a de POM, no lo termine de entender bien, pero es c贸mo un
    obj que nos permite hacer diferentes metodos y tiene propiedades sobre una p谩gina para hacer el testing.

Lo que m谩s me costo fue ubicar bien los elementos, ya que me estaba dando alg煤n que otro problema con los xpath que tiene MercadoLibre y en general, tampoco tienen la mejor estructura.

C贸digo:

test_mercado_libre.py

#!/usr/bin/python

import unittest
from csv import reader as csv_reader
from ddt import ddt, data, unpack
from selenium import webdriver
from mercado_libre_page import MercadoLibrePage

def get_csv_data (csv_url):
    rows = []

    with open(csv_url, encoding="UTF-8", mode="r") as csv_file:
        reader = csv_reader(csv_file)
        next(reader, None)

        for row in reader:
            rows.append(row)

    return rows

def convert_filters_to_dict (filters_arr, separator=':'):
    filter_dict = {}

    for value in filters_arr:
        filter_name, filter_value = value.split(separator)

        filter_dict[filter_name] = filter_value

    return filter_dict

@ddt
class MercadoLibreTests (unittest.TestCase):
    @classmethod
    def setUp (cls):
        cls.options = webdriver.ChromeOptions()
        cls.options.binary_location = '/usr/bin/brave'
        cls.driver = webdriver.Chrome(executable_path='/home/bl4ky113/bin/chromedriver', options=cls.options)
        cls.driver.maximize_window()

    @data (*get_csv_data('./product_info.csv'))
    @unpack

    def test_search_elements (self, element, num_elements, *filters):
        mercadolibre = MercadoLibrePage(self.driver)
        filter_dict = convert_filters_to_dict(filters)

        mercadolibre.open_contry_page()
        mercadolibre.search_product(element)
        
        for filter_name, filter_value in filter_dict.items():
            if filter_name == "Orden":
                mercadolibre.filter_by(filter_value)
            else:
                mercadolibre.add_filter(filter_name, filter_value)

        product_list = mercadolibre.get_product_list(int(num_elements))

        print(*product_list)

    @classmethod
    def tearDown (cls):
        cls.driver.quit()

if __name__ == "__main__":
    unittest.main(verbosity=2)

mercado_libre_page.py

#!/usr/bin/python

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class MercadoLibrePage (object):
    def __init__ (self, driver):
        self._driver = driver
        self._url = "https://mercadolibre.com/"
        self._country_name = "Colombia"
        self._country_code = "co"
        self.search_locator = 'as_word'

    @property
    def is_in_country_page (self):
        return f".com.{self._country_code}" in self._driver.current_url

    @property
    def _len_special_filters (self):
        if not self.is_in_country_page:
            return None

        WebDriverWait(self._driver, 10).until(
            EC.presence_of_element_located(
                (By.XPATH, '//*[@id="root-app"]/div/div/aside/div[3]/div[1]/ul/li/section')
            )
        )

        len_special_filters = len(self._driver.find_elements_by_xpath(
            '//*[@id="root-app"]/div/div/aside/div[3]/div/ul/li/section'
        ))

        return len_special_filters

    @property
    def _available_filters (self):
        if not self.is_in_country_page:
            return None

        WebDriverWait(self._driver, 10).until(
            EC.element_to_be_clickable(
                (By.XPATH, '//*[@id="root-app"]/div/div/aside/div[3]/div[5]/ul/li[1]/form/button')
            )
        )

        filter_titles = self._driver.find_elements_by_xpath(
            '//*[@id="root-app"]/div/div/aside/div[3]/div/div'
        )

        return filter_titles

    def _open_url (self):
        self._driver.get(self._url)

    def _get_filter_options (self, filter_index):
        if not self.is_in_country_page:
            return None

        filter_options_names = self._driver.find_elements_by_xpath(
            f'//*[@id="root-app"]/div/div/aside/div[3]/div[{filter_index}]/ul/li/form/button/span[1]'
        )
        filter_options_btn = self._driver.find_elements_by_xpath(
            f'//*[@id="root-app"]/div/div/aside/div[3]/div[{filter_index}]/ul/li/form/button'
        )

        filter_options = {
            filter_options_names[i].text: filter_options_btn[i]
            for i in range(len(filter_options_names))
        }

        return filter_options

    def _get_order_options (self):
        WebDriverWait(self._driver, 10).until(
            EC.presence_of_element_located(
                (By.XPATH, '//*[@id="root-app"]/div/div/section/div[1]/div/div/div/div[2]/div/div/div/ul')
            )
        )

        filter_options_names = self._driver.find_elements_by_xpath(
            '//*[@id="root-app"]/div/div/section/div[1]/div/div/div/div[2]/div/div/div/ul/a/div[1]/span'
        )
        filter_options_obj = self._driver.find_elements_by_xpath(
            '//*[@id="root-app"]/div/div/section/div[1]/div/div/div/div[2]/div/div/div/ul/a'
        )

        filter_options = {
            filter_options_names[i].text: filter_options_obj[i]
            for i in range(len(filter_options_names))
        }

        return filter_options

    def _open_order_by_dropdown (self):
        if not self.is_in_country_page:
            return None

        filter_by_input = self._driver.find_element_by_xpath(
            '//*[@id="root-app"]/div/div/section/div[1]/div/div/div/div[2]/div/div/button'
        )
        self._js_click(filter_by_input)

    def _get_product_info (self, product, product_index):
        product_info = {}
        product_info["name"] = self._driver.find_element_by_xpath(
            f'//*[@id="root-app"]/div/div/section/ol/li[{product_index}]/div/div/div[2]/div[1]/a[1]/h2'
        ).text
        product_info["value"] = self._driver.find_element_by_xpath(
            f'//*[@id="root-app"]/div/div/section/ol/li[{product_index}]/div/div/div[2]/div[2]/div[1]/div[1]/div/div/div/span[1]/span[2]/span[2]'
        ).text

        return product_info

    def _get_products (self, size_of_the_list):
        product_list = []
        product_index = 1

        while len(product_list) <= size_of_the_list:
            product = self._driver.find_element_by_xpath(
                f'//*[@id="root-app"]/div/div/section/ol/li[{product_index}]'
            )
            product_info = self._get_product_info(product, product_index)

            product_list.append(product_info)
            product_index += 1

        return product_list

    def _js_click(self, element):
        self._driver.execute_script('arguments[0].click()', element)

    def open_contry_page (self):
        self._open_url()

        WebDriverWait(self._driver, 10).until(
            EC.presence_of_element_located(
                (By.ID, self._country_code.upper())
            )
        )

        self._driver.find_element_by_id(self._country_code.upper()).click()

        return self.is_in_country_page

    def search_product (self, product_keyword):
        if not self.is_in_country_page:
            return None

        search_input = self._driver.find_element_by_name(self.search_locator)
        search_input.send_keys(product_keyword)
        search_input.submit()

    def add_filter (self, name, value):
        if not self.is_in_country_page:
            return None

        filter_index = 1 + self._len_special_filters
        for filter_ in self._available_filters:
            if filter_.text == name:
                filter_options = self._get_filter_options(filter_index)
                self._js_click(filter_options[value])
                break

            filter_index += 1

    def filter_by (self, order):
        if not self.is_in_country_page:
            return None

        self._open_order_by_dropdown()
        filter_options = self._get_order_options()

        self._js_click(filter_options[order])

    def get_product_list (self, number_of_elements):
        if not self.is_in_country_page:
            return None

        product_list = self._get_products(number_of_elements)

        return product_list

Y el .csv

ProductName,NumberOfProducts,Filers*
xbox one s,5,Condici贸n:Nuevo,Orden:Mayor precio,Ubicaci贸n:Bogot谩 D.C.
playstation 4,5,Condici贸n:Usado,Orden:Menor precio 

El 4to art铆culo por alguna raz贸n me complicaba el scraping. Tuve que cambiar un poco el c贸digo 馃槗

El c贸digo refactorizado (revisar el comentario de abajo) utilizando los cambios que har铆a. Espero que le sea de utilidad a la hora de crear automatizaciones a alguien m谩s.

Archivo de constantes:

from selenium.webdriver.common.by import By
from string import Template

#Url principal del sitio a accesar.
URL = 'https://www.mercadolibre.com'
#Busqueda a realizar.
SEARCH = 'playstation 4'
#Tiempo de espera por acci贸n.
TIME_FOR_ACTION = 1

#Pa铆s.
COUNTRY = (By.ID, 'CO')
#Campo de busqueda.
SEARCH_FIELD = (By.NAME, 'as_word')
#Locaci贸n.
LOCATION = (By.XPATH, '//button[@aria-label="Bogot谩 D.C."]')
#Condici贸n: Nuevo, Usado o Reacondicionado. 
CONDITION = (By.XPATH, '//button[@aria-label="Nuevo"]')
#Menu (dropdown) de Ordenar por.
ORDER_MENU = (By.CLASS_NAME, 'andes-dropdown__trigger')
#Opci贸n del menu: Mayor precio.
HIGHER_PRICE = (By.PARTIAL_LINK_TEXT, 'Mayor precio')

#Articulos de compra.
ARTICLES = (By.CLASS_NAME, 'ui-search-item__title')
#Xpath general de los precios.
PRICES_XPATH = Template('//*[@id="root-app"]/div/div/section/ol/li[$num]/div/div/div[2]/div[2]/div[1]/div[1]/div/div/div/span[1]/span[2]/span[2]')
#Precios de los articulos.
PRICES = (By.XPATH, PRICES_XPATH)

#True si se cliquea de forma estandar.
#False si se cliquea mediante Javascript.
CLICKABLE = {
    'country' : True,
    'search_field' : True,
    'location' : False,
    'condition' : False,
    'order_menu' : True,
    'higher_price' : False,
}

Archivo de testing:

#Para los tests.
import unittest
from pyunitreport import HTMLTestRunner

#Paras la automatizaci贸n.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service

#Excepci贸n al no encontrar un elemento Web.
from selenium.common.exceptions import NoSuchElementException

#Para las pausas.
from time import sleep

#Cargamos las constantes.

#Texto.
from merc_constantes import URL, SEARCH, TIME_FOR_ACTION
#Elementos a usar.
from merc_constantes import COUNTRY, SEARCH_FIELD, CONDITION, LOCATION, ORDER_MENU,  HIGHER_PRICE
#Elementos a leer.
from merc_constantes import ARTICLES, PRICES
#Si se cliquea de forma estandar o no.
from merc_constantes import CLICKABLE

service = Service(r'C:\Users\carlo\Desktop\chromedriver_win32\chromedriver.exe')

class TestingMercadoLibre(unittest.TestCase):

    def setUp(self):
        driver = self.driver = webdriver.Chrome(service=service)
        driver.get(URL)
        driver.maximize_window()

    #Cuando no funciona el click mediante Webdriver, usamos javascript.
    #https://www.selenium.dev/selenium/docs/api/py/webdriver_remote/selenium.webdriver.remote.webdriver.html#selenium.webdriver.remote.webdriver.WebDriver.execute_script
    def click_javascript(self, web_element):
        self.driver.execute_script("arguments[0].click();", web_element)

    #Metodo para definir el tipo de clickeo en el elemento web.
    def click_WD(self, web_element, clickable):
        if clickable:
            web_element.click()
        else:
            self.click_javascript(web_element)

    #Metodo para reducir la acci贸n de seleccionar
    # y clickear a una sola funci贸n.
    def select_and_click(self, terms, clickable):
        web_element = self.driver.find_element(*terms)
        self.click_WD(web_element, clickable)
        return web_element

    def test_search_ps4(self):
        driver = self.driver
        s_c = self.select_and_click

        #Seleccionamos Colombia.
        s_c(COUNTRY, CLICKABLE['country'])

        #Seleccionamos el buscador, limpiamos, escribimos y buscamos.
        search_field = s_c(SEARCH_FIELD, CLICKABLE['search_field'])
        search_field.clear()
        search_field.send_keys(SEARCH)
        search_field.submit()
        sleep(TIME_FOR_ACTION)

        #Filtramos por locaci贸n: Bogot谩.
        s_c(LOCATION, CLICKABLE['location'])
        sleep(TIME_FOR_ACTION)

        #Filtramos por antiguedad: Nuevo.
        s_c(CONDITION, CLICKABLE['condition'])
        sleep(TIME_FOR_ACTION)

        #Cliqueamos el dropdown de Ordenar por.
        s_c(ORDER_MENU, CLICKABLE['order_menu'])

        #Ordenamos por: Mayor precio.
        s_c(HIGHER_PRICE, CLICKABLE['higher_price'])
        sleep(TIME_FOR_ACTION)
        
        #Creamos un diccionario con los articulos de la pagina actual
        #como llaves por poseer una clase en com煤n.
        articles_prices = {i.text:None for i in driver.find_elements(*ARTICLES)}

        #Buscamos el precio correspondiente a cada articulo.
        #Como tanto los precios, como las cuotas poseen 
        #las mismas clases, los precios deben o filtrarse,
        #o como en el caso actual usar el Xpath.
        for i, article in enumerate(articles_prices.keys()):
            #Existen articulos sin el precio explicito.            
            try:
                p_method = PRICES[0]
                p_key = PRICES[1].substitute(num=i + 1)
                price = driver.find_element(p_method, p_key).text
            except NoSuchElementException:
                price = 'No disponible'

            #Almacenamos el precio perteneciente al articulo actual.
            articles_prices[article] = price

        #Mostramos los primeros 5 articulos en pantalla.
        #Pero podemos mostrarlos todos si queremos.
        articles_to_show = 5
        for article, price in list(articles_prices.items())[:articles_to_show]:
            print(article, ' : ', price)

    def tearDown(self):
        self.driver.quit()

if __name__ == "__main__":
    unittest.main(verbosity = 2, testRunner = HTMLTestRunner(output = 'reports', report_name = 'ml-report'))

Aport贸 el c贸digo comentado para el 17/3/2022

**Hice algunos cambios:
**

  • Cree un nuevo m茅todo que contiene el cliqueo mediante javascript, que es el m茅todo que ya han comentado si no funciona elemento.click()
  • Para la Locaci贸n y la Antig眉edad uso el Xpath, con el atributo aria-label. Me pareci贸 el m茅todo m谩s corto y f谩cil de adaptar.
  • La clase del Dropdown cambio.
  • Para el 鈥楳ayor precio鈥, use partial_link_text, es m谩s corto que el selector de css.
  • Use un diccionario como recomend贸 otro usuario, para art铆culos y precios. Y los guarda todos por defecto.
  • Para los art铆culos use una clase que pose铆an en com煤n.
  • Para los precios no pude hacer esto, as铆 que use el Xpath y un for.
  • Como algunos elementos no ten铆an precio disponible, use una try-except para integrarlos en el diccionario.
  • Hay una variable con la cantidad de art铆culos y precios a visualizar.

**Cambios que har铆a si fuera un script de uso frecuente: **

  • En un archivo anexo guardar las siguiente constantes:
  1. M茅todo de b煤squeda (Clase, ID, Xpath, etc), la clave para dicha b煤squeda. [As铆 si un m茅todo falla o una clave es cambiada, se puede reemplazar con facilidad]. En una tupla, luego se desempaqueta en find_element.
  2. 驴Click 鈥渆st谩ndar鈥 o Click Javascript? As铆 como los elementos cambian de m茅todo y clave. Tambi茅n pueden dejar de ser cliqueables por el m茅todo est谩ndar. Por lo que puede generarse otro m茅todo de clase al cual se le pasar铆a como argumento el 鈥渆lemento a cliquear鈥 y un booleano de 鈥渃lick estandar s铆 o no鈥, de ese paso en particular. As铆 podr铆an alternarse los clicks, volver uno de javascript al estandar y viceversa. Estas variables booleanas serian las que se almacenar铆an como constantes (Otra alternativa ser铆a pasar todos los Clicks Estandar a Click Javascript, si no se tienen problemas con esto, aunque no lo prefiero por eficiencia y limpieza de c贸digo).
  3. La cantidad de art铆culos y precios a mostrar.

Con esto para peque帽os cambios deber铆a seguir funcionando en el tiempo y las modificaciones ser铆an peque帽as y f谩ciles de aplicar.

#Para los tests.
import unittest
from pyunitreport import HTMLTestRunner

#Paras la automatizaci贸n.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

#Excepci贸n al no encontrar un elemento Web.
from selenium.common.exceptions import NoSuchElementException

#Para las pausas.
from time import sleep

service = Service(r'C:\Users\carlo\Desktop\chromedriver_win32\chromedriver.exe')

class TestingMercadoLibre(unittest.TestCase):

    def setUp(self):
        driver = self.driver = webdriver.Chrome(service=service)
        driver.get('https://www.mercadolibre.com')
        driver.maximize_window()

    #Cuando no funciona el click mediante Webdriver, usamos javascript.
    #https://www.selenium.dev/selenium/docs/api/py/webdriver_remote/selenium.webdriver.remote.webdriver.html#selenium.webdriver.remote.webdriver.WebDriver.execute_script
    def click_javascript(self, web_element):
        self.driver.execute_script("arguments[0].click();", web_element)

    def test_search_ps4(self):
        driver = self.driver

        #Seleccionamos Colombia.
        country = driver.find_element(By.ID, 'CO')
        country.click()

        #Seleccionamos el buscador, limpiamos, escribimos y buscamos.
        search_field = driver.find_element(By.NAME, 'as_word')
        search_field.click()
        search_field.clear()
        search_field.send_keys('playstation 4')
        search_field.submit()
        sleep(3)

        #Filtramos por locaci贸n: Bogot谩.
        xpath_l = '//button[@aria-label="Bogot谩 D.C."]'
        location = driver.find_element(By.XPATH, xpath_l)
        #location.click()
        self.click_javascript(location)
        sleep(3)

        #Filtramos por antiguedad: Nuevo.
        xpath_c = '//button[@aria-label="Nuevo"]'
        condition = driver.find_element(By.XPATH, xpath_c)
        #condition.click()
        self.click_javascript(condition)
        sleep(3)

        #Cliqueamos el dropdown de Ordenar por.
        order_menu = driver.find_element(By.CLASS_NAME, 'andes-dropdown__trigger')
        order_menu.click()

        #Ordenamos por: Mayor precio.
        higher_price = driver.find_element(By.PARTIAL_LINK_TEXT, 'Mayor precio')
        #higher_price.click()
        self.click_javascript(higher_price)
        sleep(3)
        
        #Creamos un diccionario con los articulos de la pagina actual
        #como llaves por poseer una clase en com煤n.
        articles_prices = {i.text:None for i in driver.find_elements(By.CLASS_NAME, 'ui-search-item__title')}

        #Buscamos el precio correspondiente a cada articulo.
        #Como tanto los precios, como las cuotas poseen 
        #las mismas clases, los precios deben o filtrarse,
        #o como en el caso actual usar el Xpath.
        for i, article in enumerate(articles_prices.keys()):
            xpath_ap = f'//*[@id="root-app"]/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[2]/div[1]/div[1]/div/div/div/span[1]/span[2]/span[2]'

            #Existen articulos sin el precio explicito.            
            try:
                price = driver.find_element(By.XPATH, xpath_ap).text
            except NoSuchElementException:
                price = 'No disponible'

            #Almacenamos el precio perteneciente al articulo actual.
            articles_prices[article] = price

        #Mostramos los primeros 5 articulos en pantalla.
        #Pero podemos mostrarlos todos si queremos.
        articles_to_show = 5
        for article, price in list(articles_prices.items())[:articles_to_show]:
            print(article, ' : ', price)

    def tearDown(self):
        self.driver.quit()

if __name__ == "__main__":
    unittest.main(verbosity = 2, testRunner = HTMLTestRunner(output = 'reports', report_name = 'ml-report'))

No pude obtener los textos de la tabla desde el xpath

from time import sleep
import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class MercadoLibreTest(unittest.TestCase):
    
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path=r'C:/Users/Usuario/Documents/platzi/python/Clases del Curso de Introducci贸n a Selenium con Python/chromedriver.exe')
        driver = self.driver
        driver.get('https://mercadolibre.com')
        driver.maximize_window()
    
    def test_seach_ps4(self):
        driver = self.driver

        #Paso 1
        driver.find_element(By.ID, 'CO').click()

        #Paso 2
        field_search = driver.find_element(By.NAME, 'as_word')
        field_search.click()
        field_search.clear()
        field_search.send_keys('playstation 4')
        field_search.submit()
        sleep(3)

        #Paso 3
        location = driver.find_element(By.PARTIAL_LINK_TEXT, 'Bogot谩 D.C.')
        driver.execute_script("arguments[0].click();", location)
        sleep(3)

        #Paso 4
        condition = driver.find_element(By.PARTIAL_LINK_TEXT, 'Nuevo')
        driver.execute_script("arguments[0].click();", condition)
        sleep(3)

        #Paso 5
        order_menu = driver.find_element(By.CLASS_NAME, 'andes-dropdown__trigger')
        order_menu.click()
        higher_price = driver.find_element(By.CSS_SELECTOR, '#root-app > div > div > section > div.ui-search-view-options__container > div > div > div > div.ui-search-sort-filter > div > div > div > ul > a:nth-child(3) > div.andes-list__item-first-column > div.andes-list__item-text > div')
        higher_price.click()
        sleep(3)

        #Paso 6
        articles = []
        prices = []

        # for i in range(5):
        #     article_name = driver.find_element(By.XPATH, f'//*[@id="root-app"]/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[2]/a/h2').text
        #     articles.append(article_name)
        #     article_price = driver.find_element(By.XPATH, f'//*[@id="root-app"]/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[3]/div[1]/div[1]/div/div/div/span[1]/span[2]/span[2]').text
        #     prices.append(article_price)

        # print(articles, prices)

        table_elements_li = driver.find_elements(By.CSS_SELECTOR, '#root-app > div > div > section > ol > li')

        count_find_items = len(table_elements_li)

        item = 1
        while ((count_find_items > 5 and item <= 5) or (count_find_items <= 5 and item != count_find_items)):
            table_title_element = table_elements_li[item - 1].find_element(By.CLASS_NAME, 'ui-search-item__title').text
            table_simbol_price_element = table_elements_li[item - 1].find_element(By.CLASS_NAME, 'price-tag-symbol').text
            table_price_element = table_elements_li[item - 1].find_element(By.CLASS_NAME, 'price-tag-fraction').text
            articles.append(table_title_element)
            prices.append(table_simbol_price_element + ' ' + table_price_element)
            item += 1

        print(articles, prices)
        sleep(3)


    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)

Comparto mi codigo!. Muchas gracias

import unittest
from selenium import webdriver
from time import sleep

class MercadoLibre(unittest.TestCase):
    

    def setUp(self):
        self.driver = webdriver.Chrome("D:\webdriver-chrome/chromedriver.exe")
        driver = self.driver
        driver.implicitly_wait(15)
        driver.maximize_window()
        driver.get('https://mercadolibre.com')
        
    def test_search_ps4(self):
        driver = self.driver
        country = driver.find_element_by_id('CO')
        country.click()
        sleep(3)

        search_field = driver.find_element_by_name('as_word')
        search_field.click()
        search_field.clear()
        search_field.send_keys('playstation 4')
        search_field.submit()
        sleep(3)


        location = driver.find_element_by_partial_link_text('Bogot谩 D.C.')
        driver.execute_script("arguments[0].click();", location)
        sleep(3)

        condition = driver.find_element_by_partial_link_text('Nuevo')
        driver.execute_script("arguments[0].click();", condition)
        sleep(3)

        order_menu = driver.find_element_by_class_name('andes-dropdown__trigger')
        order_menu.click()
        higher_price = driver.find_element_by_css_selector('#root-app > div > div > section > div.ui-search-view-options__container > div > div > div > div.ui-search-sort-filter > div > div > div > ul > a:nth-child(3) > div.andes-list__item-first-column > div.andes-list__item-text > div')
        higher_price.click()
        sleep(3)

        articles = []
        prices = []

        for i in range(5):
            article_name = driver.find_element_by_xpath(f'//*[@id="root-app"]/div/div/section/ol/li[{i+1}]/div/div/div[2]/div[1]/a/h2').text
            articles.append(article_name)
            article_price = driver.find_element_by_xpath(f'//*[@id="root-app"]/div/div/section/ol/li[{i+1}]/div/div/div[2]/div[2]/div[1]/div[1]/div/div/span[1]/span[2]/span[2]').text
            prices.append(article_price)

        print(articles,prices)

    def tearDown(self):
        self.driver.close()

if __name__ == "__main__":
    unittest.main(verbosity = 2)

El TestCase es el siguiente

import unittest
from selenium import webdriver
from mercado_page import MercadoPage


class MercadoTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        cls.driver = webdriver.Chrome(executable_path=r'./chromedriver.exe')
        cls.driver.maximize_window()
    
    def test_search(self):
        mercado = MercadoPage(self.driver)
        mercado.open()
        mercado.select_country('Colombia')
        mercado.type_search('playstation 4')
        mercado.click_submit()
        mercado.acepted_politcal()
        mercado.select_filter('Nuevo')
        mercado.select_filter('Bogot谩 D.C.')
        mercado.order_by()
        mercado.get_five_productos()

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)

Para el page use

from selenium.webdriver.common.by import By


class MercadoPage(object):

    def __init__(self, driver):
        self.driver = driver
        self.url = 'https://www.mercadolibre.com'
        self.search_locator = 'as_word'
    
    def open(self):
        self.driver.get(self.url)
        self.driver.maximize_window()

    def select_country(self, country):
        country = self.driver.find_element(By.LINK_TEXT, country)
        country.click()

    def type_search(self, keywords):
        text_field = self.driver.find_element(By.NAME, self.search_locator)
        text_field.send_keys(keywords)

    def click_submit(self):
        text_field = self.driver.find_element(By.NAME, self.search_locator)
        text_field.submit()
    
    def acepted_politcal(self):
        acepted = self.driver.find_element(By.ID, 'newCookieDisclaimerButton')
        acepted.click()
        close = self.driver.find_element(By.CLASS_NAME, 'andes-tooltip-button-close')
        close.click()
    def select_filter(self, filter):
        column_filter = self.driver.find_element(By.CSS_SELECTOR, '#root-app > div > div > aside')
        filter_select = column_filter.find_element(By.PARTIAL_LINK_TEXT, filter)
        filter_select.click()
    
    def order_by(self):
        button_order = self.driver.find_element(By.XPATH, '//*[@id="root-app"]/div/div/section/div[1]/div/div/div/div[2]/div/div/button')
        button_order.click()
        field_order = self.driver.find_element(By.XPATH, '//*[@id="root-app"]/div/div/section/div[1]/div/div/div/div[2]/div/div/div/ul/a[2]')
        field_order.click()
    
    def get_five_productos(self):
        products = self.driver.find_elements(By.CLASS_NAME, 'ui-search-layout__item')
        for i in range(5):
            product = products[i].find_element(By.CLASS_NAME, 'price-tag-fraction')
            print(product.text)

El mejor curso que he visto, que crack H茅ctor

Aqu铆 mi c贸digo! Usando try y except en caso de que te salga un art铆culo recomendado (cambian sus nodos en la estructura de HTML), usando un diccionarios en lugar de solo listas, etc.

import unittest
from selenium import webdriver
from time import sleep
from selenium.common.exceptions import NoSuchElementException

class TestingMercadoLibre(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome(executable_path='./chromedriver')
        driver = self.driver
        driver.get('https://mercadolibre.com/')
        driver.maximize_window()
    
    def test_search_ps4(self):
        driver = self.driver

        country = driver.find_element_by_id('CO')
        country.click()

        search_field = driver.find_element_by_name('as_word')
        search_field.click()
        search_field.clear()
        search_field.send_keys('playstation 4')
        search_field.submit()
        sleep(3)

        location = driver.find_element_by_partial_link_text('Bogot谩 D.C.')
        # location.click()
        driver.execute_script("arguments[0].click();", location)
        sleep(3)

        condition = driver.find_element_by_partial_link_text('Nuevo')
        # condition.click()
        driver.execute_script("arguments[0].click();", condition)
        sleep(3)

        order_menu = driver.find_element_by_class_name(
            'andes-dropdown__trigger'
            )
        order_menu.click()
        higher_price = driver.find_element_by_xpath(
            '//*[@id="root-app"]/div/div/section/div[1]/div/div/div/div[2]/div/div/div/ul/a[2]/div[2]/div[2]/div'
            )
        higher_price.click()
        sleep(3)

        articles = []
        
        for i in range(5):
            try:
                article_name = driver.find_element_by_xpath(
                    f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[1]/a/h2'
                    ).text 
                article_price = driver.find_element_by_xpath(
                    f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[2]/div[1]/div[1]/a/div/div/span[1]/span[2]/span[2]'
                    ).text
            except NoSuchElementException:
                article_name = driver.find_element_by_xpath(
                    f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[2]/a/h2'
                    ).text
                article_price = driver.find_element_by_xpath(
                    f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[3]/div[1]/div[1]/a/div/div/span[1]/span[2]/span[2]'
                    ).text
            
            article = {'name': article_name, 'price': article_price}
            articles.append(article)
        print(articles)

    
    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2) 

Un poco diferente, evitando los xPaths:

import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By


class TestMercadoLibre(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path=r'chromedriver')
        driver = self.driver
        driver.implicitly_wait(10)
        driver.maximize_window()
        driver.get("https://www.mercadolibre.com/")

    def test_search_in_mercadolibre(self):
        self.driver.find_element(By.ID, "CO").click()
        driver = self.driver
        driver.implicitly_wait(5)
        search_field = driver.find_element(By.NAME, "as_word")
        search_field.click()
        search_field.clear()
        search_field.send_keys("playstation 4")
        search_field.submit()
        city = driver.find_element(By.PARTIAL_LINK_TEXT, "Bogot谩 D.C.")
        driver.execute_script("arguments[0].click();", city)
        state = driver.find_element(By.PARTIAL_LINK_TEXT, "Nuevo")
        driver.execute_script("arguments[0].click();", state)
        articles = driver.find_elements(By.CLASS_NAME, "ui-search-item__title")
        prices = driver.find_elements(By.CLASS_NAME, "price-tag-fraction")
        for i in range(5):
            print(f'Art铆culo {i+1}:{articles[i].text}, {prices[i].text}')
        print(results)

    def tearDown(self):
        self.driver.close()


if __name__ == "__main__":
    unittest.main(verbosity=2)

Me tomo tiempo, pero aqu铆 est谩 mi c贸digo.

import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


class MercadoLibre(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(service=Service('./chromedriver'))
        driver = self.driver
        driver.implicitly_wait(30)
        driver.maximize_window()
        # 1 go to ML
        driver.get('https://mercadolibre.com/')

    def test_tecnique(self):
        driver = self.driver
        country = driver.find_element(By.ID, 'MX')
        country.click()
        # 2 select country is MX
        self.assertTrue('mx' in self.driver.current_url)

        search_field = driver.find_element(By.NAME, 'as_word')
        search_field.clear()
        search_field.send_keys('Playstation 4')
        search_field.submit()
        # 3 search playstation 4
        # self.asserTrue()

        condition_new = driver.find_element(By.PARTIAL_LINK_TEXT, 'Nuevo')
        driver.execute_script("arguments[0].click();", condition_new)       
        # 4 filter by condition Nuevos
        
        # 5 filter by location Nuevo Le贸n 
        location_state = driver.find_element(By.PARTIAL_LINK_TEXT, 'Nuevo Le贸n')
        driver.execute_script("arguments[0].click();", location_state)       

        menu_order = driver.find_element(By.XPATH, '//*[@id="root-app"]/div/div[1]/section/div[1]/div/div/div/div[2]')
        menu_order.click()
        higher_price = driver.find_element(By.XPATH,'//*[@id="root-app"]/div/div[1]/section/div[1]/div/div/div/div[2]/div/div/div/ul/a[2]')
        higher_price.click()
        # 6 sort by mayor to menor precio

        articles = []
        prices = []

        for i in range(5):
            if i == 0:
                article_name = driver.find_element(By.XPATH,f'/html/body/main/div/div[1]/section/ol/li[{i + 1}]/div/div/div[2]/div[2]/a/h2').text
                articles.append(article_name)
            elif i < 4 and i > 0:
                article_name = driver.find_element(By.XPATH,f'/html/body/main/div/div[1]/section/ol/li[{i + 2}]/div/div/div[2]/div[1]/a/h2').text
                articles.append(article_name)
            else:
                article_name = driver.find_element(By.XPATH,f'/html/body/main/div/div[1]/section/ol/li[{i + 1}]/div/div/div[2]/div[1]/a[1]/h2').text
                articles.append(article_name)

        for j in range(5):
            if j == 0:
                article_price = driver.find_element(By.XPATH,f'/html/body/main/div/div[1]/section/ol/li[{j + 1}]/div/div/div[2]/div[3]/div[1]/div[1]/a/div/div/span[1]/span[2]/span[2]').text
                prices.append(article_price)
            elif j > 0 and j < 3:
                article_price = driver.find_element(By.XPATH, f'/html/body/main/div/div[1]/section/ol/li[{j + 1}]/div/div/div[2]/div[2]/div[1]/div[1]/a/div/div/span[1]/span[2]/span[2]').text
                prices.append(article_price)
            else:
                article_price = driver.find_element(By.XPATH, f'/html/body/main/div/div[1]/section/ol/li[{j + 1}]/div/div/div[2]/div[2]/div[1]/div[1]/div/div/span[1]/span[2]/span[2]').text
                prices.append(article_price)
        print(articles, prices)
        # 7 get name and price of first 5


    def tearDown(self):
        self.driver.implicitly_wait(3)
        self.driver.close()

if __name__ == '__main__':
    unittest.main(verbosity = 2)

Yo lo hice en wallapop (es como el OLX de Espa帽a)
Tambi茅n agregue aceptar cookies, enviar ENTER en vez de submit() y por ultimo una lista llamada products que contiene tuplas donde tiene estructurada la informaci贸n de la siguiente manera: (item, precio)

import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep

class WallaTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Chrome(executable_path=r'./chromedriver.exe')
        driver = cls.driver
        driver.implicitly_wait(20)
        driver.maximize_window()
        driver.get('https://es.wallapop.com/')

    def test_walla(self):
        driver = self.driver

        accept_cks = driver.find_element_by_id('didomi-notice-agree-button')
        accept_cks.click()

        search_field = driver.find_element_by_name('searchKeyword')
        search_field.click()
        search_field.clear()
        search_field.send_keys('Nintendo Switch')
        search_field.send_keys(Keys.ENTER)

        location = driver.find_element_by_css_selector('body > tsl-root > tsl-public > tsl-search > div > div > tsl-filters-wrapper > div > div > tsl-filter-group > div > div:nth-child(4) > tsl-filter-host > div > tsl-location-filter > tsl-filter-template > div > tsl-bubble > div > div > div')
        location.click()
        search_loc =driver.find_element_by_xpath('/html/body/tsl-root/tsl-public/tsl-search/div/div/tsl-filters-wrapper/div/div[2]/tsl-filter-group/div/div[4]/tsl-filter-host/div/tsl-location-filter/tsl-filter-template/div/div/div[2]/div/tsl-drawer-placeholder-template/div/div/div[1]/input')
        search_loc.click()
        search_loc.clear()
        search_loc.send_keys('Tarragona')
        sleep(2)
        apply_loc = driver.find_element_by_css_selector('body > tsl-root > tsl-public > tsl-search > div > div > tsl-filters-wrapper > div > div.FiltersWrapper__bar.d-flex.pl-3.py-2.FiltersWrapper__bar--opened > tsl-filter-group > div > div:nth-child(4) > tsl-filter-host > div > tsl-location-filter > tsl-filter-template > div > div > div.FilterTemplate__actions.px-4.d-flex.align-items-center.justify-content-end > tsl-button:nth-child(2) > button')
        apply_loc.click()
        sleep(2)

        products = []

        for i in range(5):
            article_name = driver.find_element_by_xpath(f'/html/body/tsl-root/tsl-public/tsl-search/div/tsl-search-layout/div/div[2]/div/tsl-public-item-card-list/div/a[{i+1}]/tsl-public-item-card/div/div[2]/div[2]/p[1]').text
            price = driver.find_element_by_xpath(f'/html/body/tsl-root/tsl-public/tsl-search/div/tsl-search-layout/div/div[2]/div/tsl-public-item-card-list/div/a[{i+1}]/tsl-public-item-card/div/div[2]/div[1]/span').text
            product = (article_name, price)
            products.append(product)

        print(products)
    

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()


if __name__ =='__main__':
    unittest.main(verbosity=2) 

Pr谩ctica a la fecha 17-10-2021

import unittest

from time import sleep
from selenium import webdriver
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.common.by import By

from common import SERVICE
from common import CHROME_OPTIONS

class MercadoLibreTestCase(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        cls.driver = webdriver.Chrome(
            service=SERVICE,
            options=CHROME_OPTIONS,
        )
        cls.driver.get('https://mercadolibre.com/')
        cls.driver.maximize_window()
        cls.driver.implicitly_wait(1)

    def test_search_ps4(self):
        country: WebElement
        country = self.driver.find_element(By.ID, 'CO')
        country.click()

        sleep(1)

        search_field: WebElement
        search_field = self.driver.find_element(By.NAME, 'as_word')
        search_field.click()
        search_field.clear()
        search_field.send_keys('playstation 4')
        search_field.submit()
        
        sleep(1)

        location: WebElement
        location = self.driver.find_element(By.PARTIAL_LINK_TEXT, 'Bogot谩 D.C.')
        self.driver.execute_script("arguments[0].click();", location)

        sleep(1)

        condition: WebElement
        condition = self.driver.find_element(By.PARTIAL_LINK_TEXT, 'Nuevo')
        self.driver.execute_script("arguments[0].click();", condition)

        sleep(1)

        order_menu: WebElement
        order_menu = self.driver.find_element(By.CLASS_NAME, 'andes-dropdown__trigger')
        order_menu.click()

        higher_price_sort: WebElement
        higher_price_sort = self.driver.find_element(By.CSS_SELECTOR, '#root-app > div > div > section > div.ui-search-view-options__container > div > div > div > div.ui-search-sort-filter > div > div > div > ul > a:nth-child(3)')
        higher_price_sort.click()

        sleep(1)

        items = []

        for i in range(5):
            item_title = self.driver.find_element(By.CSS_SELECTOR, f'#root-app > div > div > section > ol > li:nth-child({i + 1}) > div > div > div.ui-search-result__content-wrapper > div.ui-search-item__group.ui-search-item__group--title > a > h2').text
            item_price = self.driver.find_element(By.CSS_SELECTOR, f'#root-app > div > div > section > ol > li:nth-child({i + 1}) > div > div > div.ui-search-result__content-wrapper > div.ui-search-result__content-columns > div.ui-search-result__content-column.ui-search-result__content-column--left > div.ui-search-item__group.ui-search-item__group--price > a > div > div > span.price-tag.ui-search-price__part > span.price-tag-amount > span.price-tag-fraction').text

            items.append((item_title, item_price))

        print(items)

    @classmethod
    def tearDownClass(cls) -> None:
        cls.driver.quit()


if __name__ == '__main__':
    unittest.main(verbosity=2)

[Solucion] Element click intercepted

webdriver.ActionChains(driver).move_to_element(location).click(location).perform()

Tambi茅n estuve revisando y si damos click en el aviso de privacidad, Realiza el click de forma correcta utilizando unicamente location.click()

Resolv铆 as铆 la prueba:

import unittest
from selenium import webdriver
from time import sleep

# Requerimientos
#聽Ir a mercado libre
# Filtrar por CL
# Buscar PS4
# Filtro RM, Nuevo
# Menor precio

class MercadoLibre(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome("./chromedriver")
        driver = self.driver
        driver.implicitly_wait(30)
        driver.maximize_window()
        driver.get("https://www.mercadolibre.com/")

    def clickMeWithJS(self, clickAble):
        self.driver.execute_script("arguments[0].click();", clickAble)

    def test_search_ps4(self):
        driver = self.driver
        country = driver.find_element_by_css_selector("#CL")
        country.click()

        search_field = driver.find_element_by_css_selector("body > header > div > form > input")
        search_field.click()
        search_field.clear()
        search_field.send_keys("ps4")
        search_field.submit()
        sleep(3)

        location = driver.find_element_by_partial_link_text('RM (Metropolitana)')
        #location.click()
        self.clickMeWithJS(location)
        sleep(3)

        condition = driver.find_element_by_partial_link_text('Nuevo')
        self.clickMeWithJS(condition)
        #condition.click()
        sleep(3)

        buttonDropDown = driver.find_element_by_css_selector('#root-app > div > div > section > div.ui-search-view-options__container > div > div > div > div.ui-search-sort-filter > div > div > button')
        buttonDropDown.click()
        sleep(3)

        ascPrice = driver.find_element_by_css_selector('#root-app > div > div > section > div.ui-search-view-options__container > div > div > div > div.ui-search-sort-filter > div > div > div > ul > li:nth-child(2) > a')
        ascPrice.click()
        sleep(3)

        objectsNames = driver.find_elements_by_class_name('ui-search-item__title')
        #objectsPrices = driver.find_elements_by_class_name('price-tag-fraction')
        size = len(objectsNames)
        res = dict()
        for i in range(size):
            x = driver.find_element_by_xpath(f'//*[@id="root-app"]/div/div/section/ol/li[{i+1}]/div/div/div[2]/div[1]/a/h2')
            y = driver.find_element_by_xpath(f'//*[@id="root-app"]/div/div/section/ol/li[{i+1}]/div/div/div[2]/div[2]/div[1]/div/div/div/span[1]/span[2]/span[2]')
            res[i] = {"name": x.text, "price": y.text}

        print(res)

        sleep(3)

    def tearDown(self):
        self.driver.close()

if __name__ == '__main__':
    unittest.main(verbosity=2)

La salida es la siguiente:

Quede bastante contento (Y), WEN PROFE

Si que tom贸 m谩s tiempo esto. Pareciera que en la p谩gina de mercado libre la hacen excesivamente redundante y con divs vac铆os para que sea dif铆cil hacer esto. Aqu铆 va mi versi贸n antes de ver la soluci贸n y con ayuda de uno de los comentarios porque no pod铆a hacer click en los filtros:

import unittest
from time import sleep
from pyunitreport import HTMLTestRunner
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select

class AccessModals(unittest.TestCase):

    @classmethod
    def setUp(cls):
        options = Options()
        options.binary_location = '/snap/brave/119/opt/brave.com/brave/brave'
        cls.driver = webdriver.Chrome(options = options, executable_path="./chromedriver")
        driver = cls.driver
        driver.get("https://www.mercadolibre.com/")
        driver.maximize_window()
    
    def test_account_link(self):
        driver = self.driver
        driver.find_element(By.LINK_TEXT,"M茅xico").click()
        search_bar = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.NAME,"as_word")))
        search_bar.clear()
        search_bar.send_keys("playstation 4")
        search_bar.submit()
        ln = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#root-app > div > div.ui-search-main > aside > section > dl:nth-child(19) > dd:nth-child(2) > a > span.ui-search-filter-name")))
        driver.execute_script("arguments[0].click();", ln)
        ll = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT,"Distrito Federal")))
        driver.execute_script("arguments[0].click();", ll)

        obtn = driver.find_element(By.CSS_SELECTOR,"#root-app > div > div.ui-search-main > section > div.ui-search-view-options__container > div > div > div.ui-search-view-options__group > div.ui-search-sort-filter > div > div > button")
        driver.execute_script("arguments[0].click();", obtn)
        lp = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT,"Menor precio")))
        driver.execute_script("arguments[0].click();", lp)
        WebDriverWait(driver, 10).until(EC.text_to_be_present_in_element((By.XPATH,'//*[@id="root-app"]/div/div[1]/section/div[1]/div/div/div[2]/div[1]/div/div/button'),"Menor precio"))

        products = driver.find_elements(By.CSS_SELECTOR,"ol.ui-search-layout.ui-search-layout--stack li")
        for i in range(5):
            product = products[i]
            title = product.find_element(By.TAG_NAME,"h2").text
            price = product.find_element(By.CSS_SELECTOR,"div.ui-search-item__group.ui-search-item__group--price a").text
            price = price.split(" ")[0]
            print((title, price))

    @classmethod
    def tearDown(cls):
        cls.driver.quit()

if __name__ == "__main__":
    unittest.main(verbosity=2, testRunner=HTMLTestRunner(output="reportes", report_name="automatic_search"))

Para el tercer resultado de la b煤squeda, el c贸digo XPath falla con 鈥渘o such element: Unable to locate element鈥 y me toc贸 hacer un caso especial:

for contador in range(5):
    if contador == 2:
        article_name = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{contador + 1}]/div/div/div[2]/div[2]/a/h2').text
        articles.append(article_name)
        article_price = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{contador + 1}]/div/div/div[2]/div[3]/div[1]/div[1]/div/div/span[1]/span[2]').text
        prices.append(article_price)
    else:
        article_name = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{contador + 1}]/div/div/div[2]/div[1]/a/h2').text
        articles.append(article_name)
        article_price = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{contador + 1}]/div/div/div[2]/div[2]/div[1]/div[1]/div/div/span[1]/span[2]').text
        prices.append(article_price)

yo lo hice usando lo POM, y me quedo asi:

esta sera la clase MercadoLibre.

from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from time import sleep


class MercadoLibre(object):
    def __init__(self, driver):
        self._driver = driver
        self._url = 'https://www.mercadolibre.com/'
        self._country_list = 'ml-site-list'
        self.search_locator = 'q'
        
    @property
    def is_loaded(self):
        WebDriverWait(self._driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'ml-site-list')))
        return True
    
    # @property
    # def keyword(self):
    #     input_field = self._driver.find_element_by_name('q')
    #     return input_field.get_attribute('value')
    
    def open(self):
        self._driver.get(self._url)
        self._driver.maximize_window()
        self._driver.implicitly_wait(30)
        
    def typo_search(self, keyword):
        input_field = self._driver.find_element_by_xpath('//input[@class="nav-search-input"]')
        input_field.send_keys(keyword)
    
    def select_filter(self, filter_condition):
        filter_list= self._driver.find_elements_by_xpath('//span[@class="ui-search-filter-name"]')
        filter_by = list(filter(lambda span: span.text== filter_condition, filter_list))
        print(filter_by[0].text)
        filter_by[0].click()

    def click_submit(self):
        input_field = self._driver.find_element_by_xpath('//input[@class="nav-search-input"]')
        input_field.submit()
        
    def search(self, keyword, location, condition):
        self.typo_search(keyword)
        self.click_submit()
        self.select_filter(location)
        self.select_filter(condition)
    
    def order_by(self, condition):
        self._driver.find_element_by_class_name('ui-search-sort-filter').click()
        self._driver.find_element_by_xpath(f'//li[@value="{condition}"]').click()
    
    def extrac_first_articles(self):
        list_articles_card = self._driver.find_elements_by_class_name('ui-search-result__content-wrapper')
        top_5_articles = list_articles_card[0:4]
        articles_info=[]
        for article in top_5_articles:
            dict_article = {'article_name': '',
                            'price': ''}
            article_name = top_5_articles[0].find_element_by_class_name('ui-search-item__title').text
            price = top_5_articles[0].find_element_by_class_name('price-tag-fraction').text
            dict_article['article_name']=article_name
            dict_article['price']=price
            articles_info.append(dict_article)
        return articles_info
    
    def accept_cookies(self):
        cookies_button = self._driver.find_element_by_id('cookieDisclaimerButton')
        cookies_button.click()
    
    def select_country(self, country_name):
        country_list = self._driver.find_element_by_class_name('ml-site-list')
        country_list = country_list.find_elements_by_tag_name('a')
        country = list(filter(lambda a: a.text== country_name, country_list))
        country = country[0]
        country.click()

y este seri el archivo de test.

import unittest
from selenium import webdriver
from mercadolibre_page import MercadoLibre
from time import sleep

class GoogleTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Chrome(executable_path = './chromedriver')
        
    def test_search(self):
        mercadolibre = MercadoLibre(self.driver)
        mercadolibre.open()
        mercadolibre.select_country('Colombia')
        sleep(3)
        mercadolibre.accept_cookies()
        mercadolibre.search('playstation 4', 'BogotD.C.', 'Nuevo')
        mercadolibre.order_by('price_desc')
        top_5_articles = mercadolibre.extrac_first_articles()
        print(top_5_articles)
        

    @classmethod
    def tearDownClass(cls):
	    cls.driver.implicitly_wait(3)
	    cls.driver.close()

if __name__ == "__main__":
	unittest.main(verbosity = 2)

de esta manera si quieremos cambiar los parametros de busqueda solo debemos modificar el statement del metodo search, tambiejn se podra usar otro tipo de orden por ejemplo 鈥榩rice_asc鈥 para ordenar los productos de menor a mayor precio, por ultimo cree un metodo para la extraccion de la informacion de los articulos el cual los retorna en un diccionario

Les comparto mi codigo

# unittest
import unittest

# Selenium
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


class TestingMercadoLibre(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(r'C:\Users\santi\Downloads\Descargas Basura\chromedriver.exe')
        driver = self.driver
        driver.get('https://mercadolibre.com')
        driver.maximize_window()

    def test_search_ps5(self):
        driver = self.driver
        driver.find_element_by_id('CO').click()
        search_field = driver.find_element_by_name('as_word')
        search_field.click()
        search_field.clear()
        search_field.send_keys('Playstation 5')
        search_field.submit()
        driver.implicitly_wait(3)

        # Ubicaci贸n
        location = driver.find_element_by_xpath('//*[@id="root-app"]/div/div/aside/section/dl[18]/dd[1]/a')
        driver.execute_script("arguments[0].click();", location)
        driver.implicitly_wait(3)

        # Condici贸n
        condition = driver.find_element_by_xpath('//*[@id="root-app"]/div/div/aside/section/dl[17]/dd[1]/a')
        driver.execute_script("arguments[0].click();", condition)
        driver.implicitly_wait(3)

        # Ordenar
        driver.find_element_by_class_name('andes-dropdown__trigger').click()
        higher_price = WebDriverWait(self.driver, 10).until(
            EC.visibility_of_element_located((By.XPATH, '//*/div[1]/div/div/div[2]/div[1]/div/div/div/ul/li[3]/a'))
        )
        higher_price.click()
        driver.implicitly_wait(3)

        articles = []
        prices = []

        for i in range(5):
            article_name = driver.find_element_by_xpath(
                f'//*[@id="root-app"]/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[1]/a/h2'
            )
            articles.append(article_name.text)
            article_price = driver.find_element_by_xpath(
                f'//ol/li[{i + 1}]/div/div/div[2]/div[2]/div[1]/div[1]/div/div/span[1]/span[2]'
            )
            prices.append(article_price.text)
        print(articles, prices)

    def tearDown(self):
        self.driver.close()


if __name__ == '__main__':
    unittest.main()

Hubo algunos cambios con respecto al men煤 desplegable, sin embargo, aqu铆 est谩 el c贸digo:

import unittest
from selenium import webdriver
from time import sleep
class TestingMercadoLibre(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path='/home/yanina/Downloads/chromedriver')
        driver= self.driver
        driver.get('https://www.mercadolibre.com')
        driver.maximize_window()

    def test_search_ps4(self):
        driver= self.driver
        country=driver.find_element_by_id('CO')
        country.click()

        search_field= driver.find_element_by_name('as_word')
        search_field.clear()
        search_field.send_keys('playstation 4')
        search_field.submit()
        sleep(3)

        location= driver.find_element_by_partial_link_text('Bogot谩 D.C.')
        location.click()
        sleep(3)

        condition= driver.find_element_by_partial_link_text('Nuevo')
        condition.click()
        sleep(3)

        order_menu= driver.find_element_by_class_name('andes-dropdown__trigger')
        order_menu.click()
        higher_pric= driver.find_element_by_css_selector('li.andes-list__item:nth-child(3)')
        higher_pric.click()
        sleep(3)

        articles= []
        prices= []
        for i in range(5):
            article_name= driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{i+1}]/div/div/div[2]/div[1]/a/h2').text
            articles.append(article_name)
            article_price= driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{i+1}]/div/div/div[2]/div[2]/div/div/span[1]/span[2]').text
            prices.append(article_price)

        print(articles, prices)
    def tearDown(self):
        self.driver.close()
if __name__== "__main__":
    unittest.main(verbosity=2)```

Para el uso correcto de las esperas, podemos encontrar hasta 3 tipos diferentes de esperas:
Esperas impl铆citas: Indicarle al Driver que espere durante un cierto per铆odo de tiempo cuando intente encontrar un elemento o elementos.
Esperas expl铆citas: Ayuda a pasar por alto la espera impl铆cita para algunos elementos espec铆ficos.
Espera fluida: A diferencia de la espera impl铆cita y expl铆cita, la espera fluida utiliza dos par谩metros. Tiempo de espera y frecuencia de sondeo.

Fuente y ejemplos: https://riptutorial.com/es/selenium-webdriver/example/15495/tipos-de-espera-en-selenium-webdriver

import unittest
from selenium import webdriver
from time import sleep

class MercadoLibre(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path='./chromedriver')
        driver = self.driver
        driver.implicitly_wait(5)
        driver.get("https://www.mercadolibre.com")
        
    def test_ps4_search(self):
        driver = self.driver
        articles = []
        prices = []
        driver.find_element_by_link_text('Colombia').click()

        search_field = driver.find_element_by_xpath('/html/body/header/div/form/input')
        search_field.send_keys('playstation 4')
        search_field.submit()

        driver.find_element_by_xpath('/html/body/main/div/div/aside/section[2]/dl[7]/dd[1]/a').click()
        
        driver.find_element_by_xpath('//*[@id="root-app"]/div/div/aside/section[3]/dl[7]/dd[1]/a').click()
        price = driver.find_element_by_xpath('//*[@id="root-app"]/div/div/aside/section[2]/div[2]/div[1]/div/div/button').click()
        driver.find_element_by_xpath('//*[@id="root-app"]/div/div/aside/section[2]/div[2]/div[1]/div/div/div/ul/li[3]/div/div/a').click()

        for i in range(5):
            article_name = driver.find_element_by_xpath(f'//*[@id="root-app"]/div/div/section/ol/li[{i+1}]/div/div/div[2]/div[1]/a/h2').text
            articles.append(article_name)
            articles_price = driver.find_element_by_xpath(f'//*[@id="root-app"]/div/div/section/ol/li[{i+1}]/div/div/div[2]/div[2]/div/div/span[1]/span[2]').text
            prices.append(articles_price)
        print("")
        for i in range(5):
            print(articles[i] + " : " + prices[i])


    def tearDown(self):
        driver = self.driver
        sleep(5)
        driver.quit()

if __name__ == "__main__":
    unittest.main(verbosity=2)

ahora de automatizar una encuesta que se hace todos los d铆as en la empresa.

mi pregunta es 隆驴 c贸mo hago para que ese script se ejecute a una determinada hora?

Saludos chicos les dejo mi codigo l hice unas peque帽as mejoras y explico con comentarios sus funciones

import unittest
from selenium import webdriver
from time import sleep

class TestingMercadoLibre(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Firefox(executable_path= r'./geckodriver.exe')
        driver = self.driver
        driver.get("https://mercadolibre.com")
        driver.maximize_window()

    def test_search_nintendo_switch(self):
        driver = self.driver

        #Identificar pais
        country = driver.find_element_by_id('VE')
        country.click()

        #Identificar cuadro de busqueda
        search_field = driver.find_element_by_name('as_word')
        search_field.click()#Ubicar el cursor aqui
        search_field.clear()#Limpiar strings
        search_field.send_keys('Nintendo Switch')
        sleep(3)

        #Boton de envio
        button_submit = driver.find_element_by_xpath('/html/body/header/div/form/button/div')
        button_submit.click()

        #Filtro de ubicacion
        location = driver.find_element_by_partial_link_text('Distrito Capital')
        driver.execute_script("arguments[0].click();", location)
        sleep(3)

        #Condicion
        condition = driver.find_element_by_partial_link_text('Nuevo')
        driver.execute_script("arguments[0].click();", condition)
        sleep(3)

        #Ordenar publicaciones
        dropdown = driver.find_element_by_xpath('/html/body/main/div/div/section/div[1]/div/div/div[2]/div[1]/div/div/button')
        dropdown.click()
        sleep(3)

        #Eleccion de ordenamiento
        price = driver.find_element_by_xpath('/html/body/main/div/div/section/div[1]/div/div/div[2]/div[1]/div/div/div/ul/li[3]/a/div/div')
        price.click()
        sleep(3)

        #Listas para almacenar la informacion
        articles = []
        prices = []

        #Titulo
        for i in range(5):
            article_name = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[1]/a/h2').text
            articles.append(article_name)

        #Precio
        for k in range(5):
            article_price = driver.find_element_by_xpath(f'/html/body/main/div/div/section/ol/li[{k + 1}]/div/div/div[2]/div[2]/div[1]/div/div/div/span[1]/span[2]').text
            prices.append(article_price)

        #Impresion
        print(articles, prices)

    def tearDown(self):
        self.driver.close()

if __name__ == '__main__':
    unittest.main()```

tuve el problema de uqe no pude dar click por el nombre del xpath en las condiciones y lo solucione asi

element = driver.find_element_by_xpath('//*[@id="root-app"]/div/div/aside/section/dl[15]/dd[1]/a/span[1]')
        driver.execute_script("arguments[0].click();", element) #este codigo hace que se ejecute un script de 
                                                                #javascript en python, element es tomado como
                                                                #  "argument[0]" y luego se ordena dar click() en
                                                                #  este elemento

Yo tuve problemas con encontrar el filtro de precio, entonces lo busqu茅 por partial_link_text y funcion贸.

import unittest
from time import sleep

from pyunitreport import HTMLTestRunner
from selenium import webdriver


class TestingMercadoLibre(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path='../chromedriver')
        driver = self.driver
        driver.get('https://www.mercadolibre.com')
        driver.maximize_window()

    def test_search_ps4(self):
        driver = self.driver
        country = driver.find_element_by_id('CO')
        country.click()
        search_field = driver.find_element_by_name('as_word')
        search_field.click()
        search_field.clear()
        search_field.send_keys('playstation 4')
        search_field.submit()
        sleep(3)
        driver.find_element_by_xpath('//*[@id="cookieDisclaimerButton"]').click()
        location = driver.find_element_by_partial_link_text('Bogot谩 D.C')
        location.click()
        sleep(3)

        condition = driver.find_element_by_partial_link_text('Nuevo')
        condition.click()
        sleep(3)
        order_menu = driver.find_element_by_class_name('andes-dropdown__trigger')
        order_menu.click()
        sleep(3)

        higher_price = driver.find_element_by_partial_link_text('Mayor precio')
        driver.execute_script("arguments[0].click();", higher_price)
        sleep(3)

        articles = []

        # //*[@id="root-app"]/div/div/section/ol/li[1]/div/div/div[2]/div[1]/a/h2

        for i in range(5):
            article_name = driver.find_element_by_xpath(
                f'//*[@id="root-app"]/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[1]/a/h2').text
            article_price = driver.find_element_by_xpath(
                f'//*[@id="root-app"]/div/div/section/ol/li[{i + 1}]/div/div/div[2]/div[2]/div[1]/div[1]/div/div/span[1]/span[2]').text
            articles.append((article_name, article_price))

        print(articles)

    def tearDown(self) -> None:
        self.driver.close()


if __name__ == "__main__":

    unittest.main(verbosity=2, testRunner=HTMLTestRunner(
        output='.',
        report_name=__file__))