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

29.12.21

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

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

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
Управление Selenium Web Driver из 1с (или парсинг из 1с по-взрослому):
.zip 854,26Kb
24
24 Скачать (1 SM) Купить за 1 850 руб.

Что такое 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.

См. также

WEB-интеграция Администрирование веб-серверов Платные (руб)

Веб-портал обеспечивает удобный доступ к конфигурации 1С:ITIL(ИТИЛ), 1С:ITILIUM, Управление IT-отделом 8 через интернет с любого устройства посредством браузера, увеличивая эффективность работы пользователей и снижая нагрузку на сервер. Быстрая инсталляция портала за пару часов, удобный и интуитивно понятный интерфейс и безопасность данных помогут упростить работу с порталом и ускорить выполнение бизнес-процессов компании.

128000 руб.

19.12.2023    2723    3    0    

10

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

Модуль "Подсистема интеграции AmoCRM с 1С" позволяет обеспечить единое информационное пространство, в котором пользователи могут эффективно управлять клиентской базой, следить за статусами сделок и поддерживать актуальность данных как в AmoCRM, так и в 1С.

60000 руб.

07.05.2019    34812    68    45    

27

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

Онлайн-заказ - это решение для автоматизации процесса оформления заказов на сайте в торговых организациях. Продукт обеспечивает легкое взаимодействие между компанией и клиентами через веб-интерфейс, интегрированный с 1С:Предприятие. Система позволяет снизить операционные расходы, повысить лояльность клиентов и оптимизировать работу отдела продаж.

57600 руб.

26.11.2024    2498    2    3    

5

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

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

36000 руб.

03.08.2020    19148    23    22    

20

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

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

12000 руб.

02.02.2021    18920    54    50    

31

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

Модуль "Экспортер" — это расширение для 1С, предназначенное для автоматизации процессов выгрузки данных. Оно позволяет эффективно извлекать, преобразовывать и передавать данные из систем 1С в интеграционную платформу Spot2D. Подсистема упрощает настройку, снижает количество ручных операций и обеспечивает удобный контроль данных.

14400 руб.

20.12.2024    927    4    2    

6

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

Расширение значительно упрощает написание API на 1С. Веб программисты получают простой и понятный доступ к 1С. Описание API создаётся автоматически и представляется в виде удобном как для человека, так и для программной обработки.

24000 руб.

27.09.2024    4229    3    2    

4

Обмен с ГосИС 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    93239    193    217    

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

https://infostart.ru/public/1492489/
2. Prometeus2011 177 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 23 16.05.23 05:42 Сейчас в теме
(5)Так же в ключ text вставляете идентификаторы спец символов через перенос строки, например
ТелоЗапроса = "{
            |""text"": ""Привет\n\ue007""
            |}";    

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

Судя по документации лучше ставить свойство "pageLoadStrategy " в "normal", см скрины.
Прикрепленные файлы:
9. fixin 4280 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 4280 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 23 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 4280 18.07.23 15:44 Сейчас в теме
(11) нужно чтобы при клике на ссылке "Скачать" файл начинал скачиваться в папку по-умолчанию, т.е. нужно установить у браузера опции "Скачивать в папку по умолчанию" и задать эту папку.
По сути, чтобы кликнуть на файле и потом проверить, скачался он в папку или нет.
13. ONLYTILT 23 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 4280 19.07.23 11:07 Сейчас в теме
(13) Спасибо, то что доктор прописал! Попробую.
16. fixin 4280 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 4280 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 23 21.07.23 09:29 Сейчас в теме
(15) 4444 порт по умолчанию для selenium grid сервера, у вебдрайвера рандомные порты 95**
18. fixin 4280 21.07.23 15:17 Сейчас в теме
(17) странно, я же обращаюсь через localhost:4444
Хотя если честно, слово selenium grid сервер мне ни о чем не говорит.

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

Тем не менее через localhost:95** он работал, забавно.
19. ONLYTILT 23 21.07.23 15:19 Сейчас в теме
(18) selenium grid это программа из статьи, если просто скачать вебдрайвер и запустить его он запуститься на свободном порте 95**, для того что бы запустить его на определенном порте если не ошибаюсь есть аргумент --port, но по хорошему загуглить
20. fixin 4280 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 4280 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 23 31.07.23 11:49 Сейчас в теме
(21)Можете посмотреть публикацию, там уже готовый код.
25. fixin 4280 31.07.23 16:13 Сейчас в теме
(23) Где же вы раньше были, я думал это статья, не заметил файл обработки. ;-)
Но в целом у меня уже все получилось.
26. ONLYTILT 23 31.07.23 16:26 Сейчас в теме
(25)
(25)
статья, не заметил файл обработки. ;-)
Но в целом у меня уже все получилось.
Там в статье открыт код обработки
22. fixin 4280 30.07.23 18:56 Сейчас в теме
(20) Сессия прекращается вот с таким сообщением:

18:16:08.794 INFO [LocalNode.stopTimedOutSession] - Session id 59d1f1cf1a787b6282e913c588898214 timed out, stopping...
24. ONLYTILT 23 31.07.23 11:50 Сейчас в теме
(22) По умолчанию если не ошибаюсь сессия ожидает команды 10 минут, потом закрывается. Этот таймаут задается аргументом при запуске сервера, нужно смотреть документацию
27. Demion 18.10.23 11:50 Сейчас в теме
Тут обновился у меня Chrome старый драйвер перестал работать, хотел скачать новый, а там облом, написано что-то типа - "с версии 115 драйвер интегрирован в браузер" вот скачивайте по ссылке. Скачал, но откровенно скажу, что делать дальше не понял. Может кто сталкивался с этой проблемой и знает решение?
28. fixin 4280 19.10.23 18:06 Сейчас в теме
29. fixin 4280 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 177 17.04.24 11:48 Сейчас в теме
(32) Если хотите кого-то обмануть, то советую попробовать курить в сторону sikulix. Возможно, не так быстро и надёжно работает, но универсально.

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