#python #pandas #dataframe #dictionary #beautifulsoup
#питон #панды #фрейм данных #словарь #прекрасный суп
Вопрос:
Здесь я пытаюсь получить значение каждого столбца в таблице, показанной на рисунке (для трех разных страниц), и сохранить их в фрейме данных pandas. Я собрал данные, и теперь у меня есть список списков, но когда я пытаюсь добавить их в словарь, я получаю пустой словарь. может ли кто-нибудь помочь мне понять, что я делаю неправильно, или предложить альтернативный способ создания 3 кадров данных, по одному для каждой таблицы?
Вот мой код:
import numpy as np import pandas as pd from datetime import datetime import pytz import requests import json from bs4 import BeautifulSoup url_list = ['https://www.coingecko.com/en/coins/ethereum/historical_data/usd?start_date=2021-08-06amp;end_date=2021-09-05#panel', 'https://www.coingecko.com/en/coins/cardano/historical_data/usd?start_date=2021-08-06amp;end_date=2021-09-05#panel', 'https://www.coingecko.com/en/coins/chainlink/historical_data/usd?start_date=2021-08-06amp;end_date=2021-09-05#panel'] results = [] for url in url_list: response = requests.get(url) src = response.content soup = BeautifulSoup(response.text , 'html.parser') results.append(soup.find_all( "td",class_= "text-center")) collected_data = dict() for result in results: for r in result: datas = r.find_all("td", title=True) for data in datas: collected_data.setdefault(data.text) collected_data
Ответ №1:
Что происходит?
В вашем первом for loop
вы только добавляете результирующий набор soup.find_all( "td",class_= "text-center")
to results
.
Так что вы не найдете то, что ищете, с помощью datas = r.find_all("td", title=True)
Обратите также внимание, что заголовки столбцов помещаются не в lt;tdgt;
, а в lt;thgt;
.
Как это исправить?
Вы могли бы выбрать более конкретные, все lt;trgt;
, lt;tbodygt;
чтобы повторить:
for row in soup.select('tbody tr'):
Во время итерации выберите lt;thgt;
и lt;tdgt;
и zip()
это dict()
в списке заголовков столбцов:
data.append( dict(zip([x.text for x in soup.select('thead th')], [x.text.strip() for x in row.select('th,td')])) )
Пример
import pandas as pd import requests from bs4 import BeautifulSoup url_list = ['https://www.coingecko.com/en/coins/ethereum/historical_data/usd?start_date=2021-08-06amp;end_date=2021-09-05#panel', 'https://www.coingecko.com/en/coins/cardano/historical_data/usd?start_date=2021-08-06amp;end_date=2021-09-05#panel', 'https://www.coingecko.com/en/coins/chainlink/historical_data/usd?start_date=2021-08-06amp;end_date=2021-09-05#panel'] data = [] for url in url_list: response = requests.get(url) src = response.content soup = BeautifulSoup(response.text , 'html.parser') for row in soup.select('tbody tr'): data.append( dict(zip([x.text for x in soup.select('thead th')], [x.text.strip() for x in row.select('th,td')])) ) pd.DataFrame(data)
Выход
Дата | Рыночная капитализация | Объем | Открыть | Закрыть |
---|---|---|---|---|
2021-09-05 | $456,929,768,632 | $24,002,848,309 | $3,894.94 | N/A |
2021-09-04 | $462,019,852,288 | $30,463,347,266 | $3,936.16 | $3,894.94 |
2021-09-03 | $444,936,758,975 | $28,115,776,510 | $3,793.30 | $3,936.16 |
Редактировать
Чтобы получить фрейм данных по URL — адресу, вы можете изменить код на следующий-он добавит фреймы в список, чтобы вы могли повторять действия.
Обратите внимание, что это основано на вашем комментарии, и если он подходит, хорошо. Я бы предложил хранить поставщика монет также в виде столбца, чтобы вы могли фильтровать, группировать по … по всем поставщикам, но это следует задать в новом вопросе, если это имеет значение.
dfList = [] for url in url_list: response = requests.get(url) src = response.content soup = BeautifulSoup(response.text , 'html.parser') data = [] coin = url.split("/")[5].upper() for row in soup.select('tbody tr'): data.append( dict(zip([f'{x.text}_{coin}' for x in soup.select('thead th')], [x.text.strip() for x in row.select('th,td')])) ) # if you like to save directly as csv... change next line to -gt; pd.DataFrame(data).to_csv(f'{coin}.csv') dfList.append(pd.DataFrame(data))
Выход
Выберите, например, фрейм данных по индексу списка dfList[0]
Дата-эфир | Рыночная капитал_этериум | объем_этериум | Open_этериум | Закрыть эфир |
---|---|---|---|---|
2021-09-05 | $456,929,768,632 | $24,002,848,309 | $3,894.94 | N/A |
2021-09-04 | $462,019,852,288 | $30,463,347,266 | $3,936.16 | $3,894.94 |
Комментарии:
1. Спасибо за ответ, это идеально, но я хотел создать 3 таблицы со столбцами формата ‘Market Cap_CURRENCYX’, ‘Volume_CURRENCYX’, ‘Open_CURRENCYX’, ‘Close_CURRENCYX’, ‘Market Cap_CURRENCYY’, ‘Volume_CURRENCYY’, ‘Open_CURRENCYY’, ‘Close_CURRENCYY’, … для каждого.
2. Не могли бы вы, случайно, помочь мне и в этом тоже?