Золотое масло для специалиста по данным и программиста по машинному обучению — это набор данных. Без данных анализ и моделирование невозможны.

Темы этой истории

  • способ собрать набор данных
  • пример парсинга веб-страниц
  • планирование

Когда мы начинаем новый проект по анализу данных и/или моделированию машинного обучения, необходимо выполнить несколько задач, прежде чем прыгать или углубляться в кодирование.

Сбор данных является одним из самых важных. Существует несколько вариантов получения набора данных (после определения проекта). Мы можем найти набор данных в Интернете. Интернет предлагает тысячи ссылок, по которым данные можно скачать (бесплатно или за плату) и загрузить в свой проект. Набор данных можно создать вручную (я играю в гольф и собираю статистику в блокноте — вручную — а затем заполняю текстовый файл).

В этом посте я хотел бы рассказать о третьем варианте, говоря о веб-скрапинге.

Википедия возобновляет темы как «извлечение данных с веб-сайтов».



Я объясню, как создать программу веб-скрейпинга для сбора данных о коронавирусе и запланировать ежедневные свежие данные для ноутбуков.

Пример веб-скрейпинга

Блокнот определит функцию сбора данных с https://www.worldometers.info/coronavirus/. Взглянув на исходный html-код, мы можем выделить раздел, в котором создается таблица, и определить структуру таблицы для подробной статистики по каждой стране ['Всего случаев', 'Новых случаев', …, 'Население' ].

Давайте импортируем несколько библиотек

import bs4
import pandas as pd
import requests
import time
from datetime import datetime
import threading
import numpy as np

Библиотеки bs4 и потоковой передачи находятся в центре внимания этой истории. Beautiful Soup предлагает методы сканирования исходного HTML-кода и изолирует теги для сбора данных. Собранные данные будут просто добавлены в фрейм данных, который будет сохранен после конкатенации с историей (я загружаю исходный файл в фрейм данных, выполняю веб-скрапинг во временном фрейме данных и, наконец, объединяю оба фрейма данных и сохраняю их в исходном имя).

Чтение URL-адреса и возврат содержимого

def get_page_contents(url):
    page = requests.get(url, headers={"Accept-Language": "en-US"})
    return bs4.BeautifulSoup(page.text, "html.parser")

Функция соскабливания и нарезание резьбы

Код для очистки содержимого определяется в функции. Функция вызывается с использованием метода таймера потоков. Я начинаю с создания функции scrapping_url() и устанавливаю некоторые константы.

def scrapping_url():
    data = []
    url='https://www.worldometers.info/coronavirus/'
    root_url = url

Затем это волшебная линия для планирования и воспроизведения, воспроизведения и повторного воспроизведения функции.

    threading.Timer(30.0, scrapping_url).start()

30.0 указывает планировщику запускать функцию scrapping_url каждые 30 секунд (хорошо для проверки), но в реальной жизни я установил эти параметры на 36000 для сбора данных каждые 10 часов. Во время моего анализа я управляю повторяющимися строками в днях (я сделал это, чтобы иметь согласованные данные и не слишком сильно зависеть от часового пояса).

Работа с содержимым страницы

    soup = get_page_contents(url)
    entries = soup.findAll('div', class_='maincounter-number')
    rat = [e.find('span', class_='').text for e in entries]
    table = soup.find('table', 
       attrs={'class':'table table-bordered table-hover  main_table_countries'})
    table_body = table.find('tbody')
    rows = table_body.find_all('tr')

Строки содержат таблицу. С помощью простого цикла for row in rows: легко извлекать данные для каждой строки (обрабатывая ячейку за ячейкой) и сохранять результат в списке.

#I don't want to get data from the 1st row of the table
    dont_do_1_row=False
    for row in rows:
        if dont_do_1_row:
            cols = row.find_all('td')
            d=[]
            for c in cols:
                v=c.text.strip()
                d.append(v) #replaced i by v
            temp=[]
            for a in d:
                if a != '':
                    try:
                        i=int(a.replace(',',''))
                    except:
                        i=a
                else:
                    i=a
                temp.append(i)
            data.append(temp)            
        dont_do_1_row=True

В конце цикла содержимое списка может быть добавлено в список списка, который будет преобразован во временный фрейм данных и, наконец, объединен с глобальным файлом.

colname = ['Rank','Location' , 'Cases', 'New Cases'
              , 'Deaths','New Deaths', 'Recovered',
              'Actives','Serious','Case-1M'
              ,'Deaths-1M','Tests','Tests-1M'
               ,'Population','Continent',
               'dummy1','dummy2','dummy3','dummy4']
    df=pd.DataFrame(data, columns=colname)
    df['DateTime']=datetime.now()
    #read row data
    try:
        covid_global = pd.read_excel('covid_data.xlsx, index_col=0) 
    except:
        covid_global = None
    #append last readed line(s)
    try:
        covid_fusion = covid_global.append(df,  
          ignore_index=True, verify_integrity=False, sort=None)
    except:
        covid_fusion = df.copy()
    #save file with just row data scrapping from website        
    covid_fusion.to_excel('covid_data.xlsx')

Вызовите глобальную функцию, и работа сделана!

scrapping_url()

Сотрясение

  • волшебная строка - это вызов threading.timer
  • программа работает до тех пор, пока определение сайта не меняется
  • некоторые веб-сайты могут быть очень сложными для анализа, а те, у которых нет чистого html, выходят за рамки
  • Я предполагаю, что в проекте моделирования свежие данные можно использовать для проверки точности модели и запуска тонкой настройки.