1. Вступайте в наш Telegram чат: https://t.me/a_parser Нас уже 2600+ и мы растем!
    Скрыть объявление

Универсальный парсер телефонов

Статья о том, как универсально парсить номера телефонов из разных страниц

  1. Support
    Поиск контактов - это довольно частая задача для А-Парсера. На форуме уже есть несколько вариантов решения этой задачи: вот и вот. Но все они рассчитаны только на сбор e-mail. Дело в том, что почты собирать намного проще, т.к. все они имеют один формат записи и поэтому не составляет особого труда написать регулярное выражение для их извлечения. Можно также воспользоваться готовым парсером HTML::EmailExtractor HTML::EmailExtractor.

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

    Речь пойдет о библиотеке Google libphonenumber, а точнее о ее порте libphonenumber-js. Как известно, А-Парсер поддерживает работу с NPM модулями, поэтому мы легко можем использовать такое решение.

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

    Для парсинга email со страниц воспользуемся встроенным HTML::EmailExtractor HTML::EmailExtractor. Создаем простое задание:
    [​IMG]
    Здесь все настройки по-умолчанию, единственное что изменено - это Формат результата:
    • Т.к. на странице почты могут дублироваться (и встречается это довольно часто), то нам нужно удалять дубли. Но делать это нужно только в рамках текущего запроса, поэтому обычная уникализация тут не подходит. Решаем это таким шаблоном:
      Код:
      mails = {};
      FOREACH item IN p1.mails;
          mails.${item.mail} = 1;
      END;
      mails = mails.keys;
      Результатом этого кода будет массив mails, содержащий только уникальные значения.
    • Добавляем вывод ссылки на страницу и найденных почт в CSV. А также делаем проверку на наличие почты (ведь зачем нам в результате просто ссылки без почт?:)).
      Код:
      IF mails.size > 0;
          tools.CSVline(query, mails.join(', '));
      END
    Теперь нужно добавить сюда сбор телефонов. Как известно, NPM модули можно использовать в JS парсерах и внутри tools.js. И т.к. мы делаем обычный пресет, то нам отлично подходит второй вариант.

    В первую очередь устанавливаем модуль libphonenumber-js (как устанавливать npm модули).
    Далее переходим в Инструменты - Редактор JavaScript и добавляем новую функцию (не забываем нажать кнопку Сохранить после добавления):
    Код:
    Tools.prototype.getPhones = function(data, country) {
        const libphonenumber = require('libphonenumber-js');
        return libphonenumber.findPhoneNumbersInText(data, country).map(el => el.number);
    }
    [​IMG]
    В этом коде мы импортируем модуль и вызываем его метод findPhoneNumbersInText. А также немного изменяем формируемый результат для удобства работы с ним.

    Теперь мы можем обращаться к этой функции из любого места А-Парсера через вызов tools.js.getPhones(). Добавим ее в наш пресет, а точнее в шаблон Формата результата:
    Код:
    [% mails = {};
    FOREACH item IN p1.mails;
        mails.${item.mail} = 1;
    END;
    mails = mails.keys;
    
    phones = {};
    FOREACH item IN tools.js.getPhones(p1.data);
        phones.${item.number} = 1;
    END;
    phones = phones.keys;
    
    IF phones.size > 0 || mails.size > 0;
        tools.CSVline(
            query,
            mails.join(', '),
            phones.join(', ')
        );
    END %]
    • Для телефонов делаем такую же уникализацию, как и для почт.
    • Включаем в условие вывода проверку наличия телефонов и добавляем их в вывод.
    Часто в тайтлах страниц содержится имя компании, поэтому, для удобства, можно их также парсить и выводить в результат. Тогда можно будет идентифицировать кому принадлежит контакт.

    В итоге получается такой пресет:
    [​IMG]
    Код:
    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
    bw==

    Вставляем уже имеющийся список ссылок в поле запросов (или выбираем файл с ними), запускаем и получаем такую таблицу:
    [​IMG]
    На этом задача по универсальному парсингу телефонов полностью решена.
    ctpactb и Rassul нравится это.