Форум программистов, компьютерный форум, киберфорум
Python
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.73/88: Рейтинг темы: голосов - 88, средняя оценка - 4.73
 Аватар для m0nte-cr1st0
1043 / 578 / 242
Регистрация: 15.01.2019
Сообщений: 2,178
Записей в блоге: 1

Как распарсить динамическую таблицу?

02.02.2019, 02:44. Показов 19036. Ответов 23

Студворк — интернет-сервис помощи студентам
Здравствуйте. Пытаюсь разобраться в парсинге страниц. Остановился пока на простой BeautifulSoup4 (Python3). Позже думаю на Scrapy перейти.
В общем, хочу написать парсера для поиска букмекерских вилок. В общем, наткнулся на следующую проблему.

Нужно получить информацию из таблицы на странице https://<i>https://www.oddspor... i6gO5P</i>

Я получаю HTML, но это исходный код страницы (Ctrl+U), данной таблицы там вовсе нет (когда я смотрю через Firebug (Ctrl+Shift+C), то эта таблица есть).

Я знаю, что как-то её можно распарсить, именно с этого сайта и пишутся роботы в основном.
Подскажите, в какую сторону смотреть хоть, чтобы получить эту таблицу. Может, BS для данной задачи не подходит?.. И да, данные в таблице изменяются, но я думаю это уже потом решится..

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36'}
url = 'https://www.oddsportal.com/soccer/england/premier-league/tottenham-newcastle-utd-dWi6gO5P'
    
def main(url):
    html = get_html(url)
    get_page_data(html)
    
def get_html(url):
    r = requests.get(url, headers=headers)
    return r.text
    
data = {}
 
def get_page_data(html):
    soup = BeautifulSoup(html, 'lxml')
    # rows = soup.find_all('tr', class_ = 'lo')
 
    # for row in rows:
    #     col = row.find_all('td', class_ = None).find('div', class_='l').find('a', class_='name').text.strip()
    #     data[col] = col
    write_csv(soup)
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
02.02.2019, 02:44
Ответы с готовыми решениями:

Как сделать динамическую таблицу?
У меня есть отделы в одной таблице и сотрудники в другой таблице. Как я могу вызвать это с помощью php, чтобы отделы отображались в части...

Как сделать динамическую таблицу?
Добрый день, подскажите как можно сделать таблицу для игры, и что бы её размерность задавал пользователь какую технологию лучше...

Как закрасить динамическую таблицу
Закрасил таблицу в шахматном порядке, но с остальными двумя не могу, прошу помощи( Закрас шахматной : let n = 10, s; ...

23
1293 / 677 / 367
Регистрация: 07.01.2019
Сообщений: 2,302
02.02.2019, 06:31
BS для данной задачи подходит, а вот requests не подходит, тут надо selenium использовать
1
 Аватар для IRIP
514 / 146 / 28
Регистрация: 18.04.2015
Сообщений: 1,904
Записей в блоге: 16
02.02.2019, 09:18
m0nte-cr1st0, есть замечательный видео урок, по парсингу таких таблиц

1
 Аватар для m0nte-cr1st0
1043 / 578 / 242
Регистрация: 15.01.2019
Сообщений: 2,178
Записей в блоге: 1
02.02.2019, 14:25  [ТС]
Цитата Сообщение от tooru Посмотреть сообщение
BS для данной задачи подходит, а вот requests не подходит, тут надо selenium использовать
cпасибо, попробую

Цитата Сообщение от IRIP Посмотреть сообщение
есть замечательный видео урок, по парсингу таких таблиц
почему-то видео не корректно отображается. спасибо, посмотрю.

https://www.youtube.com/watch?v=BLCmWzFbC0E&t=1s

Добавлено через 1 минуту
Цитата Сообщение от IRIP Посмотреть сообщение
есть замечательный видео урок, по парсингу таких таблиц
попробовал. не вариант. всё-равно парсер не видит не таблицу. это не такая таблица, как в видео.
0
 Аватар для IRIP
514 / 146 / 28
Регистрация: 18.04.2015
Сообщений: 1,904
Записей в блоге: 16
02.02.2019, 14:30
m0nte-cr1st0, так понятнее?

можно всё сначала в терминале делать
Миниатюры
Как распарсить динамическую таблицу?  
0
 Аватар для IRIP
514 / 146 / 28
Регистрация: 18.04.2015
Сообщений: 1,904
Записей в блоге: 16
02.02.2019, 14:32
это как-бы скелет для универсального парсера


Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import requests
from bs4 import BeautifulSoup
import time
import csv
 
#получаем ссылки со страницы
#открываем каждую ссылку
#читаем страницу и сохраняем данные (заголовок, картинку, дату, описание, текст)
 
def get_html(url):
    user_agent = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'}
    r = requests.get(url, headers=user_agent)
    return r.text
 
 
def get_items_list(html):
    """ Получение ссылок на статьи
    """
    soup = BeautifulSoup(html, 'lxml')
    items_page = soup.find('div', {'class':'post-entry'})
    
    pre_url = 'http://site.ru'
    items_list = []
    for link in items_page.find_all('a', href=True):
        a = link['href']
        items_list.append(pre_url + a)
        time.sleep(1)   
    return items_list
 
 
def get_clear_text(html):
    for l in html:
        l = str(l)
        l = l.replace('\n',' ')
        l = l.replace(' align=""center""','')
        l = l.replace('""','"')
        l = l.replace('<div class='post-entry">','')
        l = l.replace('&gt','')
        l=l.replace('&lt','')
        l=l.replace(';',' ')        
 
 
def get_item_data(link):
    soup = BeautifulSoup(get_html(link), 'lxml')
    item_data = []
    try:
        title = soup.find('h1').text.strip()
        item_data.append(title)
    except:
        title = 'Без заголовка'
    
    try:
        pre = 'http://site.ru'
        img = soup.find('div', class_='post-entry').img['src']
        item_data.append(pre+img)
    except:
        img = 'http://site.ru/images/no_image.jpg'
    
    try:
        html = soup.find('div', class_='post-entry')
        text = get_clear_text(html)
        item_data.append(text)
    except:
        text = 'Текст не найден'    
    
    return item_data
    
 
def main():
    url = 'http://site.ru/'
    path = '/home/user/csv/data.csv'
    
    html = get_html(url)
    counter = 1
    for link in get_items_list(html):
        data = get_item_data(link)
        with open(path, 'a', newline='') as csvfile:
            w = csv.writer(csvfile)
            w.writerow(data)
        print('Статья', counter)
        counter += 1
        time.sleep(2)
 
 
if __name__ == '__main__':
    main()
0
 Аватар для m0nte-cr1st0
1043 / 578 / 242
Регистрация: 15.01.2019
Сообщений: 2,178
Записей в блоге: 1
02.02.2019, 15:37  [ТС]
Ну вот.

Статус - 200.

Есть подозрения, что здесь этот метод не подходит. Тут таблица с JS генерится, насколько я понял.
0
 Аватар для IRIP
514 / 146 / 28
Регистрация: 18.04.2015
Сообщений: 1,904
Записей в блоге: 16
02.02.2019, 15:47
m0nte-cr1st0, сначала нужно получить общий див (или табл)
а потом в нем делать findAll

ведь этих tr на странице может быть уйма
0
 Аватар для IRIP
514 / 146 / 28
Регистрация: 18.04.2015
Сообщений: 1,904
Записей в блоге: 16
02.02.2019, 15:50
m0nte-cr1st0, сначала нужно брать уникальный
Миниатюры
Как распарсить динамическую таблицу?  
0
 Аватар для IRIP
514 / 146 / 28
Регистрация: 18.04.2015
Сообщений: 1,904
Записей в блоге: 16
02.02.2019, 15:51
или <div id="odds-data-table"
0
 Аватар для m0nte-cr1st0
1043 / 578 / 242
Регистрация: 15.01.2019
Сообщений: 2,178
Записей в блоге: 1
02.02.2019, 16:05  [ТС]
Взял div по id, беру список 'table-container'. В итоге, их количество равно 0... А должно быть 2.
Мне интересно, это я настолько криворукий, что не могу вытащить оттуда инфу?)

0
 Аватар для m0nte-cr1st0
1043 / 578 / 242
Регистрация: 15.01.2019
Сообщений: 2,178
Записей в блоге: 1
02.02.2019, 16:16  [ТС]
Я когда вытаскиваю HTML, там просто исходный код страницы. Там нет этой таблицы. Может, в этом проблема?
odds.tar.zip
Вложения
Тип файла: xls odds.xls (59.0 Кб, 1 просмотров)
0
Эксперт Python
5438 / 3859 / 1215
Регистрация: 28.10.2013
Сообщений: 9,552
Записей в блоге: 1
02.02.2019, 16:23
Там нет никаких таблиц c данными.
Python
1
2
3
4
5
>>> resp = requests.get('https://www.oddsportal.com/soccer/england/premier-league/tottenham-newcastle-utd-dWi6gO5P')
>>> html = lxml.html.fromstring(resp.text)
>>> html.xpath('//*[@id="odds-data-table"]/div[1]/table')
[]
>>>
Очевидно, что данные прилетают из XHR запроса в виде JSONP:
Кликните здесь для просмотра всего текста
globals.jsonpCallback('/feed/match/1-1-dWi6gO5P-1-2-yj0b4.dat', {"s":1,"d":{"bt":1,"sc":2,"nav":{"1":{"2 ":["31","164","20","468","149","1","411","4 9","45","406","472","46","383","417","37 2","21","393","160","464","57","80","129 ","3","429","14","38","5","9","455","121 ","27","2","26","73","47","454","16","41 4","18","392","128","163","32","381","76 ","15","419","520","43","453","514","416 ","56","139","24","33","147","30","75"," 157"],
....
"3":["4.65",366,1549108402],["4.70",460,1549108219],["4.80",560,1549107863],["4.70",13,1549107800],["4.60",1454,1549107692],["4.50",269,1549107269],["4.45",150,1549106965],["4.50",363,1549106301],["4.45",4865,1549106179],["4.55",11490,1549106116],["4.50",204,1549105694],["4.45",5184,1549105287],["4.50",3713,1549104802],["5.40",308,1548803365]]}}},"time-base":1549110653,"brokenParser":[]},"refresh":20});


и далее из них формируется таблица.

P.S. Как с этим работать - вам уже написали: использовать selenium. Хотя, можно попробовать и внутренний API сайта расковырять.
2
 Аватар для m0nte-cr1st0
1043 / 578 / 242
Регистрация: 15.01.2019
Сообщений: 2,178
Записей в блоге: 1
02.02.2019, 16:27  [ТС]
Вот и мне кажется, что тут обычным BS+requests не обойтись.

Есть какой-то мануал по решению подобного вопроса с помощью питона?
0
1293 / 677 / 367
Регистрация: 07.01.2019
Сообщений: 2,302
02.02.2019, 16:42
Лучший ответ Сообщение было отмечено m0nte-cr1st0 как решение

Решение

Да вот как-то так

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from selenium import webdriver
import lxml.html
 
url = 'https://www.oddsportal.com/soccer/england/premier-league/tottenham-newcastle-utd-dWi6gO5P'
 
options = webdriver.ChromeOptions()
options.add_argument('headless')
driver = webdriver.Chrome(chrome_options=options)
driver.get(url)
 
html = lxml.html.fromstring(driver.page_source)
print(len(html.xpath('//*[@id="odds-data-table"]/div[1]/table')))
 
driver.close()
0
 Аватар для m0nte-cr1st0
1043 / 578 / 242
Регистрация: 15.01.2019
Сообщений: 2,178
Записей в блоге: 1
02.02.2019, 16:55  [ТС]
Спасибо.
Не могли бы вы скинуть какие-то туториалы по этой теме?
И сложно ли вообще написать парсер для всего этого сайта?
0
1293 / 677 / 367
Регистрация: 07.01.2019
Сообщений: 2,302
02.02.2019, 17:15
Цитата Сообщение от m0nte-cr1st0 Посмотреть сообщение
Не могли бы вы скинуть какие-то туториалы по этой теме?
Не знаю на счет туториалов, видел на nnm что-то по этой теме

Цитата Сообщение от m0nte-cr1st0 Посмотреть сообщение
И сложно ли вообще написать парсер для всего этого сайта?
Да как сказать, начните, а там видно будет
0
 Аватар для IRIP
514 / 146 / 28
Регистрация: 18.04.2015
Сообщений: 1,904
Записей в блоге: 16
02.02.2019, 18:15
Garry Galler, как удалось получить?

я json тоже пробовал через F12 найти
пока безуспешно =)
0
Эксперт Python
5438 / 3859 / 1215
Регистрация: 28.10.2013
Сообщений: 9,552
Записей в блоге: 1
02.02.2019, 18:40
Цитата Сообщение от IRIP Посмотреть сообщение
как удалось получить?
Там при запросе страницы много скриптов js подгружается, и они по таймеру делают запросы каждые несколько секунд на другие домены. Любой из них можно ткнуть и посмотреть какой ответ на них приходит.
Ответ в JSONP, а не JSON, так как возвращается вызов javascript функции указанной в jsonp параметре, поскольку сайт делает кроссдоменные запросы, а JSONP это способ обойти запреты для браузеров не поддерживающих CORS (Cross-Origin Resource Sharing).
Но откуда именно берутся данные для той или иной таблицы я не выяснял - там все довольно нетривиально в плане работы внутреннего API.
0
 Аватар для m0nte-cr1st0
1043 / 578 / 242
Регистрация: 15.01.2019
Сообщений: 2,178
Записей в блоге: 1
02.02.2019, 19:20  [ТС]
Вот.. Хочу получить список строк. Вылетает ошибка AttributeError: 'list' object has no attribute 'find_elements_by_tag_name'

Python
1
2
tbody = html.xpath('//*[@id="odds-data-table"]/div[1]/table/tbody')
trows = tbody.find_elements_by_tag_name("tr")
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
02.02.2019, 19:20
Помогаю со студенческими работами здесь

WPF, как создать динамическую таблицу?
Всем доброго дня. Возникла задача сделать средствами WPF динамическую таблицу. Суть в том что количество столбцов в ней может меняться. Я...

Как реализовать динамическую таблицу средствами WPF?
Всем доброго дня. Возникла потребность сделать средствами WPF довольно сложную динамическую таблицу, на вроде такого. Я далеко не...

Как связать динамическую таблицу Excel с PowerPoint
Добрый день! Столкнулся с проблемой и не могу понять как ее решить и вообще, возможно ли это. Суть в чем: Есть файл эксель со множеством...

Как сделать динамическую таблицу меняющую размеры?
Как сделать динамическую таблицу меняющую размеры?

Создать динамическую таблицу
Здравствуйте, надо создать подобную таблицу на js. Эта написана на php, а вот в js не сильна. Таблица должна генерировать по количеству...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Вывод данных через динамический список в справочнике
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru