1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/UnlimitedBladeWorks_123-WinCrawler

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

WinCrawler

WinCrawler — это универсальная среда для разработки краулеров, вдохновлённая такими инструментами, как пауки и железнодорожные локомотивы. Она использует подход, который позволяет комбинировать сбор данных с веб-страниц и интерфейсов.

Особенности

  1. Комбинированный сбор данных с веб-страниц и интерфейсов;
  2. Поддержка распознавания изображений с проверочными кодами;
  3. Поддержка логических конструкций if, for, while;
  4. Возможность экспорта данных;
  5. Настраиваемые правила шагов;
  6. Техническая основа: Spring Boot, FreeMarker, Rest Assured, Selenium, TestNG.

Использование

  1. Выполнить команду создания таблицы src/main/resources/WinCrawler.sql (wincrawler-core);
  2. Изменить файл конфигурации проекта src/main/resources/application.yml (wincrawler-core);
  3. Выполнить файл TestNG src/test/resources/projectname/crawler.xml (example).

Конфигурация шагов

Логические шаги

Общие свойства

  • needStore — нужно ли сохранять данные, один процесс может иметь только одно значение;
  • storeKey — ключ для сохранения данных, определяет уникальность данных;
  • condition — условие выполнения операции, если значение равно true, то условие выполнено успешно;
  • stepList — список шагов;
  • delayTime — время задержки после выполнения шага;
  • needUpdate — требуется ли обновить результаты;
  • updateCondition — условие обновления результатов, при выполнении условия данные обновляются.

if (добавление данных в постоянное хранилище)

{
    "name": "if-условие",
    "type": "ifGroup",
    "condition": "${(ret.body.success == true)?c}",
    "needStore": true,
    "storeKey": "age_${o.age}-sex_${o.sex}-payEndYear_${o.payEndYear}",
    "stepList": [{
        "name": "Открыть страницу входа",
        "type": "openWebPage",
        "url": "http://www.baidu.com/"
    }],
    "delayTime": 100
}

for (добавление данных в постоянное хранилище)

{
      "name":"Условный цикл",
      "type":"forGroup",
      "listStr":"${descartes('age',range(30,70),'sex','[\"Sex1\",\"Sex2\"]','payEndYear','[2,3,4]')}",
      "list": [],
      "iterAlias":"o",
      "needStore": true,
      "storeKey": "age_${o.age}-sex_${o.sex}-payEndYear_${o.payEndYear}",
      "stepList":[{},{}]
 }

while (добавление данных в постоянное хранилище)

{
     "name":"Цикл while",
     "type":"whileGroup",
     "breakCondition":"${(ret.body.success==true)?c}",
     "maxCount":3,
     "needStore": true,
     "storeKey": "age_${o.age}-sex_${o.sex}-payEndYear_${o.payEndYear}",
     "stepList":[]
}

ifSignal (аналогично коду if с логикой, step_continue,step_break,step_throwe)

{
    "name":"if-условие",
    "type":"ifGroup",
    "condition":"${(ret.body.success==true)?c}",
    "signal": "step_continue",
    "signalMsg": "Запись информации в базу данных"
}
setV
 {
     "name":"Установка константы",
     "type":"setV",
     "values":{
         "origin_ids":"${pid},<#list productList as p>${p.productId}<#if p?has_next>,</#if></#list>"
     },
     "alias":"init"
 }

Шаги на основе страниц

Общие свойства

  • frameXPathList — XPath для элементов внутри фреймов, поддерживает многоуровневые фреймы;
  • waitElementXPath — XPath элемента, ожидающего появления, используется для выполнения операций; время ожидания определяется системным значением selenium_implicitly_wait;
  • waitTime — время ожидания, имеет более низкий приоритет по сравнению с waitElementXPath;
  • matchXPath — соответствующий XPath.

Нажатие

{
    "name":"Выбор пола страхователя",
    "type":"click",
    "frameXPathList":[
        "//[@id='page-content']",
        "//[@id='WorkFrame']"
    ],
    "matchXPath":"//[@id='appSex1']",
    "hasAlert": false
}

Ввод текста

{
    "name":"Ввести имя пользователя",
    "type":"inputText",
    "waitElementXPath":"//[@id='frmInput']",
    "matchXPath":"//[@id='username']",
    "value":"33011082001025"
}

Открытие веб-страницы

{
    "name":"Открыть страницу входа",
    "type":"openWebPage",
    "url":"http://ehome.e-chinalife.com/",
    "timeOut": 5000 ,"//":"(не настроено, используется значение по умолчанию)"
}

Проверка кода

{
    "name":"Введите код подтверждения",
    "type":"validateCode",
    "waitElementXPath":"//[@id='frmInput']",
    "codeImageXPath":"//[@id='validateNum']",
    "inputTextXPath":"//[@id='inputValidateNum']",
    "ajaxFlag":true,
    "presentXPathOnSuccess":"//img[@id='rightId' and contains(@src,'tick_circle.png')]",
    "presentXPathOnFailure":"//img[@id='rightId' and contains(@src,'cross_circle.png')]",
    "submitXPath":"//[@id='frmInput']/div/table/tbody/tr[4]/td/input[1]",
    "retryTimesOnFailure":3
}

Выпадающий список с одним выбором (select)

{
    "name":"Выберите способ оплаты",
    "type":"select",
    "matchXPath":"//select[@name='common[pay_period]' and @data-key='pay_period']",
    "selectConfig":{
        "type":"byIndex",
        "value":"${o.payPeriod}"
    }
}

Выпадающий список с множественным выбором (select)

{
    "name":"Выберите способ оплаты",
    "type":"multiSelect",
    "matchXPath":"//select[@name='common[pay_config]' and @data-key='pay_config']",
    "selectConfigList":[{
        "type":"byValue",
        "value":"${o.payConfig}"
    }]
}

Расширенный выбор (расширение логики)

{
    "name":"Выбрать новый план книги",
    "type":"selectEx",
    "waitElementXPath":"//[@id='menu-content']",
    "matchXPath":"//[@id='menu-flag']",
``` **selectXPath**: `"//[@id='menu-content']/div/ul/li[@menuid=508]"`.

**提取数据**:
```json
{
    "name": "提取数据",
    "type": "extractData",
    "frameXPathList": [
        "//[@id='page-content']",
        "//[@id='WorkFrame']"
    ],
    "matchXPath": "//[@id='riskcheck']/tbody/tr[position()>3]",
    "ruleList": [
        {
            "name": "c2",
            "rule": ".//td[2]"
        },
        {
            "name": "c3",
            "rule": ".//td[3]"
        },
        {
            "name": "c4",
            "rule": ".//td[4]"
        },
        {
            "name": "c5",
            "rule": ".//td[5]"
        },
        {
            "name": "c6",
            "rule": ".//td[6]"
        },
        {
            "name": "c7",
            "rule": ".//td[7]"
        },
        {
            "name": "c8",
            "rule": ".//td[8]"
        }
    ]
}

获取 cookie:

{
    "name": "获取cookies",
    "type": "fetchCookie",
    "matchXPath": "//[@id='menu-flag']",
    "alias": "cookie"
}

设置 cookie:

{
    "name": "设置cookies",
    "type": "setCookie",
    "cookies": "cookieValue"
}

AJAX 步骤

  • Общие свойства:
    • requestUrl — адрес запроса;
    • requestMethod — метод запроса, см. com.winbaoxian.crawler.enums.RequestMethod;
    • RequestContentType — тип содержимого запроса, см. com.winbaoxian.crawler.enums.RequestContentType;
    • requestHeader — заголовок запроса (hashMap);
    • requestParams — параметры запроса (hashMap);
    • requestBody — тело запроса в формате JSON;
    • tpl — после обработки результата запроса данным шаблоном данные сохраняются под указанным псевдонимом в контексте;
    • storeFilePath — путь сохранения файла с результатом запроса;
    • alias — псевдоним результата, который сохраняется в контексте и передаётся последующим шагам; если значение пустое, то результат не сохраняется;
    • delayTime — время задержки выполнения шага.

HTTP-запрос:

{
    "name": "登录",
    "type": "http",
    "requestUrl": "https://insurance-tech-api.winbaoxian.cn/api/group/login",
    "requestParams": {
        "mobile": "${a}",
        "validateCode": "${b}"
    },
    "requestMethod": "POST",
    "requestContentType": "application/x-www-form-urlencoded",
    "alias": "ret"
}

Распознавание изображения с помощью оптического распознавания символов (OCR):

{
    "name": "识别验证吗",
    "type": "ocr",
    "requestUrl": "http://ehome.e-chinalife.com/passport/validateNum.jsp",
    "requestHeader": {
       "cookie": "${toJSONString(homePage.cookies)}"
    },
    "alias": "ret"
}

Извлечение данных из HTTP-запроса:

{
    "tpl": "${toJSONString(data)}",
    "requestUrl": "https://www.baiduc.com/video/getAudioUrlList?uuid=113f5651c1704ebda34fd5b88f86114903c",
    "name": "提取数据",
    "alias": "c",
    "type": "extractDataHttp"
}

Экспорт конфигурации

Простой формат экспорта

{
    "type": "simple",
    "fileName": "template3.csv//可不设置,使用task的name",
    "titles": [
        "年龄",
        "性别",
        "交费期间",
        "保单年度",
        "年末年龄",
        "年初保费",
        "累计保费",
        "年度最高身故保障",
        "生存给付",
        "满期给付",
        "退保金"
    ],
    "valueTplList": [
        "${params.o.age}",
        "<#if params.o.sex=='Sex1'>男<#else>女</#if>",
        "<#if params.o.payEndYear==2>3<#elseif params.o.payEndYear==3>5<#elseif params.o.payEndYear==4>10<#else>0</#if>",
        "${result.c2}",
        "${result.c3}",
        "${result.c4}",
        "${result.c5}",
        "${result.c6}",
        "${result.c7}",
        "${result.c8}"
    ]
}

Формат экспорта с использованием шаблона (tpl)

{
    "type": "tpl",
    "fileName": "p2.csv//可不设置,使用task的name",
    "tpl": "年龄,性别,交费期间,保单年度,年末年龄,年初保费,累计保费,年度最高身故保障,生存给付,满期给付,退保金 <#list list as entity > <#if entity.result?default('')?trim?length gt 0> <#assign p = toJSON(entity.params)> <#assign result = toJSON(entity.result)> <#list result as ret> ${p.o.age},<#if p.o.sex=='Sex1'>男<#else>女</#if>,<#if p.o.payEndYear==2>3<#elseif p.o.payEndYear==3>5<#elseif p.o.payEndYear==4>10<#else>0</#if>,${ret.c2},${ret.c3},${ret.c4},${ret.c5},${ret.c6},${ret.c7},${ret.c8} </#list> <#else> ${entity.keyName},error </#if> </#list>"
}

Контакты

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Описание недоступно Развернуть Свернуть
MPL-2.0
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/UnlimitedBladeWorks_123-WinCrawler.git
git@api.gitlife.ru:oschina-mirror/UnlimitedBladeWorks_123-WinCrawler.git
oschina-mirror
UnlimitedBladeWorks_123-WinCrawler
UnlimitedBladeWorks_123-WinCrawler
master