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

29.12.21

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

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

Скачать файлы

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

Что такое 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    15745    10    17    

11

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

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

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

5040 руб.

04.05.2021    17548    6    15    

13

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

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

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

12000 руб.

02.02.2021    16358    42    49    

23

[Расширение] БОР-Навигатор.Культура

Зарплата Бюджетный учет WEB-интеграция Обмен с ГосИС Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 Государственные, бюджетные структуры Россия Бюджетный учет Платные (руб)

Расширение конфигурации, включающее в себя объекты, необходимые для подготовки и сдачи отчета "Штатная численность" системы "БОР-Навигатор.Культура" в программе "1С:Зарплата и кадры государственного учреждения", редакция 3.1.

8400 руб.

01.02.2019    25737    9    0    

7

Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС

Обмен с ГосИС WEB-интеграция Платформа 1С v8.3 Управляемые формы 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия государственного учреждения 1С:Документооборот 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Платные (руб)

Обработка является альтернативой механизму, разработанному фирмой 1С и заполняющему реквизиты контрагента по ИНН или наименованию. Не требуется действующей подписки ИТС. Вызывается как внешняя дополнительная обработка, т.е. используется, непосредственно, из карточки контрагента. Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС (egrul.nalog.ru) для БП 2.0, БП 3.0, БГУ 1.0, БГУ 2.0, УТ 10.3, УТ 11.x, КА 1.1, КА 2.x, УПП 1.x, ERP 2.x, УНФ 1.5, УНФ 1.6, УНФ 3.0, ДО 2.1

2400 руб.

28.04.2016    88579    160    215    

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

https://infostart.ru/public/1492489/
2. Prometeus2011 210 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 4252 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 4252 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 4252 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 4252 19.07.23 11:07 Сейчас в теме
(13) Спасибо, то что доктор прописал! Попробую.
16. fixin 4252 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 4252 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 4252 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 4252 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 4252 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 4252 31.07.23 16:13 Сейчас в теме
(23) Где же вы раньше были, я думал это статья, не заметил файл обработки. ;-)
Но в целом у меня уже все получилось.
26. ONLYTILT 20 31.07.23 16:26 Сейчас в теме
(25)
(25)
статья, не заметил файл обработки. ;-)
Но в целом у меня уже все получилось.
Там в статье открыт код обработки
22. fixin 4252 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 4252 19.10.23 18:06 Сейчас в теме
29. fixin 4252 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?
Оставьте свое сообщение