Как выполнить итерацию сценария webscraping над объектом ежедневного временного ряда для создания ежедневного временного ряда данных с веб-страницы - PullRequest
2 голосов
/ 07 апреля 2019

Спасибо, что заглянули на мой вопрос. Я создал скрипт с использованием BeautifulSoup и Pandas, который собирает данные о прогнозах с сайта Федеральной резервной системы. Прогнозы выходят раз в квартал (~ 3 мес.). Я хотел бы написать сценарий, который создает ежедневные временные ряды и проверяет веб-сайт Федеральной резервной системы один раз в день, и если бы был опубликован новый прогноз, сценарий добавил бы это к временным рядам. Если обновления не было, сценарий просто добавил бы временной ряд с последним действительным обновленным прогнозом.

Из моего начального копания кажется, что есть внешние источники, которые я могу использовать для ежедневного "запуска" сценария, но я бы предпочел, чтобы все оставалось чисто python.

Код, который я написал для выполнения очистки, выглядит следующим образом:

from bs4 import BeautifulSoup
import requests
import re
import wget
import pandas as pd 

# Starting url and the indicator (key) for links of interest
url = "https://www.federalreserve.gov/monetarypolicy/fomccalendars.htm" 
key = '/monetarypolicy/fomcprojtabl'

# Cook the soup
page = requests.get(url)
data = page.text
soup = BeautifulSoup(data)

# Create the tuple of links for projection pages
projections = []
for link in soup.find_all('a', href=re.compile(key)):
    projections.append(link["href"])

# Create a tuple to store the projections 
decfcasts = []
for i in projections:
    url = "https://www.federalreserve.gov{}".format(i)
    file = wget.download(url)
    df_list = pd.read_html(file)
    fcast = df_list[-1].iloc[:,0:2]
    fcast.columns = ['Target', 'Votes']
    fcast.fillna(0, inplace = True)
    decfcasts.append(fcast)

Пока что код, который я написал, помещает все в кортеж, но для данных нет индекса времени / даты. Я думал о псевдокоде, чтобы написать, и я думаю, это будет выглядеть примерно так:

Create daily time series object
    for each day in time series:
        if day in time series = day in link:
            run webscraper
        other wise, append time series with last available observation

По крайней мере, это то, что я имею в виду. Последний временной ряд, вероятно, в конечном итоге должен выглядеть довольно «комковатым» в том смысле, что будет много дней с одним и тем же наблюдением, а затем, когда выйдет новая проекция, произойдет «скачок», а затем еще много повторение, пока не выйдет следующий прогноз.

Очевидно, что любая помощь чрезвычайно ценится. Спасибо заранее, в любом случае!

1 Ответ

1 голос
/ 09 апреля 2019

Я редактировал код для вас. Теперь это получить дату от URL. Дата сохраняется как период в датафрейме. Только когда дата отсутствует в кадре данных (восстановлена ​​из рассола), она обрабатывается и добавляется.

from bs4 import BeautifulSoup
import requests
import re
import wget
import pandas as pd

# Starting url and the indicator (key) for links of interest
url = "https://www.federalreserve.gov/monetarypolicy/fomccalendars.htm"
key = '/monetarypolicy/fomcprojtabl'

# Cook the soup
page = requests.get(url)
data = page.text
soup = BeautifulSoup(data)

# Create the tuple of links for projection pages
projections = []
for link in soup.find_all('a', href=re.compile(key)):
    projections.append(link["href"])

# past results from pickle, when no pickle init empty dataframe
try:
    decfcasts = pd.read_pickle('decfcasts.pkl')
except FileNotFoundError:
    decfcasts = pd.DataFrame(columns=['target', 'votes', 'date'])


for i in projections:

    # parse date from url
    date = pd.Period(''.join(re.findall(r'\d+', i)), 'D')

    # process projection if it wasn't included in data from pickle
    if date not in decfcasts['date'].values:

        url = "https://www.federalreserve.gov{}".format(i)
        file = wget.download(url)
        df_list = pd.read_html(file)
        fcast = df_list[-1].iloc[:, 0:2]
        fcast.columns = ['target', 'votes']
        fcast.fillna(0, inplace=True)

        # set date time
        fcast.insert(2, 'date', date)
        decfcasts = decfcasts.append(fcast)

# save to pickle
pd.to_pickle(decfcasts, 'decfcasts.pkl')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...