Создаю парсер, который должен парсить страницу со скидками стима, но в результате парсинга в результате дается только 3-4 игры
from bs4 import BeautifulSoup
from selenium import webdriver
import time
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
url = f'https://store.steampowered.com/specials/'
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/93.0.4577.82 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,"
"application/signed-exchange;v=b3;q=0.9",
}
def get_result(url, headers):
chrome_options = Options()
options = webdriver.ChromeOptions()
s = Service(executable_path='C:\Пользователи\Олег\PycharmProjects\TelegramBot\chromedriver_win32\chromedriver.exe')
driver = webdriver.Chrome(service=s, options=options)
options.add_argument('--headless')
options.add_argument('--no-sandbox')
driver.get(url)
time.sleep(10)
html = driver.page_source
soup = BeautifulSoup(html, "lxml")
games = soup.find_all('div', class_='salepreviewwidgets_StoreSaleWidgetRight_1lRFu')
for game in games:
game_name = f'Название: {game.find("div", class_="salepreviewwidgets_StoreSaleWidgetTitle_3jI46").text}'
discount = f'Скидка: {game.find("div", class_="salepreviewwidgets_StoreSaleDiscountBox_2fpFv").text}'
price_original = f'Цена без скидки: {game.find("div", class_="salepreviewwidgets_StoreOriginalPrice_1EKGZ").text}'
price_sale = f'Цена после скидки: {game.find("div", class_="salepreviewwidgets_StoreSalePriceBox_Wh0L8").text}'
print(game_name)
print(price_original)
print(discount)
print(price_sale)
def main():
get_result(url=url, headers=headers)
if __name__ == "__main__":
main()
Ответы (2 шт):
Автор решения: user510170
→ Ссылка
Смотрите, если самый простой способ но костыльный, то вы можете просто время ожидания сменить примерно на 90 секунд, тогда все элементы подгрузятся и вы их вытащите:
.....
driver.get(url)
time.sleep(90)
.....
Или можно использовать нажатия на кнопки, для прокуртки всех скидок, это будет выглядить примерно так, для наглядности использую вывод только имён, но думаю остальные данные вы извлечёте самостоятельно:
from bs4 import BeautifulSoup
from selenium import webdriver
import time
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
......
driver.get(url)
driver.fullscreen_window() # Используем, что бы кнопка появилась на экране
time.sleep(3)
for i in range(13):
driver.find_element(By.XPATH, '//button[@aria-label="next"]').click()
# driver.find_element(By.TAG_NAME, 'button').click() # Нажимаем на кнопку, так как скидок 13 сейчас, то взял такое количество, думаю можно и меньше
time.sleep(1)
time.sleep(3)
html = driver.page_source
soup = BeautifulSoup(html, "lxml")
games_names = soup.find_all('div', class_='animated_featured_capsule_TitleArtworkCtn_3DIUb')
for name in games_names:
try:
name = name.find('div', 'animated_featured_capsule_TitleCtn_dXV8z').find('a').text
print(name)
except AttributeError:
pass
Результат:
Deadside
The Planet Crafter
Portal 2
No Man's Sky
GTFO
Portal
Figment
Patch Quest
V Rising
Phantom Brigade
Deep Rock Galactic
Skul: The Hero Slayer
Warhammer: Vermintide
Вот вариант поиска, как вы хотели по другому классу и кнопке "Показать больше":
from selenium import webdriver, common
.....
driver.get(url)
time.sleep(3)
try:
for i in range(100): # Нажмите столько раз, сколько посчитаете нужным
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") # Прокрутить вниз страницу
time.sleep(1)
driver.find_element(By.XPATH, '//div[@class="saleitembrowser_ShowContentsContainer_3IRkb"]//button[text()="Показать больше"]').click() # Нажимаем на кнопку
except common.exceptions.NoSuchElementException: # Обработаем ошибку, когда закончатся все скидки кнопка не будет найдена
pass
time.sleep(3)
html = driver.page_source
soup = BeautifulSoup(html, "lxml")
games_names = soup.find_all('div', class_='salepreviewwidgets_StoreSaleWidgetRight_1lRFu')
for game in games_names:
try:
name = game.find('div', 'salepreviewwidgets_TitleCtn_1F4bc').find('a').text
price = game.find('div', 'salepreviewwidgets_StoreSalePriceBox_Wh0L8').text
print(f'Название:{name} - цена:{price}')
except AttributeError:
pass
....
Вывод:
Название:Deadside - цена:461 руб
Название:GTFO - цена:1172 руб
Название:Deep Rock Galactic - цена:263 руб
Название:Portal 2 - цена:38,50 руб
Название:Deep Rock Galactic - цена:263 руб
Название:Hunt: Showdown - цена:539 руб
....
больше информации по использования selenium
Автор решения: shezyy
→ Ссылка
#Дополнение к комментарию.
from bs4 import BeautifulSoup
from selenium import webdriver
import time
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
url = f'https://store.steampowered.com/specials/'
chrome_options = Options()
options = webdriver.ChromeOptions()
s = Service(executable_path='C:\Пользователи\Олег\PycharmProjects\TelegramBot\chromedriver_win32\chromedriver.exe')
driver = webdriver.Chrome(service=s, options=options)
driver.get(url)
driver.fullscreen_window() # Используем, что бы кнопка появилась на экране
time.sleep(3)
for i in range(13):
driver.find_element(By.CLASS_NAME, 'saleitembrowser_ShowContentsButton_3d9cK Focusable').click() # Нажимаем на кнопку, так как скидок 13 сейчас, то взял такое количество, думаю можно и меньше
time.sleep(1)
time.sleep(3)
html = driver.page_source
soup = BeautifulSoup(html, "lxml")
games = soup.find_all('div', class_='facetedbrowse_FacetedBrowseItems_NO-IP')
for game in games:
try:
name = game.find('div', 'salepreviewwidgets_StoreSaleWidgetTitle_3jI46').text
print(name)
except AttributeError:
pass