Соскоб с селеном, где таблица имеет одинаковые имена классов - PullRequest
0 голосов
/ 26 сентября 2019

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

enter image description here

А вот как выглядит таблица:

enter image description here

Итак, что я до сих пор кодировал:

driver = webdriver.Chrome()
driver.get(base_url)
driver.implicitly_wait(100)
driver.find_elements_by_class_name("plp-pod__image")[0].click()
first = driver.find_elements_by_class_name("col-6 specs__cell specs__cell--label")[0].getText()
first

Итак, в основном я открываю браузер Chrom, загружаю страницу элемента, который ищу, ичем искать все классы, называемые «col-6 specs__cell specs__cell - label», и пытаться получить текст из первого появившегося.Я пытаюсь решить это для всех 5 измерений и его значений.

Когда я выполняю свой код, я получаю эту ошибку:

    ---------------------------------------------------------------------------

IndexError                                Traceback (most recent call last)

<ipython-input-27-2e124acf6be5> in <module>
      3 driver.implicitly_wait(100)
      4 driver.find_elements_by_class_name("plp-pod__image")[0].click()
----> 5 first = driver.find_elements_by_class_name("col-6 specs__cell specs__cell--label")[0].getText()

IndexError: list index out of range

Есть идеи, как мне разобрать эти элементы, чтобы получить все 5 измерений и их значений в панде dataframe?

Я попытался объединить оба ваших предложения следующим образом:

from selenium.common.exceptions import NoSuchElementException, 
NoSuchFrameException
i = "Marshalltown PT164BR"
base_url = f"https://www.homedepot.com/s/" + i +"?NCNI-5"

driver = webdriver.Chrome()
driver.get(base_url)
WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 
".plp-pod__image"))).click()
#%%

groups = driver.find_elements_by_class_name("specs__group")
data = {}
for group in groups:
    if "placeholder" not in group.get_attribute("class"):
        specs = group.find_elements_by_class_name("specs__cell")
        dimension = specs[0].text.strip()
        value = float(specs[1].text.replace("in","").strip())
        #print(dimension,":",value)
        if dimension not in data:
            data[dimension] = []
        data[dimension].append(value)
print(data)
data_frame = pd.DataFrame(data=data)
print(data_frame)

, и я попал на веб-страницу, которую я использую в качестве теста, на элемент, который я использую в качестве теста, но это не кажетсячитать правильные классы, и это дает мне эту ошибку:

---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-3-1f3f99bc45ee> in <module>
      5         specs = group.find_elements_by_class_name("specs__cell")
      6         dimension = specs[0].text.strip()
----> 7         value = float(specs[1].text.replace("in","").strip())
      8         #print(dimension,":",value)
      9         if dimension not in data:

ValueError: could not convert string to float:

Ответы [ 2 ]

2 голосов
/ 26 сентября 2019

В дополнение к предыдущему посту, если я использую этот HTML:

<html>
<head></head>
<body>
<div class="specs__group col-12 col-lg-6" style="min-height: 39px;">
    <div class="col-6 specs__cell specs__cell--label">Blade Length (in.)</div>
    <div class="col-6 specs__cell">16 in</div>
</div>
<div class="specs__group col-12 col-lg-6" style="min-height: 39px;">
    <div class="col-6 specs__cell specs__cell--label">Blade Width (in.)</div>
    <div class="col-6 specs__cell">4.5</div>
</div>
<div class="specs__group col-12 col-lg-6" style="min-height: 39px;">
    <div class="col-6 specs__cell specs__cell--label">Product Height (in.)</div>
    <div class="col-6 specs__cell">3.63 in</div>
</div>
<div class="specs__group col-12 col-lg-6" style="min-height: 39px;">
    <div class="col-6 specs__cell specs__cell--label">Product Length (in.)</div>
    <div class="col-6 specs__cell">16 in</div>
</div>
<div class="specs__group col-12 col-lg-6" style="min-height: 39px;">
    <div class="col-6 specs__cell specs__cell--label">Product Width (in.)</div>
    <div class="col-6 specs__cell">4.5 in</div>
<div class="specs__group placeholder" style="min-height: 39px;">
    ??
</div>
</body>

Вы можете создать dict или dataframe:

from bs4 import BeautifulSoup
import pandas as pd
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException, NoSuchFrameException

base_url = "file:///C:/Users/.../blade.html"

driver = webdriver.Chrome()
driver.get(base_url)
groups = driver.find_elements_by_class_name("specs__group")
data = {}
for group in groups:
    if "placeholder" not in group.get_attribute("class"):
        specs = group.find_elements_by_class_name("specs__cell")
        dimension = specs[0].text.strip()
        value = float(specs[1].text.replace("in","").strip())
        #print(dimension,":",value)
        if dimension not in data:
            data[dimension] = []
        data[dimension].append(value)
print(data)
data_frame = pd.DataFrame(data=data)
print(data_frame)
1 голос
/ 27 сентября 2019

Здесь код, который будет извлекать размеры продукта.

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 import webdriver
import pandas as pd
driver = webdriver.Chrome()
i = "Marshalltown PT164BR"
base_url ="https://www.homedepot.com/s/" + i +"?NCNI-5"
driver.get(base_url)
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".plp-pod__image"))).click()
Dimensions_Type=[]
Dimention_Size=[]
elements=WebDriverWait(driver, 20).until(EC.presence_of_all_elements_located((By.XPATH, "(//h4[text()='Dimensions']/following::div[contains(@class,'specs__table')])[1]/div")))
for ele in elements:
  if "placeholder" not in ele.get_attribute("class"):
     DimensionsType=ele.find_element_by_xpath(".//div[@class='col-6 specs__cell specs__cell--label']").get_attribute("textContent")
     DimentionSize=ele.find_element_by_xpath(".//div[@class='col-6 specs__cell specs__cell--label']/following-sibling::div[1]").get_attribute("textContent")
     Dimensions_Type.append(DimensionsType)
     Dimention_Size.append(DimentionSize)

df=pd.DataFrame({"DimensionSize":Dimention_Size,"DimensionType":Dimensions_Type})
print(df)

Вывод на консоль:

    DimensionSize       DimensionType
0         16 in    Blade Length (in.)
1           4.5     Blade Width (in.)
2       3.63 in  Product Height (in.)
3         16 in  Product Length (in.)
4        4.5 in   Product Width (in.)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...