Проблема с веб-очисткой python при извлечении цены из продукта

#python #web-scraping #beautifulsoup

#python #веб-очистка #beautifulsoup

Вопрос:

Итак, у меня есть этот код. Я успешно извлекаю каждое название продукта на странице.

 from bs4 import BeautifulSoup as soup 
from urllib.request import urlopen as uReq  


page_url = "https://www.tenniswarehouse-europe.com/catpage-WILSONRACS-EN.html"


uClient = uReq(page_url)


page_soup = soup(uClient.read(), "html.parser")
uClient.close()

containers = page_soup.findAll("div", {"class":"product_wrapper cf rac"})

for container in containers:
    name = container.div.img["alt"]
    print(name)
 

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

 <div class="product_wrapper cf rac">
   <div class="image_wrap">
      <a href="https://www.tenniswarehouse-europe.com/Wilson_Pro_Staff_RF_97_V130_Racket/descpageRCWILSON-97V13R-EN.html">
      <img class="cell_rac_img" src="https://img.tenniswarehouse-europe.com/cache/56/97V13R-thumb.jpg" srcset="https://img.tenniswarehouse-europe.com/cache/112/97V13R-thumb.jpg 2x" alt="Wilson Pro Staff RF 97 V13.0 Racket" />
      </a>
   </div>
   <div class="text_wrap">
      <a class="name " href="https://www.tenniswarehouse-europe.com/Wilson_Pro_Staff_RF_97_V130_Racket/descpageRCWILSON-97V13R-EN.html">Wilson Pro Staff RF 97 V13.0 Racket</a>
      <div class="pricing">
         <span class="price"><span class="convert_price">264,89 amp;euro;</span></span>
         <span class="msrp">SRP <span class="convert_price">300,00 amp;euro;</span></span>
      </div>
      <div class="pricebreaks">
         <span class="pricebreak">Price for 2: <span class="convert_price">242,90 amp;euro;</span>  each</span>
      </div>
      <div>
         <p>Wilson updates the cosmetic of Federer's RF97 but keeps the perfect spec profile and sublime feel that has come to define this iconic racket.  Headsize: 626cm². String Pattern: 16x19. Standard Length</p>
         <div class="cf">
            <div class="feature_links cf">
               <a class="review ga_event" href="/Reviews/97V13R/97V13Rreview.html" data-trackcategory="Product Info" data-trackaction="TWE Product Review" data-tracklabel="97V13R - Wilson Pro Staff RF 97 V13.0 Racket">TW Reviews</a>
               <a class="feedback ga_event" href="/feedback.html?pcode=97V13R" data-trackcategory="Product Info" data-trackaction="TWE Customer Review" data-tracklabel="97V13R - productName">Customer Reviews</a>
               <a class="video_popup ga_event" href="/productvideo.html?pcode=97V13R" data-trackcategory="Video" data-trackaction="Cat - Product Review" data-tracklabel="Wilson_Pro_Staff_RF_97_V130_Racket">Video</a>
            </div>
         </div>
      </div>
   </div>
</div>
</td>
<td class="cat_border_cell">
   <div class="product_wrapper cf rac">
 

Комментарии:

1. Где ваша попытка получить цены? Код, которым вы поделились, даже не относится к вашему HTML.

2. @JustinEzequiel Если вы внимательно посмотрите, это так. И у меня было так много разных попыток, что было бы запутанно публиковать их все. Я попытался создать еще один цикл for и в нем выполнить еще один поиск, я в значительной степени перепробовал все div и span с новым поиском, чтобы посмотреть, смогу ли я получить доступ к цене.

3. Ваш код пытается получить атрибут alt элементов img. Как это выглядит как попытка получить цены?

4. @Justin Ezequiel Я не включил неудачные попытки

Ответ №1:

Я думаю, это сработает для вас:

 prices = page_soup.findAll("span", {"class":"convert_price"})
 

Тогда у вас будет контейнер со всеми ценами на странице, с помощью которого вы сможете получить доступ к отдельным ценам prices[0] ... prices[len(prices)-1] .
Если вы хотите удалить HTML-теги из прайсов, сделайте prices[0].text

Но откуда именно этот HTML? Bc цены не указаны на странице ссылки, которую вы добавили в свой код. Так что в этом супе вы не должны найти никаких цен.

Приведенный выше код работает для HTML-кода, который вы там указали.

Редактировать: скриншот для комментария ниже введите описание изображения здесь

! РЕШЕНИЕ!:

Способ решить эту проблему — использовать Selenium webdriver вместе с BeautifulSoup. Кажется, я не могу найти другого (более простого) способа.

Сначала установите Selenium с pip install selenium

Загрузите драйвер для своего браузера здесь.

Что мы делаем, так это нажимаем кнопку «Установить выбор», которая появляется при открытии веб-сайта, затем мы загружаем страницу с уже загруженными ценами. Наслаждайтесь моим кодом ниже.

 from bs4 import BeautifulSoup
from selenium import webdriver

# use the path of your driver.exe
driver = webdriver.Firefox(executable_path="C:Program Files (x86)geckodriver.exe")
# for Chrome it's: driver = webdriver.Chrome("C:Program Files (x86)chromedriver.exe")

# open your website link
driver.get("https://www.tenniswarehouse-europe.com/catpage-WILSONRACS-EN.html")

# button for submitting the location
button1 = driver.find_element_by_class_name("vat_entry_opt-submit")
button1.click()

# now that the button is clicked the prices are loaded in and we can soup this page
html = driver.page_source
page_soup = BeautifulSoup(html)

# extracting all prices into an array named pricing
pricing = page_soup.findAll("div",{"class":"pricing"})
price = pricing[x].span.text

# a loop for writing every price inside an array named 'price'
price = []
i = 0
while i<len(pricing):
    price.append(pricing[i].span.text)
    i = i   1

# For this example you have to use class "pricing" instead of "price" because the red prices are in class "sale"
# replace x with the price you're looking for, or let it loop and get all prices in one array

# driver.close()  closes your webdriver window
 

Комментарии:

1. Что вы имеете в виду? Я проверяю ссылку, и цены там есть. И у меня была такая проблема, когда я не получал никаких результатов.

2. Хм, теперь я понимаю. Цены указаны на веб-сайте, но при очистке массив пуст. Я пытаюсь вернуться к этому ответу, когда что-нибудь найду.

3. Хорошо, теперь я знаю, почему массив цен пуст. Когда вы загружаете веб-сайт в первый раз (удаляете файлы cookie и загружаете его снова), вас запрашивают о вашем местоположении. Цены загружаются после выбора местоположения. Bs4 не выбирает местоположение, поэтому цены нет.

4. Да, это была моя проблема — пустой массив. Я попробую и дам вам знать.

5. Да! Наконец, я сделал это. Я сделаю быструю документацию, а затем отредактирую свой ответ. 🙂

Ответ №2:

Поможет ли это:

 In [244]: soup = BeautifulSoup(requests.get('https://www.tenniswarehouse-europe.com/Wilson_Pro_Staff_RF_97_V130_Racket/descpageRCWILSON-97V13R-EN.html').content, 'html.parser')

In [245]: soup.find('h1', class_='name').text.strip()
Out[245]: 'Wilson Pro Staff RF 97 V13.0 Racket'

In [246]: soup.find(class_='convert_price').text.strip()
Out[246]: '242,90 €'
 

Комментарии:

1. Эй, это работает, но дает мне неправильную цену. 242,90 — это специальное предложение, которое у них есть, если вы покупаете больше продуктов, но окончательная цена продукта все еще не напечатана. Когда я заменяю ‘convert_price’ на price, я не получаю никаких результатов, и когда я устанавливаю цену, это дает мне скидку.