Что не так с моим парсером на python?

Пытался спарсить детали игры (хронология, рейтинги), которые появляются на сайте, но никак не выдает элементы, которые я пытался достать.
Что я сделал не так и в чем моя оишбка?

Вот код:

#parse
import requests
from bs4 import BeautifulSoup

url = 'https://osu.ppy.sh/users/16873295'
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36 OPR/68.0.3618.206', 'accept': '*/*'}

def get_html(url, params=None):
    r = requests.get(url, headers=headers, params=params)
    return r
    

def get_content(html):
    soup = BeautifulSoup(html, 'html.parser')
    items = soup.find_all('div', class_='play-detail')
    
    print(items)


def parse():
    html = get_html(url)
    if html.status_code == 200:
        get_content(html.text)
    else:
        print('Error')


parse()


#python 3.7.0
  • Вопрос задан
  • 183 просмотра
Решения вопроса 2
hottabxp
@hottabxp Куратор тега Python
Сначала мы жили бедно, а потом нас обокрали..
Я уже здесь неоднократно советовал, возьмите себе за правило, перед любым парсингом, загрузите страницу с помощью скрипта себе на диск. Далее откройте страницу в текстовом редакторе, и поищите - есть ли нужный элемент с нужным классом(или id) в html. Если есть, значит можно работать requests'том. В противном случае - Selenium (есть еще XHR...).
Вот сам код:
import requests

headers = {'user-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0',
			'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
}

url = 'ссылка'
filename = 'index.html'

response = requests.get(url,headers=headers)
if response.status_code == 200:
    with open(filename,'w') as file:
        file.write(response.text)
else:
	print(response)

Вписываете ссылку и запускаете скрипт. Если все ОК - на диске появится файл index.html(на этом файле можно дальше тренироваться с парсингом). В противном случае - в консоль вылетит HTTP код ошибки. Если ошибка, подставляете заголовки, cookies ... и заново.

Конкретно в данном случае, элемента div с классом play-detail в html нет. Он появиться после обработки js скриптов js движком. Но выход есть. Все данные есть. Но они в формате json в теге script с id (если не ошибаюсь) - json-extras.
Ответ написан
kshnkvn
@kshnkvn
yay ✌️ t.me/kshnkvn
В блоке <script id="json-extras" type="application/json"> вся нужная тебе информацию представлена в формате JSON:
json elem
{
   "scoresBest":[
      {
         "id":3211927044,
         "best_id":3211927044,
         "user_id":16873295,
         "accuracy":0.8836257309941521,
         "mods":[
            
         ],
         "score":1981044,
         "max_combo":377,
         "perfect":false,
         "statistics":{
            "count_50":1,
            "count_100":41,
            "count_300":238,
            "count_geki":29,
            "count_katu":21,
            "count_miss":5
         },
         "pp":69.7365,
         "rank":"B",
         "created_at":"2020-08-25T08:26:10+00:00",
         "mode":"osu",
         "mode_int":0,
         "replay":false,
         "beatmap":{
            "difficulty_rating":4.84,
            "id":1385399,
            "mode":"osu",
            "version":"Fanteer's Insane",
            "accuracy":7.5,
            "ar":9,
            "beatmapset_id":653534,
            "bpm":110,
            "convert":false,
            "count_circles":123,
            "count_sliders":162,
            "count_spinners":0,
            "cs":3.5,
            "deleted_at":null,
            "drain":6,
            "hit_length":95,
            "is_scoreable":true,
            "last_updated":"2018-01-08T11:05:04+00:00",
            "mode_int":0,
            "passcount":772659,
            "playcount":3155157,
            "ranked":1,
            "status":"ranked",
            "total_length":96,
            "url":"https:\/\/osu.ppy.sh\/beatmaps\/1385399"
         },
   ]
}

Можешь хоть регуляркой вытягивать этот JSON, преобразовывать его в словарь Python и доставать нужные тебе данные.
Так получается, потому что все элементы на странице рендерятся JS'ом, а requests не умеет интерпретировать JS-код, по-этому исходный код отличается от конечного, который отображается в твоём браузере. Проверить то, какой изначально страница представляется до отработки JS можешь так, как подсказал Gennady S
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы