CoderCastrov logo
CoderCastrov
Анализ данных

BYOD: Создание собственного набора данных (бесплатно с использованием парсинга веб-сайтов)

BYOD: Создание собственного набора данных (бесплатно с использованием парсинга веб-сайтов)
просмотров
8 мин чтение
#Анализ данных

**Основная идея: **Узнайте, как создать свой собственный набор данных с помощью простого парсинга веб-сайтов, который собирает отзывы на игры со всего сайта Metacritic с использованием beautiful soup в Python и размещается бесплатно на платформе Google Cloud Platform (GCP) micro (всегда бесплатный уровень)

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

Один из способов получить надежные наборы данных - это либо платить за них, либо записываться на дорогостоящие курсы, а другой способ - это парсинг веб-сайтов. Здесь я расскажу вам, как собирать большие наборы данных с использованием Python бесплатно!

Почему я выбрал парсинг веб-страниц и использование Google Cloud?

  • Данные устаревают: При парсинге данных вы можете получить самую актуальную информацию по любой теме. Хотя вы можете получить надежные наборы данных с Kaggle, если вы хотите создать что-то новое для себя или своей компании, парсинг - это правильный выбор. Например, если вы хотите создать рекомендацию по ценам на обувь, вам понадобятся последние тренды и цены с Amazon, а не данные за 2 года.
  • Настроенность под вас: Вы можете настроить код так, чтобы получать только нужные вам данные из любого источника.
  • Почему не локально? С такими крупными игроками, как Google и Amazon, на рынке облачных вычислений очень дешево арендовать ПК на несколько часов. Они также предоставляют бесплатный уровень, который идеально подходит для чего-то простого, например, для парсинга веб-страниц. GCP немного дешевле и дает вам кредит в размере 300 долларов для начала, поэтому я выбрал GCP. Кроме того, я не хотел, чтобы мой IP-адрес был заблокирован (ха-ха).
  • Веселье: Ну, это мое представление о пятничном вечере!

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

Начало работы

Все, что вам нужно сделать, это перебрать список URL-адресов, определить контейнеры для данных, извлечь данные и сохранить их в CSV-файле.

1. Используемые библиотеки

import urllib2
import csv
from bs4 import BeautifulSoup
import pandas as pd
  • urllib2: наша библиотека для отправки запросов URL.
  • csv: библиотека для сохранения данных в CSV-файле.
  • bs4: библиотека Beautiful Soup, которая упрощает извлечение данных с веб-страницы.
  • pandas: сохранение данных в удобном табличном формате.

2. Понимание структуры веб-сайта

Макет Metacritic довольно прост. Все данные структурированы следующим образом:

http://www.metacritic.com/browse/**games**/release-date/available/pc/metascore?view=detailed&page=1

давайте разберем его:

  • http://www.metacritic.com/browse/: это домен
  • games: это подраздел и может быть заменен на movies/music для других подразделов
  • available/pc/: эта часть предоставляет данные для ПК. Измените это на ps4, чтобы получить данные о играх для PS4.
  • metascore: это дает рейтинги по метаскору, мы можем изменить это на "user_rating" для получения данных по рейтингу пользователей.
  • view=detailed: это дает тип просмотра, мы выбираем детальный, так как он содержит больше данных, таких как жанр и возрастной рейтинг.
  • page=x: это дает номер страницы x. Если номер страницы не существует, сайт возвращает пустую страницу-шаблон без данных и не выдает ошибку.

Затем мы определяем элементы HTML, в которых находятся данные. Для этого мы используем инструмент inspect в Chrome. Мы выбираем элементы и выделяем подраздел, чтобы получить элемент HTML и его класс.

данные о дате выпуска находятся в элементе **li** с классом **_stat release_date_**

Теперь мы знаем, какой элемент нам нужно извлечь, давайте перейдем к его извлечению.

3. Отправка запросов URL

metacritic_base = “http://www.metacritic.com/browse/games/release-date/available/pc/metascore?view=detailed&page="hdr= {‘Accept’: ‘text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8’, ‘User-Agent’ : “Magic Browser”}filepath=’/Users/rra/Downloads/’for i in range(0,54):
    metacritic = metacritic_base+str(i)
    page = urllib2.Request(metacritic, headers=hdr )
    content = urllib2.urlopen(page).read()

Metacritic имеет простую структуру сайта с фиксированным URL-адресом, где номер страницы меняется для каждой страницы.

Мы используем urllib2.Request для запроса страницы и Urllib2.urlopen для чтения данных страницы.

Совет: Всего 53 страницы, поэтому я установил максимальное значение счетчика на 54, однако вы можете просто включить все это в try except, который завершается при возникновении ошибки.

4. Извлечение данных

Затем мы считываем данные

soup = BeautifulSoup(content, ‘html.parser’)
right_class=soup.find_all(‘div’, class_=’product_wrap’)
for item in right_class:    try:
      link=item.find(‘h3’, class_=”product_title”).find(“a”)
      g=link.get(‘href’)
      except: g=’'      try:
        score = item.find(“span”, class_=”metascore_w”)
        s=score.text
      except: s =’’      try:
       dt = item.find("li", class_="release_date").find("span",    class_="data")
       d=dt.text
      except: dt=''     try:
       rating=item.find("li",class_="stat  maturity_rating").find("span", class_="data")
       r= rating.text
     except: r=""    try:
      pub =item.find("li",class_="stat publisher").find("span", class_="data")
      p= pub.text
    except: p=''
   
   try:
     genre= item.find("li",class_="stat genre").find("span", class_="data")
     gr = genre.text
   except: gr=''  try:
   user_score=item.find("span", class_="textscore")
   u = user_score.text
   except: u=''

Мы используем BeautifulSoup(content, ‘html.parser’), который выполняет всю тяжелую работу по разбору огромного количества HTML.

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

  • g: название игры
  • s: метаскор
  • d: дата выпуска
  • p: издатель
  • r: возрастной рейтинг
  • u: рейтинг пользователей
  • gr: жанр

Совет: HTML ненадежен, поэтому лучше использовать try: except с каждым извлечением

5. Сохранение данных

game=[g,s,d,r,p,gr.strip(),u]
df = pd.DataFrame([game])
with open(filepath+'gamenames.csv', 'a') as f:
   df.to_csv(f, header=False, index=False, quoting=csv.QUOTE_NONNUMERIC, sep="|")

Мы используем pandas, чтобы преобразовать список списков в таблицу, а затем записываем данные в CSV-файл. Здесь мы используем | в качестве разделителя, так как столбец жанра содержит , (запятую).

6. Запуск кода в Google Cloud

Я предполагаю, что вы знаете, как настроить учетную запись GCP. Если нет, пожалуйста, следуйте этому блог-посту о том, как это сделать. Вам нужно создать экземпляр следующим образом.

Создание экземпляра GCP

После запуска вам нужно установить python на него и скопировать код с локальной машины на экземпляр. Здесь spheric-crow - это имя проекта, а instance-2 - это имя экземпляра. Вам также нужно указать часовой пояс для Google.

Совет: Не забудьте обновить Ubuntu после подключения к экземпляру по SSH.

gcloud compute — project “spheric-crow” ssh — zone “us-east1-b” “instance-2”gcloud compute scp scrap.py instance-1:scrap

scp копирует файл с локальной машины на экземпляр GCP. Затем вам нужно установить упомянутые выше библиотеки на вашем экземпляре. Затем установите byobu, который является текстовым менеджером окон. Это позволит сохранить сеанс даже при разрыве SSH-соединения.

Sudo apt-get install byobu
byobu
интерфейс byobu, вы можете создавать отдельные вкладки и выполнять несколько кодов одновременно

Наконец, запустите код с помощью следующей команды, и вы закончили.

python scrap.py

Совет: Вы можете использовать scp или просто git pull из моего аккаунта на GitHub.

7. Получение собранных данных

Вы можете получить собранные данные из облака с помощью scp, и теперь у вас есть действительно интересный набор данных для работы!

gcloud compute scp instance-1:scrap/game_review.csv /Users/

затем вы можете получить доступ к данным с помощью python, как показано ниже:

import pandas as pd
df= pd.read_csv(“/metacritic_scrap/gamenames.csv”, sep=”|”)
df.columns=[“game”, “metascore”,”release_date”, “maturity_rating”,”publisher”, “genre”, “user_rating”]

и ваш набор данных будет выглядеть так:

Обратите внимание, насколько хорошо структурированы данные!

Совет: Вы также можете автоматизировать это!

Советы и трюки

  • Задержка: Включите задержку, которая задерживает выполнение кода на несколько секунд перед отправкой следующего запроса. Я предпочитаю использовать sleep (randint(a,b)), то есть использовать случайное целое число вместо фиксированного значения.
from random import randint
from time import sleep
#пауза на 20-100 секунд случайным образом
sleep(randint(20,100))
  • User Agent: Это строка, которую браузер или приложение отправляет на каждый посещаемый вами сайт. Мы используем генератор user_agent, чтобы обмануть сайт и заставить его думать, что запрос приходит из разных браузеров. Поскольку многие учреждения используют один и тот же IP-адрес, мы обычно не рискуем получить ошибку слишком многих запросов. Здесь есть список популярных user agents, которые вы можете использовать.
from user_agent import generate_user_agent
  • VPN и прокси: Если вы собираете большой объем данных, вероятно, вы рано или поздно получите ошибку слишком многих запросов. В моем случае это происходит примерно каждые 2000 страниц. Чтобы справиться с этим, вы можете использовать несколько прокси и получить около 5 тысяч страниц за один запуск. Вы можете получить несколько бесплатных прокси здесь.

2. Попали в капчу: Некоторые веб-сайты действительно не хотят, чтобы вы парсили их данные, и они устанавливают капчу. Если это простая капча из 4–5 буквенно-цифровых символов, вы можете попробовать ее обойти, используя Python Tesseract и эту технику. Если это капча Google reCAPTCHA, вам придется решать ее вручную каждый раз, как и эти ребята.

3. Обработка исключений: HTML очень ненадежен, и сайт может не всегда следовать строгому шаблону, поэтому лучшей практикой является включение каждого элемента в блок try:except.

  1. Периодическое сохранение: Парсинг веб-сайтов - это рискованное дело, и если вы не регулярно сохраняете данные, вы можете потерять всю добытую до сих пор информацию. Простое решение - регулярное сохранение данных в формате csv (как я делаю) или использование SQLite (как делают умные люди). Введение в SQLite можно найти здесь.

Что дальше?

Мы можем использовать тот же код для парсинга Metacritic для множества другого контента, просто изменив базовый URL:

  • обзоры/рейтинги фильмов
  • обзоры/рейтинги телешоу
  • обзоры/рейтинги музыки

Я расширил свой код для сбора данных о всех ~100 тыс. пользовательских обзорах для ~5 тыс. компьютерных игр, и я уже упоминал, что собираюсь использовать его для создания рекомендательной системы для игр (подробности в следующих блог-постах). Если вы хотите получить часть этих данных, напишите мне, и я отправлю вам часть набора данных!

Макет сайта Metacritic довольно прост в использовании и может быть воспроизведен с помощью простого цикла for, но для сбора данных с более сложных сайтов, таких как Amazon, мы используем инструмент автоматизации браузера под названием Puppeteer, который имитирует нажатия кнопок для перехода на следующую страницу и так далее.

Ознакомьтесь с этим отличным блогом от Emad Eshan о том, как использовать Puppeteer.

Весь код для этого блога можно найти на моем git. Весь код для парсинга пользовательских обзоров также можно найти здесь.

В следующем блоге я буду проводить обработку данных и глубокое обучение на этом отличном наборе данных. Следите за обновлениями!

Это мой первый пост, поэтому, если вам понравилось, оставьте комментарий и поставьте лайк :)