Прогрузка страницы в BS

Загружаю с помощью beautiful soup ('lxml') страницу любого предмета стима, потом нахожу элемент id='market_commodity_forsale'. 1

@staticmethod
def get_item_cost(item_page):
    #print(item_page)
    r = requests.get(item_page)
    #print(r.text)
    parser = bs(r.text, "lxml")
    cost = parser.find("div", id="market_commodity_forsale")#class_='market_commodity_orders_header_promote')
    print(cost)

При этом при загрузке элемента внутреннее содержимое не выводится. Помогите исправить, пожалуйста 2


Ответы (1 шт):

Автор решения: Johan

Для начала, подразумевается, что у вас уже установлены необходимые для работы скрипта библиотеки. Но, возможно, для кого-то это будет полезно. Поэтому, напомню, что нужно установить библиотеки с помощью команды в терминале:

pip install requests bs4 lxml

То, что вы пытаетесь получить, является динамически изменяемой величиной с помощью скриптов. Соответственно, в простом запросе вы не увидите нужных вам тегов. Но, если вы откроете инструменты разработчика и перейдете во вкладку "Network" -> "Fetch/XHR", станет понятно, каким способом получаются данные. В текущем случае данные прилетают после запроса в виде JSON, нужные вам поля которого, это HTML-разметка.

введите сюда описание изображения

Таким образом, вы можете сделать запрос по тому же адресу, что и скрипт для получения нужных значений. Но, для достижения лучшего результата, лучше всего щелкнуть правой кнопкой мыши по скрипту и выбрать пункт "Copy -> Copy asCURL (bash)",

введите сюда описание изображения

перейти на сайт: https://curlconverter.com/, выбрать нужный вам язык, в данном случае Python и вставить скопированные значения. Ниже, на этой же странице вы увидите код, который можно использовать в вашем скрипте. В данном случае описывается множество параметров, одним из которых является cookie. Я удалил данные значения, но в итоге скрипт не потерял своей работоспособности. Если вы хотите получить cookies от сайта, тогда посмотрите документацию requests по их получению и использованию. И после всех проделанных манипуляций скрипт может приобрести следующий вид (это для разовой акции). Если вы планируете мучить сайт запросами постоянно, то лучше cookies все же получить.

import requests
from bs4 import BeautifulSoup
 
 
def get_source() -> (str, bool):
    headers = {
        'Accept': '*/*',
        'Accept-Language': 'ru,en;q=0.9,uk;q=0.8',
        'Connection': 'keep-alive',
        'DNT': '1',
        'If-Modified-Since': 'Tue, 27 Feb 2024 00:34:30 GMT',
        'Referer': 'https://steamcommunity.com/market/listings/730/Kilowatt%20Case',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'same-origin',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/120.0.0.0 YaBrowser/24.1.0.0 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest',
        'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "YaBrowser";v="24.1", "Yowser";v="2.5"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
    }
 
    params = {
        'country': 'RU',
        'language': 'russian',
        'currency': '1',
        'item_nameid': '176413986',
        'two_factor': '0',
    }
    try:
        res = requests.get('https://steamcommunity.com/market/itemordershistogram', params=params, headers=headers)
        if res.status_code == 200:
            return res.json()
        return False
    except ConnectionError:
        return False
 
 
def parse_lot(txt: str) -> (tuple, bool):
    try:
        soup = BeautifulSoup(txt, "lxml")
        if lots := soup.find_all("span", class_="market_commodity_orders_header_promote"):
            return lots[0].text, lots[1].text
        return False, False
    except Exception as e:
        print(e)
        return False, False
 
 
def main() -> None:
    if data_json := get_source():
        buy_order_count, by_order_prise = parse_lot(data_json.get("buy_order_summary"))
        print(f'Запросов на покупку: {buy_order_count}, Начальная цена: {by_order_prise}')
        sell_order_count, sell_order_prise = parse_lot(data_json.get("sell_order_summary"))
        print(f'Лотов на продажу: {sell_order_count}, Начальная цена: {sell_order_prise}')
    else:
        print("Не удалось получить данные")

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

→ Ссылка