Управление Selenium Web Driver из 1С (или парсинг из 1С по-взрослому)

29.12.21

Интеграция - WEB-интеграция

Нет-нет, да и появляются заказы на парсинг сайтов. Обычно, для этих целей использую net. + Selenium nuget package. Однако, если клиент использует стек технологий 1С, то предпочтительней было бы не пороть отсебятину, а применять уже знакомую пользователям парадигму работы с ИТ-продуктами - без каких-либо лишних прослоек, вроде net. или JS. И вот я задался вопросом: "а можно ли?".

Скачать исходный код

Наименование Файл Версия Размер
Управление Selenium Web Driver из 1с (или парсинг из 1с по-взрослому):
.zip 854,26Kb
19
.zip 854,26Kb 19 Скачать

Что такое Selenium - можно почитать здесь: https://habr.com/ru/post/152653/.

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

Основным назначением продукта является организация автоматического тестирования, но можно придумать и что-то еще.

Selenium в настоящий момент поддерживает управление следующими браузерами:

 

Браузер Операционная система Разработчик
Chromium/Google Chrome Windows/macOS/Linux Google
Firefox Windows/macOS/Linux Mozilla
Edge Windows 10 Microsoft
Internet Explorer Windows Selenium Project
Safari macOS El Capitan и более новые Apple
Opera Windows/macOS/Linux Opera

 

В своих экспериментах я решил использовать связку Selenium + Chrome + Windows10.

При этом, основной проблемой являлось то, что с Selenium'ом работает только ограниченный круг third-part - библиотек (которые предоставляют сервис высокого уровня абстракции (читай - удобства)).

В частности, официально, поддерживаются такие языки:

- C#

- Ruby

- Java

- Pyton (конечно-же))

- JS

https://www.selenium.dev/downloads/

Гениальнейшая (без сарказма и иронии) платформа 1с, почему-то в перечень этих библиотек не входит(.

Покопавшись немного в документации, я нашел информацию, что на самом деле-то Selenium, при запуске, поднимает локальный web-server, который обладает развесистым низкоуровневым API. Сложность работы с ним состоит в том, что он именно "низкоуровневый", то-есть для получения результата требует много кода.

Вот его описание:  https://www.w3.org/TR/webdriver/

Приготовившись читать много доки на не нашем языке, я приступил к делу.

 

1. Установка Selenium

Поскольку программный комплекс состоит как-бы из 3х звеньев (нативный web-driver + сервер Selenium + браузер), то имея уже установленный на компьютере Хром, мне осталось поставить Web-driver и сервер Selenium.

 

1.1. Установка Web-driver'а

Web-driver качается вот отсюда: https://chromedriver.chromium.org/

Однако, как оказалось, драйвер очень чувствителен к версии браузера, установленного на компьютере и чтобы подобрать и скачать нужную версию, требуется пройти квест. Почему они не сделали js-скрипт на странице, который сам определяет версию браузера и выдают нужный драйвер - я не понял. Короче вот: https://chromedriver.chromium.org/downloads/version-selection.

Если кратко, то чтобы скачанное запустилось, следует:

1. зайти в настройки браузера (3 точки - сверху, справа -- Настройки -- О браузере)

 

 

2. Из версии браузера убрать последнюю часть и получившееся добавить к строке адреса https://chromedriver.storage.googleapis.com/LATEST_RELEASE_.

Должно получиться так: https://chromedriver.storage.googleapis.com/LATEST_RELEASE_96.0.4664

3. Перейдя по получившемуся адресу, вы попадете на страницу с версией драйвера, которая подойдет под вашу версию браузера.

4. Решительно копируйте ее в буфер обмена и добавляйте к строке https://chromedriver.storage.googleapis.com/index.html?path=

Должно получиться так: https://chromedriver.storage.googleapis.com/index.html?path=96.0.4664.45/ (в конце еще следует добавить прямой слеш). 

5. После перехода по полученному адресу, вы попадете на нужную страницу закачек, на которой следует выбрать драйвер под Вашу ОС.

Качаем и кладем в папочку (без кириллицы и без пробелов в пути к папочке - в общем все как обычно).

 

1.2. Установка сервера Selenium

Здесь все просто: https://www.selenium.dev/downloads/

Качаем отсюда и кидаем в ту-же папку, что и web-driver.

 

2. Запуск

В принципе, в простейшем случае (без организации грида (сетки из множества конечных узлов Selenium)) современная версия комплекса сама себя настраивает. Чтобы все заиграло одной машине, достаточно в каталоге со скачанными образами сервера и веб-драйвера создать bat-файл с таким вот содержимым: 

//////////////////////

java -jar selenium-server-4.1.0.jar standalone
pause

//////////////////////

Произойдет запуск сервера в режиме одиночки.

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

По-умолчанию сервер стартует на порту 4444.

Теперь можно порулить.

 

3. Руление

3.1. Итак, сначала проверим: как он там.

Кидаем  вот такой GET: http://localhost:4444/status (https://www.w3.org/TR/webdriver/#status) на localhost.

Если все ок, то должна быть возвращена структура, описывающая состояние сервера:

{
	"value": {
		"ready": true,
		"message": "Selenium Grid ready.",
		"nodes": [
			{
				"id": "10811e6b-17dc-4163-bead-a38221dbc603",
				"uri": "http://ххх.ххх.ххх.ххх:4444",
				"maxSessions": 6,
				"osInfo": {
					"arch": "amd64",
					"name": "Windows 10",
					"version": "10.0"
				},
				"heartbeatPeriod": 60000,
				"availability": "UP",
				"version": "4.1.0 (revision 87802e897b)",
				"slots": [
					{
						"lastStarted": "1970-01-01T00:00:00Z",
						"session": null,
						"id": {
							"hostId": "10811e6b-17dc-4163-bead-a38221dbc603",
							"id": "b088a136-98d4-4b06-91c4-6b5a44c71a1d"
						},
						"stereotype": {
							"browserName": "chrome",
							"platformName": "WIN10"
						}
					},
					{
						"lastStarted": "1970-01-01T00:00:00Z",
						"session": null,
						"id": {
							"hostId": "10811e6b-17dc-4163-bead-a38221dbc603",
							"id": "f7f30980-09c3-481d-a202-9d8ae6600aa4"
						},
						"stereotype": {
							"browserName": "chrome",
							"platformName": "WIN10"
						}
					},
					{
						"lastStarted": "1970-01-01T00:00:00Z",
						"session": null,
						"id": {
							"hostId": "10811e6b-17dc-4163-bead-a38221dbc603",
							"id": "a820aa7d-5e18-4162-8c93-990c362e2d18"
						},
						"stereotype": {
							"browserName": "chrome",
							"platformName": "WIN10"
						}
					},
					{
						"lastStarted": "1970-01-01T00:00:00Z",
						"session": null,
						"id": {
							"hostId": "10811e6b-17dc-4163-bead-a38221dbc603",
							"id": "28bf1c2b-f351-44a2-9bdb-ea2e029e3fb1"
						},
						"stereotype": {
							"browserName": "chrome",
							"platformName": "WIN10"
						}
					},
					{
						"lastStarted": "1970-01-01T00:00:00Z",
						"session": null,
						"id": {
							"hostId": "10811e6b-17dc-4163-bead-a38221dbc603",
							"id": "a50d9495-831a-4148-89b1-8723608a3053"
						},
						"stereotype": {
							"browserName": "chrome",
							"platformName": "WIN10"
						}
					},
					{
						"lastStarted": "1970-01-01T00:00:00Z",
						"session": null,
						"id": {
							"hostId": "10811e6b-17dc-4163-bead-a38221dbc603",
							"id": "659d6bc3-7463-4c16-88f7-27395179fe62"
						},
						"stereotype": {
							"browserName": "chrome",
							"platformName": "WIN10"
						}
					}
				]
			}
		]
	}
}

Ключевой момент здесь: "ready": true.

 

3.2. Теперь запускаем экземпляр сеанса (по-факту открывается Хром)

Для этого кидаем такой POST: http://localhost:4444/session (https://www.w3.org/TR/webdriver/#new-session)

с таким телом запроса:

{
	"capabilities": {
		"firstMatch": [
			{
				"browserName": "chrome",
				"pageLoadStrategy": "eager"
			}
		],
		"timeouts": {
			"Script Timeout": "1800,000",
			"Page Load Timeout": "1800,000",
			"Implicit Wait Timeout": "1800,000"
		}
	}
}
"pageLoadStrategy = игорь"

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

После этого волшебным образом должно открыться окно браузера, а ответ должен быть такой:

{
	"value": {
		"sessionId": "bdfafa0bcbac62421cc184328f3b44bb",
		"capabilities": {
			"acceptInsecureCerts": false,
			"browserName": "chrome",
			"browserVersion": "96.0.4664.110",
			"chrome": {
				"chromedriverVersion": "96.0.4664.45 (76e4c1bb2ab4671b8beba3444e61c0f17584b2fc-refs/branch-heads/4664@{#947})",
				"userDataDir": "C:\\Users\\ХХХХХХХ\\AppData\\Local\\Temp\\scoped_dir48368_636555220"
			},
			"goog:chromeOptions": {
				"debuggerAddress": "localhost:65126"
			},
			"networkConnectionEnabled": false,
			"pageLoadStrategy": "eager",
			"platformName": "windows",
			"proxy": {
			},
			"se:cdp": "ws://ххх.ххх.ххх.ххх:4444/session/187533817ed102e7eb1b766d3a467194/se/cdp",
			"se:cdpVersion": "96.0.4664.110",
			"setWindowRect": true,
			"strictFileInteractability": false,
			"timeouts": {
				"implicit": 0,
				"pageLoad": 300000,
				"script": 30000
			},
			"unhandledPromptBehavior": "dismiss and notify",
			"webauthn:extension:credBlob": true,
			"webauthn:extension:largeBlob": true,
			"webauthn:virtualAuthenticators": true
		}
	}
}

Больше всего из этого нам важно поле "sessionId". На основе sessionId строятся все последующие запросы управления.

 

3.3. Заставим Хром открыть страницу Яндекса

POST: http://localhost:4444/session/bdfafa0bcbac62421cc184328f3b44bb/url (https://www.w3.org/TR/webdriver/#navigate-to)

Тело:

{"url": "https://yandex.ru/"}

Браузер должен открыть страницу ИТ-гиганта, а запрос вернуть такой JSON:

{
	"value": null
}

 

3.4. Найдем на странице заголовки новостей

Согласно документации, существует множество разнообразных стратегий поиска элементов на странице. 

В самом простом случае можно искать по ID, по Классу или все вместе - используя выражения xPath.

https://www.w3.org/TR/webdriver/#find-elements

Кидаем POST: http://localhost:4444/session/bdfafa0bcbac62421cc184328f3b44bb/elements

Тело:

{
	"using": "xpath",
	"value": "//span[contains(@class,'news__item-content')]"
}

Разбор синтаксиса xpath выходит за рамки этого исследования, так-что просто напишу, что данное выражение ищет по всему дереву элементов html-страницы элементы "span" с классом 'news__item-content' (это заголовки новостей).

Запрос возвращает такой ответ:

{
	"value": [
		{
			"element-6066-11e4-a52e-4f735466cecf": "714dd669-9d30-41ba-a02d-3c0d4fde3ccf"
		},
		{
			"element-6066-11e4-a52e-4f735466cecf": "cffcd89f-7403-4368-a4fc-8da4374002a8"
		},
		{
			"element-6066-11e4-a52e-4f735466cecf": "d150c945-cd8f-4342-a605-1e79cdfe8f1e"
		},
		{
			"element-6066-11e4-a52e-4f735466cecf": "c452dcf6-500b-4b9c-8aee-c6034e636ca5"
		},
		{
			"element-6066-11e4-a52e-4f735466cecf": "27f63f2c-b393-4646-804d-a47a38d0f320"
		},
		{
			"element-6066-11e4-a52e-4f735466cecf": "1383eb44-9398-476b-a2c4-88621e8584e3"
		},
		{
			"element-6066-11e4-a52e-4f735466cecf": "7729a7e1-27ae-43fb-9ff9-1b4dae4cbe4d"
		},
		{
			"element-6066-11e4-a52e-4f735466cecf": "6c5cea92-4b7f-4697-a71a-4733938f030b"
		},
		{
			"element-6066-11e4-a52e-4f735466cecf": "da63d035-d2f4-43f3-80c6-d14c1cdb7781"
		},
		{
			"element-6066-11e4-a52e-4f735466cecf": "e31e1bd3-50cf-4cee-b415-6b8a782c0e91"
		}
	]
}

Это перечень идентификаторов найденных элементов.

 

3.5. Теперь надо-бы получить текст из этих элементов

Для этой цели у Selenium'а запасен запрос https://www.w3.org/TR/webdriver/#get-element-text

Он тупо выдергивает подчиненный текст элемента (если он есть).

Get: http://localhost:4444/session/bdfafa0bcbac62421cc184328f3b44bb/element/714dd669-9d30-41ba-a02d-3c0d4fde3ccf/text

Ответ:

{
	"value": "Генеральная прокуратура обвинила «Мемориал» в реабилитации нацистских преступников"
}

Элементы можно обойти в цикле и сложить в массив все строки, что попались - с проверкой на пустые строки.

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

 

3.6. В завершении, по-хорошему следует грохнуть сессию

https://www.w3.org/TR/webdriver/#delete-session

 

Если внимательно почитать документацию, то там есть еще много замечательных возможностей: https://www.w3.org/TR/webdriver/#statehttps://www.w3.org/TR/webdriver/#element-interaction (взаимодействие с элементами) и т.д.

В заключении приложу к статье базу данных с реализацией всего вышеописанного в коде 1с.

Тестировалось все на платформе 1с версии 8.3.18.1334 x64.

См. также

Интеграция Альфа Авто 5 / Альфа Авто 6 и AUTOCRM / Инфотек

Сайты и интернет-магазины WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме.

36000 руб.

03.08.2020    16083    13    18    

13

Интеграция 1С — Битрикс24. Обмен задачами

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс24. Разработка имеет двухстороннюю синхронизацию 1С и Битрикс24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (платформа начиная с 8.3.23). При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

5040 руб.

04.05.2021    18166    10    15    

16

Автоматическая загрузка файлов (например, прайс-листов) из электронной почты, FTP, HTTP, их обработка и выгрузка на FTP (на сайт) и для других целей

Прайсы WEB-интеграция Ценообразование, анализ цен Файловый обмен (TXT, XML, DBF), FTP Автомобили, автосервисы Оптовая торговля, дистрибуция, логистика Управленческий учет Платные (руб)

Программа с заданным интервалом времени (или по ручной команде) скачивает файлы (например, прайс-листы поставщиков) из различных источников: письма электронной почты, FTP или HTTP-адреса, и сохраняет их в каталог упорядоченной структуры. При этом извлекает файлы из архивов, может переименовывать файлы и менять их формат (csv, xls, txt). Можно настроить выгрузку обработанных файлов на сайт (через FTP-подключение). Программа будет полезна компаниям, у которых есть большое количество поставщиков и/или прайс-листы поставщиков обновляются часто (необязательно прайс-листы, файлы могут быть любого назначения). Собранные таким образом актуальные версии прайс-листов можно выгрузить с помощью программы себе на сайт (или на любой FTP-сервер) или выполнить другие необходимые задачи.

25200 руб.

28.05.2015    85386    26    51    

50

Модуль для обмена "1С:Предприятие 8. УАТ. ПРОФ" с FortMonitor

WEB-интеграция 8.3.8 Конфигурации 1cv8 Автомобили, автосервисы Беларусь Украина Россия Казахстан Управленческий учет Платные (руб)

Расширение предназначено для конфигурации "1С:Предприятие 8. Управление Автотранспортом. ПРОФ". Функционал модуля: 1. Заполнение регистров сведений по подсистеме "Мониторинг", а именно: события по мониторингу, координаты по мониторингу, пробег и расход по мониторингу, текущее местоположение ТС по мониторингу 2. Заполнение путевого листа: пробег по мониторингу, время выезда/заезда, табличная часть ГСМ, места стоянок по геозонам. 3. Отчеты по данным загруженным в регистры сведений. 4. Предусмотрена автоматическая загрузка данных в фоновом режиме (условия работы данной загрузке читайте в описании товара) Модуль работает без включенной константы по настройкам мониторинга. Модуль формы предоставляется с открытым кодом, общий модуль защищен. Любой заинтересованный пользователь, имеет возможность скачать демо-версию расширения.

22656 руб.

25.05.2021    12992    33    8    

12

Интеграция с сервисом vetmanager

WEB-интеграция Платформа 1С v8.3 Бухгалтерский учет 1С:Бухгалтерия 3.0 Бытовые услуги, сервис Платные (руб)

Внешняя обработка разрабатывалась для загрузки документов из Ветменеджер в 1С: Бухгалтерия 3.0

12000 руб.

02.02.2021    16615    43    49    

23
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Steelvan 302 29.12.21 11:12 Сейчас в теме
Как вариант "Разбор сайтов с применением Chrome devtools. Примеры от kuzkov.info "

https://infostart.ru/public/1492489/
2. Prometeus2011 211 29.12.21 12:37 Сейчас в теме
(1)Точно. Но Selenium может еще и кнопочки нажимать, списки поразворачивать.
3. so-quest 140 17.05.22 07:26 Сейчас в теме
для Selenium есть контейнер докера. Так удобнее работать, не надо разворачивать все это у себя руками.
4. Michael7777 10.06.22 15:10 Сейчас в теме
Можно ли наладить обработку таким образом, что бы система логинилась в аккаунт на сайте интернет магазина, и по очереди (по указанному в 1С списку) перебирала список нужных заказов и после этого вставляла в 1С нужные данные о заказе (номер отправки, статус и тд)?
5. downloadpascal 22.04.23 12:41 Сейчас в теме
Очень крутая статья, настроил selenium по ней, если не сложно подскажи пожалуйста как сделать метод "sendKeys", очень сложно читать faq wire json protocol, ужасно написано :), примеров json нету), я методом тыка отправил текст на input сайта,
ТелоЗапроса = "{
			|""text"": """+text_+"""
			|}";	


наугад поставил text и сработало, вот хочу теперь нажатие ENTER отправить, в гугле вообще ничего нету :), в основном статьи по phyton, javascript и тд.. :)
7. ONLYTILT 20 16.05.23 05:42 Сейчас в теме
(5)Так же в ключ text вставляете идентификаторы спец символов через перенос строки, например
ТелоЗапроса = "{
            |""text"": ""Привет\n\ue007""
            |}";    

Полный список символов:
https://www.selenium.dev/selenium/docs/api/rb/Selenium/WebDriver/Keys.html
8. ONLYTILT 20 16.05.23 06:59 Сейчас в теме
(7)Ошибся, без разделителя строк, просто "Привет\ue007", кстати отправка \n работает как энтер
6. ONLYTILT 20 29.04.23 10:10 Сейчас в теме
"pageLoadStrategy = игорь"
- означает, что при переходе по адресу, сервер не вернет ответ, пока не закончится загрузка страницы и не отработают на ней все скрипты. Это очень важный момент для реализации парсинга страницы.

Судя по документации лучше ставить свойство "pageLoadStrategy " в "normal", см скрины.
Прикрепленные файлы:
9. fixin 4253 07.07.23 18:56 Сейчас в теме
У меня выдавал ошибку: "Content-Type header does not indicate utf-8 encoded json: json; charset=utf-8" при запуске сессии.
Поборол так:

&НаКлиенте
Функция POSTЗапрос(Сайт, Ресурс, ТекстЗапроса)
	//https://helpme1s.ru/rabota-s-http-zaprosami-get-i-post-v-yazyke-1s-8-3-8-2-v-primerax
	
    Соединение = Новый HTTPСоединение(Сайт,,,,,,); //Новый ЗащищенноеСоединениеOpenSSL());
 
	Заголовки = Новый Соответствие;  
	Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    Запрос = Новый HTTPЗапрос(Ресурс, Заголовки);
    Запрос.УстановитьТелоИзСтроки(ТекстЗапроса);
 
    Результат = Соединение.ОтправитьДляОбработки(Запрос);
	
	Возврат Результат;
 
КонецФункции
Показать
10. fixin 4253 07.07.23 20:49 Сейчас в теме
кто знает, что можно указывать в скрипте, например мне нужно что-то типо этого скрипта, но для хрома выполнить, могу я просто так писать:

profile = webdriver.FirefoxProfile()
profile.set_preference('browser.download.folderList', 2) # custom location
profile.set_preference('browser.download.manager.showWhenStarting', False)
profile.set_preference('browser.download.dir', '/tmp')
profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'text/csv')

browser = webdriver.Firefox(profile)
browser.get("http://www.drugcite.com/?q=ACTIMMUNE")

browser.find_element_by_id('exportpt').click()
browser.find_element_by_id('exporthlgt').click()
Показать


Хотя нашел что-то похожее тут: https://www.lambdatest.com/blog/how-to-use-javascriptexecutor-in-selenium-webdriver/
Похоже, это Java Script выполняется...
11. ONLYTILT 20 18.07.23 12:35 Сейчас в теме
(10)
profile = webdriver.FirefoxProfile()
profile.set_preference('browser.download.folderList', 2) # custom location
profile.set_preference('browser.download.manager.showWhenStarting', False)
profile.set_preference('browser.download.dir', '/tmp')
profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'text/csv

Нужно включить скачивание файлов? В хроме это можно сделать через интерфейс инструментов разработчика, тот же ендпоинт что у веб драйвера просто другой запрос, документация: Chrome DevTools Protocol, если напишите что нужно конкретно сделать, могу помочь.
12. fixin 4253 18.07.23 15:44 Сейчас в теме
(11) нужно чтобы при клике на ссылке "Скачать" файл начинал скачиваться в папку по-умолчанию, т.е. нужно установить у браузера опции "Скачивать в папку по умолчанию" и задать эту папку.
По сути, чтобы кликнуть на файле и потом проверить, скачался он в папку или нет.
13. ONLYTILT 20 18.07.23 16:58 Сейчас в теме
(12) В хроме при запуске сессии нужно установить в "предпочтения" директорию загрузок по умолчанию, примерно так выглядит тело запроса создания сессии:
{
	"capabilities": {
		"timeouts": {
			"implicit": "0",
			"pageLoad": "300",
			"script": ""
		},
		"alwaysMatch": {
			"goog:chromeOptions": {
				"prefs": {
					"download.directory_upgrade": true,
					"download.prompt_for_download": false,
					"download.default_directory": "C:\\Users\\smurf\\Documents\\seleniumpython"
				}
			},
			"pageLoadStrategy": "eager",
			"browserName": "chrome"
		}
	}
}
Показать

Обратите внимание что слеши экранированы, это важно. Код формирования тела такой (потом сериализуется в JSON):
	// https://www.w3.org/TR/webdriver/#new-session
	Параметры = Новый Соответствие;
	
	Параметры["capabilities"] = Новый Соответствие;  
	
	// Описание сессии  
	Параметры["capabilities"]["alwaysMatch"] = Новый Соответствие;
	Параметры["capabilities"]["alwaysMatch"]["browserName"]		= "chrome"; // Создаем экземпляр драйвера Chrome
	Параметры["capabilities"]["alwaysMatch"]["pageLoadStrategy"]	= ИнструкцияНавигации; // Указываем что нужно ожидать полную загрузку со всеми ассетами 
	
	Параметры["capabilities"]["alwaysMatch"]["goog:chromeOptions"] = Новый Соответствие;
	Параметры["capabilities"]["alwaysMatch"]["goog:chromeOptions"]["prefs"] = Новый Соответствие;
	
	Параметры["capabilities"]["alwaysMatch"]["goog:chromeOptions"]["prefs"]["download.default_directory"]	= "C:\Users\smurf\Documents\seleniumpython";
	Параметры["capabilities"]["alwaysMatch"]["goog:chromeOptions"]["prefs"]["download.prompt_for_download"]	= Ложь; 
	Параметры["capabilities"]["alwaysMatch"]["goog:chromeOptions"]["prefs"]["download.directory_upgrade"] 	= Истина;
	
	// Описание таймаутов
	Параметры["capabilities"]["timeouts"] = Новый Соответствие;
	
	Параметры["capabilities"]["timeouts"]["script"]	= XMLСтрока(ТаймаутСкриптов); 							// Таймаут выполнения скрипта
	Параметры["capabilities"]["timeouts"]["pageLoad"]	= XMLСтрока(ТаймаутПерехода); 							// Таймаут загрузки страницы
	Параметры["capabilities"]["timeouts"]["implicit"]	= XMLСтрока(ТаймаутОпределенияМестоположенияЭлемента); 	// Таймаут ожидания обнаружения элемента	
Показать
14. fixin 4253 19.07.23 11:07 Сейчас в теме
(13) Спасибо, то что доктор прописал! Попробую.
16. fixin 4253 20.07.23 21:55 Сейчас в теме
(13) Спасибо, все получилось. Chrome по умолчанию и так не спрашивает каталог, кидает в Загрузки текущего пользователя. Но все же я прописал принудительно, чтобы кидал в нужный мне каталог, так удобнее.

	ТаймаутСкриптов = 60;
	ТаймаутПерехода = 100; 
	ТаймаутОпределенияМестоположенияЭлемента = 60;   
	ИнструкцияНавигации = "eager";
	
	// https://www.w3.org/TR/webdriver/#new-session
    Параметры = Новый Соответствие;
    
    Параметры["capabilities"] = Новый Соответствие;  
    
    // Описание сессии  
    Параметры["capabilities"]["alwaysMatch"] = Новый Соответствие;
    Параметры["capabilities"]["alwaysMatch"]["browserName"]        = "chrome"; // Создаем экземпляр драйвера Chrome
    Параметры["capabilities"]["alwaysMatch"]["pageLoadStrategy"]    = ИнструкцияНавигации; // Указываем что нужно ожидать полную загрузку со всеми ассетами 
    
    Параметры["capabilities"]["alwaysMatch"]["goog:chromeOptions"] = Новый Соответствие;
    Параметры["capabilities"]["alwaysMatch"]["goog:chromeOptions"]["prefs"] = Новый Соответствие;
    
    Параметры["capabilities"]["alwaysMatch"]["goog:chromeOptions"]["prefs"]["download.default_directory"]    = "c:\chromedriver\downloads";
    Параметры["capabilities"]["alwaysMatch"]["goog:chromeOptions"]["prefs"]["download.prompt_for_download"]    = Ложь; 
    Параметры["capabilities"]["alwaysMatch"]["goog:chromeOptions"]["prefs"]["download.directory_upgrade"]     = Истина;
    
    // Описание таймаутов
    Параметры["capabilities"]["timeouts"] = Новый Соответствие;
    
    Параметры["capabilities"]["timeouts"]["script"]    = XMLСтрока(ТаймаутСкриптов);                             // Таймаут выполнения скрипта
    Параметры["capabilities"]["timeouts"]["pageLoad"]    = XMLСтрока(ТаймаутПерехода);                             // Таймаут загрузки страницы
    Параметры["capabilities"]["timeouts"]["implicit"]    = XMLСтрока(ТаймаутОпределенияМестоположенияЭлемента);     // Таймаут ожидания обнаружения элемента    
	
	ТекстЗапроса = ПолучитьСтрокуJSON(Параметры);

Показать


Использую функцию для преобразования соответствия в JSON:
Функция ПолучитьСтрокуJSON(Данные) Экспорт

	ЗаписьJSON = Новый ЗаписьJSON;
	ЗаписьJSON.УстановитьСтроку();
	ЗаписатьJSON(ЗаписьJSON,Данные,,);
	
	Возврат ЗаписьJSON.Закрыть();

КонецФункции
Показать
Прикрепленные файлы:
15. fixin 4253 19.07.23 23:19 Сейчас в теме
Обнаружил, что Selenium стартует иногда на разных портах, иногда на 4444, иногда на других, в чем может быть причина?
Например у меня стартанул на таком порту: http://localhost:9515/status

По netstat посмотрел, порт 4444 вроде не занят.

При старте порт пишет в окне cromedriver.exe:

Starting ChromeDriver 114.0.5735.90 (386bc09e8f4f2e02XXXXXXXXXXXXXXX-refs/branch-heads/5735@{#1052}) on port 9515
17. ONLYTILT 20 21.07.23 09:29 Сейчас в теме
(15) 4444 порт по умолчанию для selenium grid сервера, у вебдрайвера рандомные порты 95**
18. fixin 4253 21.07.23 15:17 Сейчас в теме
(17) странно, я же обращаюсь через localhost:4444
Хотя если честно, слово selenium grid сервер мне ни о чем не говорит.

Хотя стоп, я понял в чем была проблема.
Вместо команды: java -jar selenium-server-4.10.0.jar standalone
Я запустил просто chromedriver.

Тем не менее через localhost:95** он работал, забавно.
19. ONLYTILT 20 21.07.23 15:19 Сейчас в теме
(18) selenium grid это программа из статьи, если просто скачать вебдрайвер и запустить его он запуститься на свободном порте 95**, для того что бы запустить его на определенном порте если не ошибаюсь есть аргумент --port, но по хорошему загуглить
20. fixin 4253 28.07.23 22:36 Сейчас в теме
Вот такой вопрос еще возник. Может кто подскажет, прежде чем я сам разберусь.

Вот я хочу получить некую строку, содержащую информацию, например:

<tr><td></td><button></button></tr>

По XPath я нахожу такие tr.

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

И еще вопрос - как-то браузер селениум закрывается через некоторый период бездействия пользователя. Это какой из тайм-аутов? Или надо другой тайм-аут добавлять.

    Параметры["capabilities"]["timeouts"]["script"]    = XMLСтрока(ТаймаутСкриптов);                             // Таймаут выполнения скрипта
    Параметры["capabilities"]["timeouts"]["pageLoad"]    = XMLСтрока(ТаймаутПерехода);                             // Таймаут загрузки страницы
    Параметры["capabilities"]["timeouts"]["implicit"]    = XMLСтрока(ТаймаутОпределенияМестоположенияЭлемента);     // Таймаут ожидания обнаружения элемента    

21. fixin 4253 30.07.23 18:54 Сейчас в теме
(20) Как искать в пределах заданного элемента, разобрался.
При поиске через XPath надо указывать .// а не просто //, чтобы искал в пределах текущего элемента:

	ListItemIds = SeleniumGetElementsByXpath(Session, "//tr[contains(@class, 'pointer')]").ids;
	Для Каждого ListItemID Из ListItemIds Цикл            
		//Тут важна точка в начале, без нее ищет по всему документу
		NumberID = SeleniumGetElementByXpath(Session, ".//td[contains(@class, 'col-number')]", ListItemID).id;
		NumberText = SeleniumGetElementText(Session, NumberID);
		FileNameID = SeleniumGetElementByXpath(Session, ".//td[contains(@data-test-id, 'TableRow__fileName__tr')]", ListItemID).id;
		FileNameText = SeleniumGetElementText(Session, FileNameID);
		DateID = SeleniumGetElementByXpath(Session, ".//td[contains(@class, 'col-date')]", ListItemID).id;
		DateText = SeleniumGetElementText(Session, NumberID);
		Сообщить("Номер: " + NumberText + " Дата: " + DateText + " Имя файла: " + FileNameText);
	КонецЦикла;

Показать


Сами функции по поиску элементов:

&НаКлиенте
Функция SeleniumGetElementsByXpath(Session, XPath, Element = Неопределено) Экспорт
	Команда = "
	|{
	|""using"": ""xpath"",
	|""value"": """ + XPath + """ 
	|}";	  
	Ресурс = Session.sessionURL + ?(Element = Неопределено, "", "element/" + Element + "/")+"elements";
	Р = SeleniumPOST(Ресурс, Команда);
	Р.Вставить("ids", Новый Массив());
	Если Р.ОК Тогда                     
		М = Р.JSON["value"];          
		Если ТипЗнч(М) = Тип("Массив") Тогда
			Для Каждого Эл ИЗ М Цикл
				Для Каждого КЗ ИЗ Эл Цикл
					Р.ids.Добавить(КЗ.Значение);   
					Прервать;
				КонецЦикла;
			КонецЦикла;                     
		КонецЕсли;
	КонецЕсли;
	Возврат Р;
КонецФункции     


&НаКлиенте
Функция SeleniumGetElementByXpath(Session, XPath, Element = Неопределено) Экспорт
	Команда = "
	|{
	|""using"": ""xpath"",
	|""value"": """ + XPath + """ 
	|}";	                       
	Ресурс = Session.sessionURL + ?(Element = Неопределено, "", "element/" + Element + "/")+"element";
	Р = SeleniumPOST(Ресурс, Команда);
	Р.Вставить("id", Неопределено);
	Если Р.ОК Тогда                     
		Соо = Р.JSON["value"];          
		Если ТипЗнч(Соо) = Тип("Соответствие") Тогда
			Для Каждого Эл ИЗ Соо Цикл
				Р.Вставить("id", Эл.Значение);   
				Прервать;
			КонецЦикла;                     
		КонецЕсли;
	КонецЕсли;
	Возврат Р;
КонецФункции       

&НаКлиенте
Функция SeleniumGetElementText(Session, Element) Экспорт
	Р = SeleniumGET(Session.sessionURL + "element/" + Element + "/text");
	Если Р.ОК И Р.JSON <> Неопределено Тогда     
		Возврат Р.JSON["value"];
	КонецЕсли;
	Возврат Неопределено;
КонецФункции 
Показать
23. ONLYTILT 20 31.07.23 11:49 Сейчас в теме
(21)Можете посмотреть публикацию, там уже готовый код.
25. fixin 4253 31.07.23 16:13 Сейчас в теме
(23) Где же вы раньше были, я думал это статья, не заметил файл обработки. ;-)
Но в целом у меня уже все получилось.
26. ONLYTILT 20 31.07.23 16:26 Сейчас в теме
(25)
(25)
статья, не заметил файл обработки. ;-)
Но в целом у меня уже все получилось.
Там в статье открыт код обработки
22. fixin 4253 30.07.23 18:56 Сейчас в теме
(20) Сессия прекращается вот с таким сообщением:

18:16:08.794 INFO [LocalNode.stopTimedOutSession] - Session id 59d1f1cf1a787b6282e913c588898214 timed out, stopping...
24. ONLYTILT 20 31.07.23 11:50 Сейчас в теме
(22) По умолчанию если не ошибаюсь сессия ожидает команды 10 минут, потом закрывается. Этот таймаут задается аргументом при запуске сервера, нужно смотреть документацию
27. Demion 18.10.23 11:50 Сейчас в теме
Тут обновился у меня Chrome старый драйвер перестал работать, хотел скачать новый, а там облом, написано что-то типа - "с версии 115 драйвер интегрирован в браузер" вот скачивайте по ссылке. Скачал, но откровенно скажу, что делать дальше не понял. Может кто сталкивался с этой проблемой и знает решение?
28. fixin 4253 19.10.23 18:06 Сейчас в теме
29. fixin 4253 19.10.23 19:50 Сейчас в теме
(27) а хотя нет, разобрался.
Скачать последнюю версию сервера, опция --selenium-manager true и java от oracle, а не c java.com
"c:\Program Files\Java\jdk-21\bin\java" -jar selenium-server-4.14.1.jar standalone --selenium-manager true


Подробнее:https://geniy1s.ru/kak-ispolzovat-novyj-selenium-web-driver/
30. Demion 20.10.23 09:46 Сейчас в теме
(29) Спасибо, тоже интересный вариант, но я вчера другой нашёл. Вот по этой ссылке https://www.nuget.org/packages/Selenium.WebDriver.ChromeDriver#readme-body-tab
Скачал пакет, в visual studio сделал сборку и получил в итоге нужный chromedriver проверил, всё работает. Хотя "танцев с бубном" было много :)
31. sergiykooo 27.11.23 11:03 Сейчас в теме
Кто-то пробовал использовать undetected-chromedriver чтобы обойти cloudflare?
32. igrned 15.04.24 23:19 Сейчас в теме
(31) Тоже интересует вопрос.CloudFlare блочит вход Как обойти?
33. Prometeus2011 211 17.04.24 11:48 Сейчас в теме
(32) Если хотите кого-то обмануть, то советую попробовать курить в сторону sikulix. Возможно, не так быстро и надёжно работает, но универсально.

Порядок действий примерно такой: Сикуля (Глаз Бога))) выполняет задачу по имитации действий пользователя по сохранению нужных вам страниц в каталог, а скрипт на 1с или любом другом языке - их парсит.
Оставьте свое сообщение