2016-12-26 1 views
1

Я пытаюсь извлечь из этой страницы (http://www.basketball-reference.com/teams/CHO/2017.html) все элементы, соответствующие таблице (Team Misc).Элементы таблицы обхода Python

Я хотел бы, чтобы извлечь все номера из «Team» - (эта линия: 17 13 2,17 -0,51 1,66 106,9 104,7 96,5 0,300 0,319 0,493 10,9 20,5 0,228 0,501 11,6 79,6 0,148 Spectrum Center 269 , 47)

import urllib2 
from bs4 import BeautifulSoup 

htmla = urllib2.urlopen('http://www.basketball-reference.com/teams/CHO/2017.html') 
bsObja=BeautifulSoup(htmla,"html.parser") 
tables = bsObja.find_all("table") 

Пробужденный выше код, надеясь, что я получу список всех таблиц, а затем выберите правильный. Но теперь, как я пытаюсь, я получаю только 1 таблицу с этой страницы.

Любые идеи на другом подходе?

+0

Пожалуйста, включите эту картинку прямо в свой вопрос, а не ссылку, которая может быть сломана в любое время. – ettanany

+0

Эта страница содержит все данные в HTML, но скрыта как комментарии и использует JavaScript для его отображения. Но вы можете использовать 'BeautifuSoup', чтобы найти эти комментарии, удалить' 'и использовать результат с' BeautifuSoup' для получения данных. Я думаю, что эта проблема была решена в каком-то вопросе раньше. – furas

ответ

2

Эта страница содержит все таблицы, спрятанные в комментариях и JavaScript использует его для отображения таблицы и, возможно, сортировать или фильтровать перед выводом на экран.

Все комментарии после <div class='placeholder'>, поэтому вы можете использовать это, чтобы найти этот комментарий, получить весь текст из комментария и использовать BS для его анализа.

#!/usr/bin/env python3 

#import urllib.request 
import requests 
from bs4 import BeautifulSoup as BS 

url = 'http://www.basketball-reference.com/teams/CHO/2017.html' 

#html = urllib.request.urlopen(url) 
html = requests.get(url).text 

soup = BS(html, 'html.parser') 

placeholders = soup.find_all('div', {'class': 'placeholder'}) 

total_tables = 0 

for x in placeholders: 
    # get elements after placeholder and join in one string 
    comment = ''.join(x.next_siblings) 

    # parse comment 
    soup_comment = BS(comment, 'html.parser') 

    # search table in comment 
    tables = soup_comment.find_all('table') 

    # ... do something with table ... 

    #print(tables) 

    total_tables += len(tables) 

print('total tables:', total_tables)  

Таким образом, я нашел 11 таблиц, скрытых в комментариях.

0

Я думаю, что вы хотите

tables = bsObja.findAll("table") 
+0

Тем не менее, я получаю только 1 таблицу :( –

+1

Я только что просмотрел страницу. Это потому, что таблицы загружаются JavaScript. Вам нужно использовать Selenium – HenryM

+0

Хорошо. Я посмотрю, как это работает. Спасибо за предложение. –

0

Данные объекта Комментарий в БС, и объект Комментарий просто особый тип NavigableString, что вам нужно сделать, это:

  1. Найти жала, которые содержат информацию

  2. Использование BeautifulSoup преобразовать строку в объект BS

  3. Извлечение данных из BS объекта

Код:

import re 
table_string = soup.find(string=re.compile('div_team_misc')) 

Это вернет жало, который содержит таблицу HTML код.

table = BeautifulSoup(table_string, 'lxml') 

Используйте жало, чтобы построить объект BS, и извлекать данные из объекта

for tr in table.find_all('tr', class_=False): 
    s = [td.string for td in tr('td')] 
    print(s) 

Out:

['17', '13', '2.17', '-0.51', '1.66', '106.9', '104.7', '96.5', '.300', '.319', '.493', '10.9', '20.5', '.228', '.501', '11.6', '79.6', '.148', 'Spectrum Center', '269,471'] 
['10', '9', '8', '24', '10', '17', '5', '15', '4', '11', '22', '1', '27', '5', '12', '28', '3', '1', None, '15'] 

Подробнее о комментарии:

markup = "<b><!--Hey, buddy. Want to buy a used parser?--></b>" 
soup = BeautifulSoup(markup) 
comment = soup.b.string 

Объект Comment - это особый тип NavigableString, BS будет извлекать строку из строки. Нам не нужно изменять или заменять любой html.

comment 
# u'Hey, buddy. Want to buy a used parser' 

Исходя из этого, мы можем использовать чистый BS вместо re извлечь комментарий

table_string = soup.find(id="all_team_misc").contents[-2] 

Если вы что найти все строки таблицы, вы можете сделать это:

from bs4 import Commnet 
tables = soup.find_all(string=lambda text:isinstance(text,Comment) and str(text).startswith(' \n'))