Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 4, 2023 14:26:45

JD724
Зарегистрирован: 2023-01-04
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Как при парсинге указать парсить именно span (без класса) внутри div'a с классом

Добрый день!
Необходимо парсить содержимое span (без класса) внутри div'a с классом ‘free_seats’ . Где-то видел, что можно поставить символ показывающий дочернее отношение. Но найти самостоятельно не получается, все примеры span'oв с классами. Если указать просто span, то он берет его первый по счету, а это не мой!

Приведу часть кода:
for item in items:
comps.append({
‘title’: item.find('a').get_text(strip = True),
‘mesta’: item.find('div', class_ = ‘free_seats’ что тут указать? ‘span’).get_text(strip = True)
})

Отредактировано JD724 (Янв. 4, 2023 14:34:15)

Офлайн

#2 Янв. 4, 2023 15:14:10

JD724
Зарегистрирован: 2023-01-04
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Как при парсинге указать парсить именно span (без класса) внутри div'a с классом

Проверил на другом сайте с .find_next. Все отлично работает (правда со ‘strong’)! НО на сайте на котором мне нужно парсить в этом месте стоит скрипт. При загрузки страницы он отсылает запрос и выдает количество свободных мест чуть позже.. видимо парсер успевает пробежать до того как страница полностью загрузится.. Нужно как то проверять загрузилась ли страница полностью..
Работает вот так:
'mesta': item.find('div', class_ = ‘events__free-places’).find_next('strong').get_text(strip = True)

Офлайн

#3 Янв. 4, 2023 17:50:49

xam1816
Зарегистрирован: 2020-05-11
Сообщения: 1352
Репутация: +  118  -
Профиль   Отправить e-mail  

Как при парсинге указать парсить именно span (без класса) внутри div'a с классом

покажи какой сайт и что нужно спарсить
и на будущее

[code python]между этими тегами вставлять код[/code]

Офлайн

#4 Янв. 4, 2023 20:47:48

JD724
Зарегистрирован: 2023-01-04
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Как при парсинге указать парсить именно span (без класса) внутри div'a с классом

xam1816
покажи какой сайт и что нужно спарситьи на будущее
Сайт: https://russdramteatr.ru/index.php/ru/afisha
Нужно название спектакля и количество свободных мест. Вот с количеством как раз у меня проблема. За подсказу с выставлением кода отдельное спасибо!

Офлайн

#5 Янв. 4, 2023 22:15:57

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9867
Репутация: +  853  -
Профиль   Отправить e-mail  

Как при парсинге указать парсить именно span (без класса) внутри div'a с классом

JD724
количество свободных мест
Из этого куска можно id получить
  
<div class="free_seats">Свободных мест: <span id="free_seats_96449ed3-92bc-4e2b-9796-a2a2e381fc32"></span></div>

Дальше посылается POST-запрос с передачей этого id и в ответ приходит JSON-документ
  
[guest@localhost py]$ curl -X POST --data 'id=96449ed3-92bc-4e2b-9796-a2a2e381fc32' "https://russdramteatr.ru/mesta/query.php"
{"seatsFree":34}[guest@localhost py]$ 

JD724
Вот с количеством как раз у меня проблема.
Там количества свободных мест и нет изначально. Они догружаются через JavaScript-код с помощью XMLHttpRequest-запроса.

Так что тут надо получить id из страницы и посылать дополнительный запрос с указанием этого id, чтобы получить данные по местам для спектакля с этим id.

Думаю, xam1816 справится.



Отредактировано py.user.next (Янв. 4, 2023 22:24:47)

Офлайн

#6 Янв. 4, 2023 23:20:29

JD724
Зарегистрирован: 2023-01-04
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Как при парсинге указать парсить именно span (без класса) внутри div'a с классом

Точно!! Огромное спасибо! Мысль собирать id летала рядом, но для чего я так и не увидел! И если вытащить id и разложить я возможно еще смогу. Но вот написать POST запрос правильно в Python пока нет. Буду копать, т.к. с питоном только неделю примерно..! Еще раз спасибо за разъяснения!

Офлайн

#7 Янв. 5, 2023 14:06:30

xam1816
Зарегистрирован: 2020-05-11
Сообщения: 1352
Репутация: +  118  -
Профиль   Отправить e-mail  

Как при парсинге указать парсить именно span (без класса) внутри div'a с классом

если сильно не заморачиваться

  
import re
import csv
 
import requests
from bs4 import BeautifulSoup
URL = 'https://russdramteatr.ru/index.php/ru/afisha'
def get_html(url):
    resp = requests.get(url)
    if resp.status_code == 200:
        return resp.content.decode()
 
def get_num_free_seats(id):
    r = requests.post('https://russdramteatr.ru/mesta/query.php', data={'id': id})
    if r.status_code == 200 and r.headers['Content-type'] == 'application/json':
        num = r.json()['seatsFree']
        return num
 
def get_data_from_item(item):
    data = dict.fromkeys(['название', 'свободных мест'])
    search_head = item.find('h2')
    if search_head:
        data['название'] = search_head.text
    search_addr = item.find('address')
    search_title = search_addr.findPreviousSibling('p')
    if search_title:
        data['название'] += f'\n{search_title.text}'
    search = item.find('span', id=re.compile('free_seats_'))
    id = search['id'].replace('free_seats_', '') if search else None
    if id:
        data['свободных мест'] = get_num_free_seats(id)
    return data
 
def parse():
    out = []
    print('загрузка страницы')
    html = get_html(URL)
    soup = BeautifulSoup(html, 'html.parser')
    items = soup.find_all('div', class_=re.compile('items-row cols-\d+ row-\d+'))
    if items:
        print('загрузка данных')
        for i in items:
            data = get_data_from_item(i)
            out.append(data)
        print('.............done..................')
    return out
 
def main():
    res = parse()
    with open('parse_data.csv', 'w') as f:
        fieldnames = ['название', 'свободных мест']
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(res)
    print(res)
 
if __name__ == '__main__':
    main()

только загрузка мест долго идет, можно попробовать асинхронно

Офлайн

#8 Янв. 5, 2023 22:01:37

JD724
Зарегистрирован: 2023-01-04
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Как при парсинге указать парсить именно span (без класса) внутри div'a с классом

Работает! Огромное спасибо!!! Постепенно подчерпываю для себя что-то новое!

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version