Web Scraping не получить всю таблицу - PullRequest
3 голосов
/ 25 марта 2020

Я написал код, который принимает таблицу, используя BeautifulSoup и Selenium.

Однако получается только часть таблицы. Строки и столбцы, которые не отображаются при доступе к веб-сайту , не получены объектом супа.

Я уверен, что проблема возникает в отрывке WebDriverWait(driver, 10).until (EC.visibility_of_element_located((By.ID,"contenttabledivjqxGrid")))

... Я попробовал несколько других вариантов, но ни один из них не дал мне ожидаемого результата (то есть загрузить все строки и столбцы этой таблицы, прежде чем я изменил дату с помощью Selenium).

enter image description here

Следуйте коду:

import os
import time
from selenium import webdriver
from bs4 import BeautifulSoup

​from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options

# Escolhe o driver Firefox com Profile e Options
driver = webdriver.FirefoxProfile()
driver.set_preference('intl.accept_languages', 'pt-BR, pt')
driver.set_preference('browser.download.folderList', '2')
driver.set_preference('browser.download.manager.showWhenStarting', 'false')
driver.set_preference('browser.download.dir', 'dwnd_path')
driver.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/octet-stream,application/vnd.ms-excel')

options = Options()
options.headless = False

driver = webdriver.Firefox(firefox_profile=driver, options=options)

# Cria um driver

site = 'http://mananciais.sabesp.com.br/HistoricoSistemas'
driver.get(site)


WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,"contenttabledivjqxGrid")))
soup = BeautifulSoup(driver.page_source, 'html.parser')

# Cabeçalho
header = soup.find_all('div', {'class': 'jqx-grid-column-header'})
for i in header:
    print(i.get_text())


# Seleciona as relevantes
head = []
for i in header:
    if i.get_text().startswith(('Represa', 'Equivalente')):
        print('Excluído: ' + i.get_text())
    else:
        print(i.get_text())
        head.append(i.get_text())

print('-'*70)
print(head)
print('-'*70)
print('Número de Colunas: ' + str(len(head)))

# Valores
data = soup.find_all('div', {'class': 'jqx-grid-cell'})
values = []
for i in data:
    print(i.get_text())
    values.append(i.get_text())


import numpy as np
import pandas as pd

# Convert data to numpy array
num = np.array(values)

# Currently its shape is single dimensional
n_rows = int(len(num)/len(head))
n_cols = int(len(head))
reshaped = num.reshape(n_rows, n_cols)

# Construct Table
pd.DataFrame(reshaped, columns=head)

Я всего лишь гидролог, и хочу получить данные этого водохранилища. Кто-нибудь может мне помочь?

Моя таблица результатов на данный момент такова:

enter image description here

Ответы [ 2 ]

0 голосов
/ 25 марта 2020

Похоже, таблица загружается динамически, а в HTML отображается только та часть таблицы, которая видна, поэтому вы получаете только часть данных. Возможным решением будет использование полос прокрутки по Selenium и считывание данных по битам.

0 голосов
/ 25 марта 2020

Я только что проверил сайт. В Firefox, если вы go выберите Инструменты разработчика> Сеть и если вы проверите файл с именем «0», вы заметите, что ответ этого файла - файл JSON со всей необходимой вам информацией (Рисунок 1). ). Для того, чтобы получить эту информацию, вам необходимо следовать заголовкам запроса (Изображение 2)

Изображение 1: Ответ на запрос

JSON Request Data

Изображение 2: Заголовки запроса

headers

Вам необходимо выполнить запрос «GET» для веб-сайт с этими заголовками и ответом, если он будет принят, будет JSON со всеми вашими данными. Имейте в виду, что в каком-то запросе может потребоваться заголовок cook ie, который необходимо получить перед его выполнением.

Я не очень хорошо знаю Beatutiful Soup, но знаю, что это достижимо с помощью Scrapy или с помощью библиотеки запросов. Я уверен, что это укажет вам правильное направление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...