Соберите исторические данные о биткоинах с Coinmarketcap с помощью BeautifulSoup

#python #pandas #web-scraping #beautifulsoup

Вопрос:

Я пытаюсь соскрести исторические данные о биткоинах с coinmarketcap.com чтобы приблизиться, укажите объем, дату, высокие и низкие значения с начала года до 30 сентября 2021 года. После многочасового просмотра тем и видео, а я новичок в работе с Python, я не знаю, в чем моя ошибка (или есть что-то с веб-сайтом, чего я не обнаруживаю?). Ниже приведен мой код:

 from bs4 import BeautifulSoup import requests import pandas as pd   closeList = [] volumeList = [] dateList = [] highList = [] lowList = []  website = 'https://coinmarketcap.com/currencies/bitcoin/historical-data/'  r = requests.get(website)  r = requests.get(website) soup = BeautifulSoup(r.text, 'lxml')  tr = soup.find_all('tr') FullData = [] for item in tr:  closeList.append(item.find_all('td')[4].text)  volumeList.append(item.find_all('td')[5].text)  dateList.append(item.find('td',{'style':'text-align: left;'}).text)  highList.append(item.find_all('td')[2].text)  lowList.append(item.find_all('td')[3].text)  FullData.append([closeList,volumeList,dateList,highList,lowList])  df_columns = ["close", "volume", "date", "high", "low"]  df = pd.DataFrame(FullData, columns = df_columns) print(df)  

В результате я получаю только:

 Empty DataFrame Columns: [close, volume, date, high, low] Index: []  

Задача обязывает меня очистить BeautifulSoup, а затем экспортировать в csv (что, очевидно, тогда просто df.to_csv — может ли кто-нибудь мне помочь? Это было бы весьма признательно.

Ответ №1:

На самом деле данные динамически загружаются javascript из api-вызовов json-ответа. Таким образом, вы можете легко получить данные следующим образом:

Код:

 import requests import json import pandas as pd api_url= 'https://api.coinmarketcap.com/data-api/v3/cryptocurrency/historical?id=1amp;convertId=2781amp;timeStart=1632441600amp;timeEnd=1637712000' r = requests.get(api_url) data = [] for item in r.json()['data']['quotes']:  close = item['quote']['close']  volume =item['quote']['volume']  date=item['quote']['timestamp']  high=item['quote']['high']  low=item['quote']['low']  data.append([close,volume,date,high,low])   cols = ["close", "volume","date","high","low"]  df = pd.DataFrame(data, columns= cols) print(df) #df.to_csv('info.csv',index = False)  

Выход:

 close volume date high low 0 42839.751696 4.283935e 10 2021-09-24T23:59:59.999Z 45080.491063 40936.557169 1 42716.593147 3.160472e 10 2021-09-25T23:59:59.999Z 42996.259704 41759.920425 2 43208.539105 3.066122e 10 2021-09-26T23:59:59.999Z 43919.300970 40848.461660 3 42235.731847 3.098003e 10 2021-09-27T23:59:59.999Z 44313.245882 42190.632576 4 41034.544665 3.021494e 10 2021-09-28T23:59:59.999Z 42775.146142 40931.662500 .. ... ... ... ... ... 56 58119.576194 3.870241e 10 2021-11-19T23:59:59.999Z 58351.113266 55705.180685 57 59697.197134 3.062426e 10 2021-11-20T23:59:59.999Z 59859.880442 57469.725661 58 58730.476639 2.612345e 10 2021-11-21T23:59:59.999Z 60004.426383 58618.931432 59 56289.287323 3.503612e 10 2021-11-22T23:59:59.999Z 59266.358468 55679.840404 60 57569.074876 3.748580e 10 2021-11-23T23:59:59.999Z 57875.516397 55632.759912  [61 rows x 5 columns]  

Комментарии:

1. Это действительно впечатляет — огромное спасибо @Fazlul! Один последующий вопрос: можно ли это также сделать с помощью BeautifulSoup или Селена?

2. @Джеффри Сакс, это совершенно невозможно сделать с помощью BeautifulSoup только потому, что URL-адрес динамичен. Если вы отключите javacript из браузера, вы заметите, что данные исчезают с URL-адреса. Да, это возможно с использованием селена, но немного сложнее. Приведенное выше решение является лучшим, самым простым и быстрым способом извлечения данных. Спасибо

3. большое спасибо за вашу помощь. Очень признателен!