CoderCastrov logo
CoderCastrov
Питон

Запланированный парсинг веб-сайта с помощью Django и Heroku

Запланированный парсинг веб-сайта с помощью Django и Heroku
просмотров
7 мин чтение
#Питон

Создание приложения Django, которое ежедневно парсит доску вакансий

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

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

Решение? Ежедневно парсить их доску вакансий, чтобы я получал уведомление о каждой новой вакансии.

Давайте создадим простое приложение Django, развернем его на Heroku и будем ежедневно парсить доску вакансий.

Настройка приложения

Создайте каталог для приложения и перейдите в него с помощью команды cd.

mkdir jobs && cd jobs

Откройте его в выбранном вами редакторе кода. Я использую Sublime.

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

python -m venv env
source env/bin/activate
pip3 install django psycopg2 django-heroku bs4 gunicorn

Создайте проект (веб-приложение Django).

django-admin startproject jobs

Перейдите в каталог проекта и создайте приложение для парсинга.

cd jobs
django-admin startapp parsing

Создание модели Job

Нам понадобится определить только одну модель в этом приложении - модель Job. Она представляет собой собранные нами вакансии.

Перепишите /parsing/models.py следующим образом.

from django.db import models
from django.utils import timezone

class Job(models.Model):
    url = models.CharField(max_length=250, unique=True)
    title = models.CharField(max_length=250)
    location = models.CharField(max_length=250)
    created_date = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ['title']

    class Admin:
        pass

Зарегистрируйте свою модель в /parsing/admin.py. Это позволит нам просматривать записи в стандартной панели администратора Django (о ней мы поговорим позже).

from parsing.models import Job
admin.site.register(Job)

Добавьте parsing в установленные приложения в /jobs/settings.py.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'parsing'
]

Настройка базы данных

Настройте базу данных. Я предпочитаю использовать postgres, поэтому мы будем использовать его.

На данном этапе убедитесь, что вы уже установили postgres на своем Mac с помощью brew и запустили его (это выходит за рамки данной статьи).

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

psql -d template1

Создайте пользователя и базу данных, затем выйдите.

create user django_user;
create database django_jobs owner django_user;
\q

В файле /jobs/settings.py обновите DATABASES. В других фреймворках вы захотели бы указать их специально для среды разработки, но здесь мы не будем об этом беспокоиться. В любом случае это будет работать на Heroku (мы скоро дойдем до этого).

Обратите внимание, что это имена пользователя и базы данных, которые мы создали выше.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'django_jobs',
        'USER': 'django_user',
        'HOST': '',
        'PORT': ''
    }
}

Создайте миграции и выполните миграцию базы данных из командной строки.

python manage.py makemigrations
python manage.py migrate

Это создаст таблицу с названием scraping_job. Это соглашение пространства имен Django, потому что она принадлежит приложению scraping.

Теперь создайте суперпользователя и установите ему пароль в командной строке.

python manage.py createsuperuser --email admin@example.com --username admin

Тестирование текущего приложения

Мы уже проделали некоторую работу, но не знаем, работает ли что-нибудь. Давайте протестируем его, прежде чем продолжать.

В командной строке выполните следующую команду:

python manage.py runserver

Затем перейдите по адресу http://127.0.0.1:8000/admin в вашем браузере. Войдите в систему с помощью только что созданного суперпользователя.

После входа в систему нажмите на "jobs" в разделе "scraping", затем на "add job" в правом верхнем углу. Теперь заполните некоторую выдуманную информацию и нажмите "save". Если вы видите созданную вами задачу, значит, все работает до этого момента!

Пользовательские команды django-admin

Мы собираемся настроить пользовательскую команду django-admin, которая будет парсить доску вакансий. Это то, что мы будем автоматически планировать на уровне инфраструктуры для автоматизации парсинга.

Внутри модуля /scraping создайте каталог /management, а внутри /management создайте каталог /commands. Затем создайте 2 файла Python: _private.py и scrape.py в /commands.

Не показывается все в /scraping здесь

Вставьте этот код в файл scrape.py.

from django.core.management.base import BaseCommand
from urllib.request import urlopen
from bs4 import BeautifulSoup
import json
from scraping.models import Job

class Command(BaseCommand):
    help = "collect jobs"
    
    def handle(self, *args, **options):
        html = urlopen('https://jobs.lever.co/opencare')
        soup = BeautifulSoup(html, 'html.parser')
        postings = soup.find_all("div", class_="posting")
        
        for p in postings:
            url = p.find('a', class_='posting-btn-submit')['href']
            title = p.find('h5').text
            location = p.find('span', class_='sort-by-location').text
            
            try:
                Job.objects.create(
                    url=url,
                    title=title,
                    location=location
                )
                print('%s added' % (title,))
            except:
                print('%s already exists' % (title,))
        
        self.stdout.write('job complete')

Размещение кода в такой структуре каталогов, а затем определение класса Command с функцией handle говорит django, что это пользовательская команда django-admin.

Здесь мы используем библиотеку Beautiful Soup для парсинга доски вакансий Lever, а затем сохраняем ее в нашей базе данных. У меня нет отношения к этой компании, но я выбрал доску вакансий для фантастической компании Opencare - вы можете подать заявку, если они что-то разместят!

Теперь вы можете запустить эту команду из командной строки следующим образом:

python manage.py scrape

И вы увидите этот вывод:

Запустите его снова и вы увидите это:

Это происходит потому, что мы предотвращаем добавление дублирующихся записей о вакансиях в коде scrape.py выше.

Если у вас настроена программа администрирования базы данных (например, dbeaver), вы также можете просматривать строки в вашей базе данных. Мы не будем вдаваться в это здесь, но это должно выглядеть примерно так:

Развертывание в продакшн

Теперь давайте развернем это на Heroku.

Заморозьте ваши зависимости, чтобы Heroku знал, что установить при развертывании.

pip3 freeze > requirements.txt

В командной строке выполните nano .gitignore и добавьте следующее.

.DS_Store
jobs/__pycache__
scraping/__pycache__

Затем ctrl+x, y, enter для сохранения и закрытия (на Mac). Это предотвратит развертывание ненужных файлов.

Создайте файл с названием Procfile в корневой папке и вставьте следующее внутрь. Это сообщает Heroku запустить веб-дино и выполнить вторую команду для миграции базы данных.

web: gunicorn jobs.wsgi
release: python manage.py migrate

Структура файлов будет выглядеть так.

Убедитесь, что у вас есть учетная запись [Heroku](http://heroku create flask-ml-api-123), затем выполните вход с помощью heroku login в командной строке.

Создайте приложение с любым именем, которое вам нравится. Но оно должно быть уникальным среди всех приложений на Heroku. Я использовал heroku create django-scraper-879, где имя приложения - django-scraper-879. Но вам нужно выбрать свое собственное имя.

Теперь добавьте эти строки в самый конец файла settings.py. heroku_django заботится о некоторых настройках, таких как (статические файлы / WhiteNoise) за вас.

import django_heroku
django_heroku.settings(locals())

Обновите DEBUG в настройках. Не хотим развертывать в продакшн в режиме отладки.

DEBUG = False

Добавьте файлы в git с помощью следующей команды.

git init
git add . -A
git commit -m 'first commit'

Теперь отправьте наше приложение на Heroku с помощью этой команды.

git push heroku master

Планирование работы

Вы можете запустить задачу вручную из локальной командной строки с помощью heroku run python manage.py scrape, но было бы неприятно каждый день запускать ее вручную.

Давайте автоматизируем это.

Войдите в консоль Heroku и перейдите в раздел "Resources", затем "find more add-ons".

Теперь найдите и нажмите на этот дополнительный модуль. Попробуйте использовать комбинацию клавиш "ctrl+f", чтобы его найти. У Heroku есть огромное количество потенциальных дополнительных модулей. Он выглядит примерно так.

Теперь добавьте его к своему приложению, чтобы у вас было следующее.

Нажмите на него и создайте задачу, everyday at… 12am UTC. Не стоит чаще, чем необходимо, обращаться к веб-сайтам!

Введите свою команду и сохраните ее.

Сохраните и мы закончили!

Теперь просто дождитесь 12 часов UTC (или любого другого времени, которое вы выбрали), и ваша база данных будет заполняться.

Заключение

Мы затронули много вещей здесь. Django, Heroku, планирование, парсинг веб-страниц, Postgres.

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

  • Компании электронной коммерции хотят отслеживать цены конкурентов.
  • Рекрутеры топ-менеджеров могут хотеть видеть, когда компания размещает вакансию.
  • Вы или я можем хотеть видеть, когда на Kaggle добавляется новое соревнование.

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