Reputation: 11
for some reason find function return none, even though it exists in html code. First find:
price = row.find('div', {'class': 'price-normal selenium-price-normal'})
return normally the price, but second one:
price = row.find('div', {'class': 'price-normal'})
Return none and when i try to print text out of it I get error even though HTML looks very similar:
AttributeError: 'NoneType' object has no attribute 'text'
Here is HTML, from where I can not extract data:
<div class="product-price price-show instalments-show">
<div class="price-normal">
4 095 zł</div>
<div class="price-instalments-box">
<div class="price-instalments-row">
<span class="price-instalments-label">
RATY:</span>
<a href="/telefony-komorkowe/apple-iphone-12-256gb-zielony.bhtml#outlet-doskonaly|raty" class="price-instalments selenium-price-instalments js-scroll-by-hash">
682,50 zł <span>x 6 rat 0%</span><i></i>
</a>
</div>
</div>
</div>
Here is HTML that works:
<div class="product-prices-box">
<div class="product-price product-price-101611036529 price-show instalments-show">
<div class="price-presentation">
<div class="price-normal selenium-price-normal">
5 499 zł</div>
</div>
<div class="price-instalments-box">
<div class="price-instalments-row">
<span class="price-instalments-label">
RATY:</span>
<div class="price-instalments price-instalments-only-shop selenium-price-instalments">
274,95 zł <span>x 20 rat 0%</span><i></i>
</div>
</div>
<div class="price-instalments-row price-instalment-shop-only-info">
Raty tylko w sklepie stacjonarnym<a href="#" class="js-price-installment-shop-info"></a>
</div>
</div>
</div>
</div>
Here is my code:
main_url = 'https://www.euro.com.pl/telefony-komorkowe,_Apple.bhtml'
pages_html = [main_url]
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.implicitly_wait(10)
wait = WebDriverWait(driver, 10)
driver.get(main_url)
soup = BeautifulSoup(driver.page_source , 'lxml')
pages_numbers = soup.find('div', {'class': 'paging-numbers'})
for page in pages_numbers.find_all('a', {'class': 'paging-number'}):
print(page['href'])
pages_html.append('https://www.euro.com.pl' + page['href'])
for url in pages_html:
driver.get(url)
soup = BeautifulSoup(driver.page_source, 'lxml')
product_list = soup.find('div', {"id": "products", 'class': 'list'})
product_rows = soup.find_all('div', {'class': 'product-row'})
for row in product_rows:
product = row.find('h2', class_='product-name')
all_products.append(product.text.strip())
try:
price = row.find('div', {'class': 'price-normal selenium-price-normal'})
except AttributeError:
price = row.find('div', {'class': 'price-normal'})
print(price)
print(f'Produkt: {product.text.strip()}, Cena: {price.text.strip()}')
driver.close()
Does anyone know what is going on here?
I tried using WebDriverWait object, as other posts suggested but I couln't make it work.
Upvotes: 1
Views: 173
Reputation: 195428
If you want to get names and prices of products you can use next example:
import pandas as pd
import requests
from bs4 import BeautifulSoup
url = 'https://www.euro.com.pl/telefony-komorkowe,_Apple.bhtml'
soup = BeautifulSoup(requests.get(url).content, 'html.parser')
all_data = []
for product in soup.select('.product-for-list'):
name = product.h2.text.strip()
price = product.select_one('.price-normal').text.strip()
all_data.append((name, price))
df = pd.DataFrame(all_data, columns=['Name', 'Price'])
print(df.to_markdown(index=False))
Prints:
Name | Price |
---|---|
Apple iPhone 14 128GB (północ) | 4 899 zł |
Apple iPhone 11 64GB (biały) | 2 799 zł |
Apple iPhone 14 Pro 128GB (złoty) | 7 199 zł |
Apple iPhone 11 64GB (czarny) | 2 599 zł |
Apple iPhone 14 Pro 128GB (gwiezdna czerń) | 7 199 zł |
Apple iPhone 12 64GB (biały) | 3 999 zł |
Apple iPhone 13 128GB (księżycowa poświata) | 4 749 zł |
Apple iPhone 12 64GB (czarny) | 3 999 zł |
Apple iPhone 13 128GB (północ) | 4 199 zł |
Apple iPhone 13 128GB (zielony) | 4 749 zł |
Apple iPhone 13 256GB (księżycowa poświata) | 4 999 zł |
Apple iPhone 12 64GB (niebieski) | 3 999 zł |
Apple iPhone 14 Pro 256GB (głęboka purpura) | 7 899 zł |
Apple iPhone 14 128GB (fioletowy) | 4 899 zł |
Apple iPhone 14 Pro Max 128GB (złoty) | 7 899 zł |
Apple iPhone 14 Pro 256GB (srebrny) | 7 899 zł |
Apple iPhone 14 Pro 128GB (srebrny) | 7 199 zł |
Apple iPhone 14 Pro 256GB (złoty) | 7 899 zł |
Apple iPhone 14 Pro Max 1TB (czarny) | 11 499 zł |
Apple iPhone 14 128GB (księżycowa poświata) | 4 899 zł |
Apple iPhone 13 128GB (różowy) | 4 749 zł |
Apple iPhone 12 128GB (biały) | 4 549 zł |
Apple iPhone 14 Plus 128GB (północ) | 5 499 zł |
Apple iPhone 12 64GB (fioletowy) | 3 299 zł |
Apple iPhone 12 128GB (niebieski) | 4 549 zł |
Apple iPhone 13 mini 128GB (niebieski) | 3 499 zł |
Apple iPhone 13 mini 128GB (północ) | 4 299 zł |
Apple iPhone 11 128GB (czarny) | 3 099 zł |
Upvotes: 1