Я пытаюсь перетащить таблицу csv с веб-страницы в фрейм данных pandas в блокноте Jupyter - процесс, который я успешно реализовал несколько раз в прошлом для других веб-сайтов, но с этим я столкнулся с проблемой.
Таблица, которую я пытаюсь получить, доступна только как ответ JavaScript на нажатие кнопки, а не по определенному URL-адресу.
Вот URL-адрес: https://ciffc.net/national // Таблица, которую я пытаюсь очистить, находится внутри кнопки «Экспорт» (CSV), выделенной красным.
Я попытался реализовать решение с помощью pandas.read_csv, но не могу указать на нужную кнопку.
Следует отметить, что я использую Jupyter Notebooks в среде ArcGIS Online.
Спасибо!






JSON, например, для страницы 1, кажется, доступен по стабильному URL-адресу https://api.ciffc.net//v1/wildfires?page=1.
Итак, если вы не против выполнить дополнительное форматирование DataFrame, вы можете использовать:
import pandas
import requests
df = pandas.DataFrame.from_dict(
requests.get('https://api.ciffc.net//v1/wildfires?page=1').json()["rows"])
Который содержит:
Это работает для меня:
import requests
import pandas as pd
url = 'https://api.ciffc.net//v1/wildfires?export=true'
jsonData = requests.get(url).json()
# So want to skip `rows': [` part because the other part seems to have the column headers and data:
#solution to bypassing outer level from
# answer to 'Remove outer array from JSON in Python dataframe' https://stackoverflow.com/a/69800668/8508004
d = requests.get(url).json()
#df = pd.DataFrame(json.loads(d)["rows"]) #if d is a string
df = pd.DataFrame(jsonData["rows"]) #uncomment if d is not a string
df
Это были два основных ресурса, которые позволили объединить это:
Дайте мне знать, если вам нужны дополнительные разъяснения.
Я сделал это с помощью Selenium, используя некоторые ресурсы Javascript, как вы сказали, для загрузки файла нужно щелкнуть нижнюю часть с помощью JS. Нравиться:
def download_file(self):
try:
self.setup_driver()
url = "https://ciffc.net/national"
self._driver.get(url)
wait = WebDriverWait(self._driver, 20)
button_download = wait.until(
EC.element_to_be_clickable((By.XPATH, "//div[contains(@class, 'table-filter')]//button[contains(@class, 'button')]"))
)
self._driver.execute_script("arguments[0].click();", button_download)
time.sleep(2)
downloaded_file = self.get_downloaded_file_path()
df = pd.read_csv(downloaded_file)
print(df)
except Exception as e:
print(f"An error occurred: {e}")
finally:
if self._driver:
self._driver.quit()
def get_downloaded_file_path(self):
files = os.listdir(os.getcwd())
files.sort(key=lambda x: os.path.getmtime(x))
return os.path.join(os.getcwd(), files[-1])
Этот код прост и отлично работает, чтобы найти элемент и выполнить щелчок, чтобы загрузить файл и преобразовать его в фрейм данных pandas. Здесь указана self._driver.execute_script("arguments[0].click();", button_download) деталь, которая необходима в таких ситуациях!
Весь код, если вам нужно:
from selenium import webdriver
import pandas as pd
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import
expected_conditions as EC
from webdriver_manager.chrome import
ChromeDriverManager
import os
import time
class FileHandlerX:
def __init__(self) -> None:
self._chrome_options = self.define_options()
self._driver = None
def define_options(self):
chrome_options = Options()
prefs = {
"download.prompt_for_download": False,
"download.directory_upgrade": True,
"safebrowsing.enabled": True,
"download.default_directory": os.getcwd()
}
chrome_options.add_experimental_option("prefs",
prefs)
return chrome_options
def setup_driver(self):
chrome_service =
Service(ChromeDriverManager().install())
self._driver =
webdriver.Chrome(service=chrome_service,
options=self._chrome_options)
self._driver.implicitly_wait(10)
def download_file(self):
try:
self.setup_driver()
url = "https://ciffc.net/national"
self._driver.get(url)
wait = WebDriverWait(self._driver, 20)
button_download = wait.until(
EC.element_to_be_clickable((By.XPATH,
"//div[contains(@class, 'table-
filter')]//button[contains(@class, 'button')]"))
)
self._driver.execute_script("arguments[0].click();",
button_download)
time.sleep(2)
downloaded_file =
self.get_downloaded_file_path()
df = pd.read_csv(downloaded_file)
print(df)
except Exception as e:
print(f"An error occurred: {e}")
finally:
if self._driver:
self._driver.quit()
def get_downloaded_file_path(self):
files = os.listdir(os.getcwd())
files.sort(key=lambda x: os.path.getmtime(x))
return os.path.join(os.getcwd(), files[-1])
if __name__ == "__main__":
test = FileHandlerX()
test.download_file()
Некоторые ресурсы о деталях: https://www.tutorialspoint.com/how-to-click-button-selenium-python и https://thewikihow.com/video_xhnOGgPrdj0?si=bshEDsk6ukzlRcEl
Чем это отличается от других ваших усилий? «Я пытаюсь перетащить таблицу csv с веб-страницы в фрейм данных pandas в блокноте Jupyter — процесс, который я успешно реализовал несколько раз в прошлом для других веб-сайтов, но с этим я столкнулся с проблемой». Поделитесь примерами кода и как вы пытались их адаптировать? Единственное, что я вижу здесь, это то, что это динамическая страница, а не статическая, поэтому вы не просто получаете URL-адрес. Но поскольку у вас нет кода, я не могу сказать, знаете ли вы это уже?