Skip to content

ecodomen/nsreg-watcher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ngreg-watcher

ecodomen.ru flake8 linter deploy and build

License MIT Code style black Python versions Django versions Postgres version Nginx Redis Telegram

Установка и запуск

💡 Необходимо для запуска

Установка

Клонировать репозиторий:

git clone git@github.com:ecodomen/nsreg-watcher.git

Перейти в директорию проекта:

cd nsreg-watcher

Создать виртуальное окружение.

  • Если версии Python, установленная в системе по умолчанию, соответствует требованиям, выполнить:
python3 -m venv env
  • или указать версию Python явно:
python3.11 -m venv env

Активировать виртуальное окружение:

source env/bin/activate

Обновить pip:

pip install pip -U

Установить зависимости:

pip install -r requirements.txt

В корневой директории проекта создать файл .env и заполнить его по шаблону .env.template

База данных

  • Использование локальной СУБД PostgreSQL.

    • Создать базу данных:
    createdb -U postgres -h localhost -p 5432 nsreg
  • Запуск PostgresSQL в Docker.

    • Экспортировать переменные окружения:
    export $(echo $(cat .env | sed 's/#.*//g'| xargs) | envsubst)
    • выполнить запуск сервисов:
    sudo docker compose up -d

Выполнить миграции:

python src/website/manage.py migrate

Запуск

Запустить dev сервер Django:

python src/website/manage.py runserver

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

cd <PATH>/nsreg-watcher

Проверить и при необходимости задать права -rwxrwxr-x на выполнение runspiders.sh:

ls -l runspiders.sh
chmod 775 runspiders.sh

Выполнить скрипт для запуска scrapy:

./runspiders.sh

Дождаться завершения парсинга.

Создание спайдера

В папке нужно создать новый парсер с обязательным нэймингом "nsreg_sitename"

Посмотрите пример парсера с использованием композиции:

По аналогии пишете имена, ссылки в классе вашего Спайдера. site_name нужно найти на сайте регистратора:

class NsregDomainshopSpider(scrapy.Spider):
    name = "nsreg_domainshop.py"
    start_urls = ["https://domainshop.ru/services/"]
    allowed_domains = ("domainshop.ru")
    site_names = ("ООО «Лавка доменов»",)

Подбираете путь к ценам: покупка домена, продление, перенос. Например:

'price_reg': '/html/body/div/div[2]/div/div/div/div/div[3]/div/div/div/div/table/tbody/tr[1]/td[2]/div/text()'

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

Подбираете регулярное выражение (поможет сайт Regex):

regex=r"([0-9]+[.,\s])?руб"
# -*- coding: utf-8 -*-
import scrapy

from ..base_site_spider import BaseSpiderComponent


# Пример спайдера для одного сайта
class NsregDomainshopSpider(scrapy.Spider):
    name = "nsreg_domainshop.py"
    start_urls = ["https://domainshop.ru/services/"]
    allowed_domains = ("domainshop.ru")
    # в site_names важно поставить запятую, иначе scrapy вместо целого названия вставит одну букву
    site_names = ("ООО «Лавка доменов»",)

    def __init__(self, name=None, **kwargs):
        super().__init__(name, **kwargs)
        self.component = BaseSpiderComponent(
            start_urls=self.start_urls,
            allowed_domains=self.allowed_domains,
            site_names=self.site_names,
            regex=r"([0-9]+[.,\s])?руб",
            path={
                'price_reg': '/html/body/div/div[2]/div/div/div/div/div[3]/div/div/div/div/table/tbody/tr[1]/td[2]/div/text()',
                'price_prolong': '/html/body/div/div[2]/div/div/div/div/div[3]/div/div/div/div/table/tbody/tr[4]/td[2]/div/p/text()',
                'price_change': '/html/body/div/div[2]/div/div/div/div/div[3]/div/div/div/div/table/tbody/tr[7]/td[2]/div/text()'
            }
        )

    # Метод для обработки ответов на запросы
    def parse(self, response):
        # Применение метода parse компонента BaseSpiderComponent
        return self.component.parse(response)

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

regex = {
    'price_reg': 'your_regex1',
    'price_prolong': 'your_regex2',
    'price_change': 'your_regex3'
}

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

from nsreg.items import NsregItem()
EMPTY_PRICE = {
    'price_reg': None,
    'price_prolong': None,
    'price_change': None,
}

...

def parse_price_change(self, response):
        price_change = response.xpath(self.component.path['price_change']).get()
        price_change = find_price(, price_change)

        item = NsregItem()
        item['name'] = "ООО «Ваш ООО»"
        price = item.get('price', EMPTY_PRICE)
        price['price_change'] = price_change
        item['price'] = price
        price['price_change'] = price_change
        item['price'] = price

        yield item

А также вызвать ее из функции parse:

def parse(self, response):
    price_reg = response.xpath(self.pathreg).get()
    price_reg = self.find_price(self.regex_reg, price_reg)

    price_prolong = response.xpath(self.pathprolong).get()
    price_prolong = self.find_price(self.regex_prolong, price_prolong)

    yield scrapy.Request('https://2domains.ru/domains/transfer', callback=self.parse_price_change)

    site_name = self.site_names[0]

    item = NsregItem()
    item['name'] = site_name
    price = item.get('price', EMPTY_PRICE)
    price['price_reg'] = price_reg
    price['price_change'] = price_change
    item['price'] = price