2016-11-25 4 views
0

Я соскабливаю ~ 10 сайтов для получения той же информации и в настоящее время имею скрипт для каждого из них, который работает сам по себе. Эти сценарии имеют одну и ту же базу (перебирают доступные страницы, очищают информацию, сохраняют ее), но разные атрибуты.Рефакторинг кода Ruby scrape (с различными атрибутами)

В качестве примера, это примеры того, как я извлечения author элемент из двух страниц:

page.at('b[itemprop="author"]').children.text.strip 
page.at('.author-username').text.strip 

Моя цель состоит в том, чтобы реорганизовать это так главная логика обрабатывается в классе, но я У меня возникли проблемы с выяснением того, как пройти в вышеуказанных экстракторах в зависимости от источника. Я знаю, что могу pass CSS selectors as arguments, но, как вы можете видеть, для каждой извлечения есть дополнительная логика.

Хотя я мог бы иметь отдельный метод для обработки этого (как указано в предыдущей ссылке), это быстро выйдет из-под контроля с ~ 10 источниками.

Каков наилучший способ реорганизации этого кода?

ответ

0

Я бы, вероятно, пошел с хешем.

Предполагая, что не так много деталей, поместите все это в своего рода хаос Rosetta Stone, который поставляет соответствующую информацию для каждой страницы. Это можно использовать в сочетании с оператором case...when, чтобы загрузить соответствующие данные.

Что-то вроде:

site_attributes = { 
    site_1: ['attribute_1', 'attribute_2', ... ], 
    site_2: ['attribute_3', 'attribute_4', ... ], 
    ... 
} 

Это может понадобиться, чтобы быть немного более сложным, если вам нужно вызвать различные методы по результатам различных атрибутов. Тогда ваш массив атрибутов для каждого сайта должен быть хешей вместо строк. Что-то вроде:

[ 
    { 
    attr: 'attribute_1', 
    methods: [:children, :text, :strip] 
    }, { 
    attr: 'attribute_2', 
    methods: [:text, :strip] 
    }, 
    ... 
] 

Тогда вы можете each через атрибуты, использовать их с page.at() и итеративно вызвать дополнительные методы результата.

+0

Спасибо за ваш ответ Скотт, это полезно. Не могли бы вы рассказать, как я буду делать вызовы методов, которые предоставляются через эти строки ('['children', 'text', 'strip']')? В качестве примера, как я могу запустить 'attribute_1.children.text.strip'? – Manonthemoon

+0

А я понял, я использую 'page.send ()' для вызова каждого метода. – Manonthemoon

+0

Справа. И действительно, эти списки методов должны были быть символами, а не строками. Либо должны работать одинаково, но символы более эффективны с точки зрения памяти. –

Смежные вопросы