Как получить доступ к ng-модели элемента при отборе данных с сайта, который использует angular? - PullRequest
1 голос
/ 17 января 2020

У нас есть оптовый продавец, у которого мы покупаем много продуктов, которые мы настраиваем и перепродаем для наших клиентов. Некоторые из их продуктов мы продаем на складе, другие мы заказываем по заказу клиента. Мы рекламируем эти продукты на нашем веб-сайте и делаем их доступными для приобретения (с настройкой и т. Д. c.) Через наш сайт, но у поставщика часто имеется ограниченный запас (особенно этих "специально заказанных" продуктов, которые не ' t так часто продается), поэтому мы не рекламируем продукты и не делаем их доступными для покупки, если предложение поставщика слишком мало.

Сейчас таких продуктов много, и каждый день мы должны знать, какое количество вендора доступно для каждого из них, чтобы мы не продавали то, чего не можем получить. В течение многих лет мы просили поставщика предоставить нам веб-службу или ftp-сайт с ежедневным дампом или каким-либо другим способом получить эти доступные данные инвентаризации, кроме как соскребая их веб-сайт, поверьте мне, мы очень умоляли их много, и они просто не будут этого делать. (Они скажут, что мы слишком заняты, возможно, к следующему году у нас будет что-то, но через 10 лет у них все еще ничего не будет.) Поэтому мы должны очистить их сайт. И они знают, что мы делаем это, и это не то, чем каждый из нас очень доволен, но это нужно сделать, если мы собираемся продавать эти продукты.

Ну, их сайт теперь использует Angular, и это настоящая боль в заднице, чтобы попытаться очистить. Более года у нас был хорошо работающий скребок на основе Selenium, но после некоторых изменений, которые они сделали несколько месяцев назад, он просто упал, пытаясь запустить JavaScript на их сайте. (Я получаю различные непонятные ошибки и исключения, и вещи, которые обычно работают нормально, просто не работают, потому что, кажется, javascript запускается на событиях, связанных с любым элементом html, с которым я пытаюсь взаимодействовать, и кажется, как у Selenium проблемы с обработкой этого JavaScript.) Я пробовал много разновидностей селена, все доступные веб-драйверы, много разных попыток конфигурации, всевозможные настройки параметров и тому подобное, я просто не могу добиться успеха Я больше не использую этот сайт, поэтому я прибег к использованию браузера с отключенной веб-безопасностью и запуску программы JavaScript, которая открывает их сайт в отдельном окне. (Я не могу просто открыть его во фрейме, потому что они часто используют window.top. Потому что они сами используют фреймы. Весело.)

Итак, после того, как мой скребок войдет в систему и немного перейдет, что он без проблем делает, он должен поместить значение поиска в поле поиска и нажать кнопку поиска. Что ж, значение отображается в окне поиска просто отлично, но когда моя программа нажимает на кнопку поиска, их JavaScript заметно очищает поле поиска и в результате выдает сообщение об ошибке о более чем 2000 продуктах, возвращаемых моим поиском, как будто я ввел пустое значение.

При просмотре их страницы я вижу это:

<textarea id="searchBox" ng-model="searchParams.searchString" rows="3"
          ng-blur="formatSearch()" class="ng-pristine ng-valid ng-touched"
          style="">
</textarea>

Так что, похоже, что даже я помещаю значение поиска в текстовое поле отправляя события нажатия клавиш на вход (и я также пытался просто установить значение входа), тем не менее, ng-модель searchParams.searchString не обновляется, поэтому, когда запускается formatSearch (), он принимает то, что в этом model (строка emtpy), форматирует ее и помещает в поле. Или, по крайней мере, так выглядит происходящее.

Как мне задать для searchParams.searchString значение поиска, которое я пытаюсь вставить в окно поиска? Я могу получить область действия angular элемента, но, похоже, мне нужна область контроллера или что-то в этом роде. Я не вижу ни одного элемента, который бы определял ng-контроллер ... о, подождите, вот содержащийся div в некотором отдаленном происхождении окна поиска:

<div ng-controller="AppCtrl" ng-class="routeClassName"
     class="fluid-container ng-scope ViewProducts" style="">

.. возможно, я в конечном итоге отвечу на мой собственный вопрос.

(я могу sh Я мог бы опубликовать ссылку на сайт продавца и нашу регистрационную информацию, чтобы вы, ребята, могли опробовать идеи и тому подобное, но, очевидно, я не могу этого сделать.)

1 Ответ

0 голосов
/ 17 января 2020

Я попытался добавить angular к открываемой странице, которая загружает мой скребок, который затем загружает сайт поставщика и затем использует его, чтобы попытаться получить доступ к необходимой области действия angular, но это не сработало , Я пытался получить доступ к angular, запущенному на их странице, через объект окна, но его там не было.

Вот что я должен был сделать:

    var f = self.sitewin.top.document.querySelector('#contentFrame');
    f.contentWindow.angular.element(tag).scope().searchParams.searchString = self.puid;

Это сработало.

«Я» - это мой скребковый объект. «sitewin» - это окно сайта. «тег» - это элемент, который я нашел следующим образом:

find: function (selector) {
    var self = GTPScraper;
    var tag = self.sitewin.document.querySelector(selector);
    if (tag) return tag;
    try {
        tag = self.sitewin.top.document.querySelector('#contentFrame').contentDocument.querySelector(selector);
    }
    catch (e) {
        // swallow errors about things that are null because something hasn't loaded yet - this function gets retried for up to a timeout length
    }
    return tag;
},

«self.puid» - это «идентификатор продукта», который я ввожу в поле поиска.

Я думаю, Отсюда следует, что angular может в конечном итоге быть загружен во фрейм окна очищенного сайта, и если это произойдет, вы можете получить к нему доступ через contentWindow этого фрейма, а затем вы можете получить доступ к областям элементов оттуда и получить доступ к их модели оттуда.

Это работает - после установки searchParams.searchString = self.puid, он нажимает кнопку поиска, и теперь появляется страница продукта. Halellujah.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...