Python, Selenium: изолировать элемент из возвращенного списка

Благодаря чтению, видео, SO и помощи сообщества я смог собрать данные из Tessco.com, используя Selenium и Python.

Этот веб-сайт требует ООН и PW. Я включил это в приведенный ниже код, это необязательные учетные данные, созданные специально для того, чтобы задавать вопросы.

Моя конечная цель — просмотреть список номеров деталей в Excel и найти набор параметров, включая цену. Прежде чем вводить список для циклического просмотра, я хочу изолировать необходимую информацию от того, что было соскоблил.

Я не знаю, как фильтровать эту информацию.

Код выглядит следующим образом:

    import time
    #Need Selenium for interacting with web elements
    from selenium import webdriver
    from selenium.webdriver.support import expected_conditions as EC
    #Need numpy/pandas to interact with large datasets
    import numpy as np
    import pandas as pd
    
    chrome_path = r"C:\Users\James\Documents\Python Scripts\jupyterNoteBooks\ScrapingData\chromedriver_win32\chromedriver.exe"
    driver = webdriver.Chrome(chrome_path)
    driver.get("https://www.tessco.com/login")
    
    userName = "[email protected]"
    password = "PasswordForThis123"
    
    #Set a wait, for elements to load into the DOM
    wait10 = WebDriverWait(driver, 10)
    wait20 = WebDriverWait(driver, 20)
    wait30 = WebDriverWait(driver, 30)
    
    elem = wait10.until(EC.element_to_be_clickable((By.ID, "userID"))) 
    elem.send_keys(userName)
    
    elem = wait10.until(EC.element_to_be_clickable((By.ID, "password"))) 
    elem.send_keys(password)
    
    #Press the login button
    driver.find_element_by_xpath("/html/body/account-login/div/div[1]/form/div[6]/div/button").click()
    
    #Expand the search bar
    searchIcon = wait10.until(EC.element_to_be_clickable((By.XPATH, "/html/body/header/div[2]/div/div/ul/li[2]/i"))) 
    searchIcon.click()
    
    searchBar = wait10.until(EC.element_to_be_clickable((By.XPATH, '/html/body/header/div[3]/input'))) 
    searchBar.click()
    
    #load in manufacture part number from a collection of components, via an Excel file
    
    #Enter information into the search bar
    searchBar.send_keys("HL4RPV-50" + '\n')
    
    # wait for the products information to be loaded
    products = wait30.until(EC.presence_of_all_elements_located((By.XPATH,"//div[@class='CoveoResult']")))
    # create a dictionary to store product and price
    productInfo = {}
    # iterate through all products in the search result and add details to dictionary
    for product in products:
        # get product info such as OEM, Description and Part Number
        productDescr = product.find_element_by_xpath(".//a[@class='productName CoveoResultLink hidden-xs']").text
        mfgPart = product.find_element_by_xpath(".//ul[@class='unlisted info']").text.split('\n')[3]
        mfgName = product.find_element_by_tag_name("img").get_attribute("alt")
        
        # get price
        price = product.find_element_by_xpath(".//div[@class='price']").text.split('\n')[1]
    
        # add details to dictionary
        productInfo[mfgPart, mfgName, productDescr] = price
    
    # print products information   
    print(productInfo)

Выход

{('MFG PART #: HL4RPV-50', 'CommScope', '1/2" Plenum Air Cable, Off White'): '$1.89', ('MFG PART #: HL4RPV-50B', 'CommScope', '1/2" Plenum Air Cable, Blue'): '$1.89', ('MFG PART #: L4HM-D', 'CommScope', '4.3-10 Male for 1/2" AL4RPV-50,LDF4-50A,HL4RPV-50'): '$19.94', ('MFG PART #: L4HR-D', 'CommScope', '4.3-10M RA for 1/2" AL4RPV-50, LDF4-50A, HL4RPV-50'): '$39.26', ('MFG PART #: UPL-4MT-12', 'JMA Wireless', '4.3-10 Male Connector for 1/2” Plenum Cables'): '$32.99', ('MFG PART #: UPL-4F-12', 'JMA Wireless', '4.3-10 Female Connector for 1/2" Plenum'): '$33.33', ('MFG PART #: UPL-4RT-12', 'JMA Wireless', '4.3-10 R/A Male Connector for 1/2" Plenum'): '$42.82', ('MFG PART #: L4HF-D', 'CommScope', '4.3-10 Female for 1/2 in AL4RPV-50, LDF4-50A'): '$20.30'}

Я просто хотел бы, чтобы то, что было упомянуто в автоматическом поиске, поэтому для этого примера я бы искал

('MFG PART #: HL4RPV-50', 'CommScope', '1/2" Plenum Air Cable, Off White'): '$1.89'

Со временем я планирую заменить тег HL4RPV-50 списком элементов, но пока я считаю, что должен фильтровать то, что необходимо.

Я сомневаюсь, что логика верна, но я попытался напечатать информацию о продукте для любой части, которая соответствует этому требованию поиска, как показано ниже.

for item in mfgPart:
    if mfgPart == "HL4RPV-50":
        print(productInfo)

Но приведенный выше код просто распечатал весь вывод, как и раньше.

Затем я попытался импортировать itertools и запустить следующее:

print(dict(itertools.islice(productInfo.items(), 1)))

Что на самом деле вернуло нужный мне элемент строки, но нет гарантии, что первый возвращенный элемент — это то, что я ищу. Было бы лучше, если бы я мог отфильтровать точный поиск по заданному номеру детали.

Есть ли способ отфильтровать результаты на основе ввода?

Любые подсказки приветствуются.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
213
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете использовать этот код фильтра для словаря Python

 searchedProduct = dict(filter(lambda item: "HL4RPV-50" in item[0], productInfo.items()))
 print(searchedProduct)

Ваш первоначальный пример был очень близок, нам просто нужно просмотреть и проверить каждый элемент со списком, который находится в ключевом разделе нашего словаря. Если вы не возражаете против вложенности, это сработает :) Вам просто нужно соответствующим образом настроить ключевое слово.

Примечание:

Возможно, вам придется использовать productinfo.iteritems() при использовании Python 2.X, предполагая, что в данном случае это 3.X.

Пример:

def main():

""" Get our key from our dictionary """
for key in productinfo.items():

    """ Retrieve our list of strings """
    for stringList in key[0]:

        """ For every new line in our list of strings """
        for newline in stringList.splitlines():

            """ Lets split by each word in our line """
            for string in newline.split(' '):

                """ Check each string against our keyword """
                if string == "HL4RPV-50B":
                    print(key)

if __name__ == '__main__':
    main()

Да, я использую Python3. Извините, что не разъяснил! Я вижу, что вы там делаете, и это выглядит аккуратно; хотя приведенный выше код ничего не возвращает, и я знаю, что строка HL4RP-50 существует. Кроме того, есть второй элемент списка с именем HL4RPV-50B, не будет ли этот элемент с добавленной буквой «B» также возвращать значение?

James Hayek 08.07.2019 21:57

Спасибо, Дэвид! Вызов индекса нуля фиксирует вывод, хотя он распечатывает другие элементы строки, содержащие эту строку. Я ищу решение @jkulskis. Это работает очень хорошо, я пытаюсь понять это сейчас.

James Hayek 08.07.2019 22:14

@ДжеймсХайек Нет проблем

David S 08.07.2019 22:17
Ответ принят как подходящий

Другие ответы, кажется, проверяют, находится ли номер детали в строке детали mfg, но я видел, что некоторые элементы могут содержать один и тот же номер детали, например HL4RPV-50 и HL4RPV-50B. Если вы хотите изолировать номер детали, чтобы вы могли точно знать, на какую часть вы смотрите, я бы рекомендовал выполнить итерацию по словарю и разделить строку детали mfg на двоеточие, чтобы получить идентификатор. Вы также можете взять другие части элемента, чтобы более четко распечатать информацию, как показано в примере ниже.

for (mfg_part, comm_scope, name), price in productInfo.items():
    mfg_id = mfg_part.split(': ')[1]
    if mfg_id == 'HL4RPV-50':
        print('Part #:', mfg_id)
        print('Company:', comm_scope)
        print('Name:', name)
        print('Price:', price)

Я бы никогда не догадался сделать это. Спасибо! Он работает безупречно. Сейчас я пытаюсь понять ваш мыслительный процесс и приведенный выше код. Я отвечу на комментарии, если мне понадобятся разъяснения. Спасибо любезно!

James Hayek 08.07.2019 22:17

Я столкнулся с ошибкой: NoSuchElementException когда я использую другой номер детали. когда mfg_id = HL4RPV-50 это возвращает правильную информацию. Однако, когда я вхожу в часть FSJ4-50B, я получаю ошибку NoSuchElementException. Есть идеи, почему?

James Hayek 13.07.2019 15:05

В какой строке в приведенном выше блоке кода выдается ошибка? Кроме того, формат элементов на сайте когда-либо меняется? Этот код предполагает, что у каждого элемента есть mfg_part, comm_scope, имя и цена. Я думаю, что NoSuchElementException — это ошибка Selenium, поэтому ваш код для фактического парсинга элементов, скорее всего, не смог найти все. Если вы измените свой код очистки, чтобы поймать это с помощью try, кроме каждого элемента find, это может помочь. Пример для первой находки:

jkulskis 13.07.2019 17:53

Он плохо форматируется в комментариях, поэтому я не буду публиковать здесь весь блок кода, но внутри блока try: есть productDescr = product.find_element_by_xpath(".//a[@class='productName CoveoResultLink hidden-xs']").text, а в блоке except NoSuchElementException: есть productDescr = None

jkulskis 13.07.2019 17:53

Я попробую это сейчас, но, чтобы увидеть результаты, но он зацикливается, как будто XPATH был разным для каждой позиции в списке результатов. Кроме того, возможно, мой [1] комментарий в конце цены, пытаясь изолировать второй элемент, заставлял price всегда возвращать первый price в списке сгенерированных продуктов. В итоге я изолировал рассматриваемую переменную, используя селектор CSS, а не XPATH. Я написал в этой теме: stackoverflow.com/questions/56996738/…

James Hayek 13.07.2019 19:52

Ok! Рад, что ты понял это. Если у вас есть какие-либо другие проблемы, не стесняйтесь добавлять комментарии.

jkulskis 13.07.2019 19:57

Что ж, это была кульминация вас и всех остальных! Очень ценю помощь.

James Hayek 13.07.2019 20:00

Другие вопросы по теме