В этом видео мы покажем, как с помощью библиотеки undetected-chromedriver и фреймворка Selenium для языка программирования Python можно автоматизировать поиск бесплатных товаров на Avito. Мы продемонстрируем, как настроить среду для работы с библиотекой, написать скрипт для поиска бесплатных товаров на Avito и сохранения результатов в файл. Этот метод позволит существенно сэкономить время и повысить эффективность при поиске бесплатных товаров на Avito
Расшифровка видео
0:00
Всем привет Сегодня мы будем искать халяву на сайте avito.ru
0:05
Давайте сразу приступим Итак вот я открыл данный сайт нас
0:12
интересует именно то что можно взять бесплатно поисковике
0:19
бесплатно
0:28
и так здесь выводится то что можно
0:34
взять бесплатно или за деньги я так понимаю но еще все-таки если в описании есть слово бесплатно
0:43
[музыка] мне хотелось бы
0:48
все-таки найти что-то по электронике может удастся взять бесплатно
0:55
новый телефон процессор или видеокарта Итак давайте смотреть как мы будем
1:12
чуть-чуть увеличим экран чтобы было лучше видно Так давайте смотреть Из чего состоит
1:21
конкретно каждую объект как мы видим
1:27
уже сразу видно что различные классы название класса формируется динамически
1:34
то есть Авито всячески препятствует
1:40
Но их можно понять у них есть свой пиай который предоставляется только на
1:45
платных тарифах то есть Кто хочет может без проблем все это сделать но за деньги
1:53
мы же хотим это сделать бесплатно если мы посмотрим вкладку то тоже можно
2:00
заметить страницу
2:09
здесь запросов нам не приходит
2:15
не приходят эти данные которые нам необходимы Нам необходимо в первую очередь название цена описание
2:27
то есть здесь этих данных нет я потому что смотрел просто заранее
2:36
но всегда есть вариант интереснее
2:41
не то чтобы интереснее но который у нас очень сработал Давайте сразу создадим
2:46
новый проект который называем его пар совета
2:59
используется в данный момент питон версии 311 заметьте сразу создается новая
3:06
виртуальное окружение советую делать вам также как создаем проект
3:16
и
3:37
есть такая замечательная библиотека как selenium Но
3:42
она эмулирует полностью браузер то есть создавалась в первую очередь для тестов
3:48
для автоматического тестирования но как всегда пошел это все дальше и начали
3:55
людей использовать для автоматизации каких-то действий в браузере накруток и
4:01
прочего прочего прочего но сам селениум скажем так голос селениум довольно-таки легко
4:08
определяется сайтами и чаще всего они против того
4:14
чтобы например Авито так себя ведет для этого создали надстройки над
4:22
серийным которые с помощью определенных каких-то внутренних настроек просто банально Не палятся
4:31
не палец сайтами один из них я довольно часто использую это драйвер
4:40
он создавался в первую очередь для входа
4:46
система против ботов
4:51
комната ожидания и прочее прочее но во всяком случае если он обходит
4:57
Вы можете видеть здесь как это все происходит значит И для этого явно нам пригодится И
5:05
так ищем каменную как команду Как его установить ничего сложного идем наш проект терминал
5:16
команду и устанавливаем
5:24
пока останавливаться мы посмотрим как оно все работает самый минимальный код
5:31
У нас есть здесь мы будем грузить не данный сайт
5:39
который показывает Проходит ли проверку Вера или нет данной библиотека будет
5:45
открывать
5:58
Итак у нас не запускается У нас есть ошибка что данная версия
6:04
Chrome Driver поддерживает Chrome версии 111 То есть самый последний это такая
6:10
довольно известная ошибка Дело в том что у меня Google Chrome не обновлен вот
6:17
есть Справа сверху кнопка обновить все предлагает Но я это сейчас делать не
6:22
буду есть возможность замечательно возможно данной библиотеки указать какую
6:28
конкретную версию необходимо использовать [музыка]
6:34
у меня версия 108
6:41
сейчас Должно все запуститься
6:55
необходимо вставлять это
7:09
и сейчас должно закрыться Да все супер это работает
7:16
приступим коду предлагаю писать код с помощью LP
7:21
звучит может сложновато Но на самом деле мы напишем сегодня класс нам это должно
7:26
хватить Так давайте заведем класс
7:34
как угодно можно и набросаем методы
7:42
просто как угодно потом подумаем чем будем выполнять Итак нам понадобится
7:51
инициализатор и Плюс нам понадобится
8:02
здесь я предлагаю социализировать запускать сам браузер
8:11
нам понадобится одинаково потому как мы будем парсить сразу несколько страниц
8:20
то есть сколько будет сам проходить нажимать кнопку далее проходить в
8:26
следующей странице и пошли Так сколько нам необходимо ни одной страницы только парсить дальше
8:31
напишем непосредственно функцию которая метод который как раз
8:38
таки парсинг Одну страницу
8:46
но и который мы будем вызывать
8:54
[музыка]
9:02
конструктор не набросал думаю этого хватит
9:09
сразу предлагаю так у нас будет метод который будет доступен Извне это явно
9:17
все остальное можно сказать такие служебные методы которые не должны торчать наружу и будут просто вызываться
9:25
в данном методе поэтому есть возможность
9:30
сделать скажем так их приватными языке поэтому это не совсем то что у
9:39
других языках но грубо говоря это означает для других
9:45
разработчиков что не нужно вызывать данный метод Извне потому как он может
9:50
поменяться Ну или безопасность не стоит
9:58
конечно же делаем обычно будет у нас доступен
10:04
Давайте смотреть что мы будем передавать в инициализатор Нам необходимо передать
10:12
Явный урок Которому будет
10:18
потом нам необходимо передать что мы конкретно будем искать
10:25
потом как если посмотреть
10:31
мы увидим что здесь
10:37
явно больше 100 и явно нам не все это нужно то есть
10:42
смысл всего этого такой что пользователь должен вводить
10:48
примеру телевизор и скрипт должен искать все
10:57
все все объявления где есть телевизор примеру скины для cs:go Мне нужно чехол
11:04
не надо игровой машине нужны нужны только телевизоры Вот такая вот идея так как таких слов
11:12
может быть несколько примеру если мы хотим найти смартфон можно ввести слова
11:20
ключевые такие слова как смартфон телефон iPhone Android или что-то другое
11:26
Поэтому явно это будет передавать как слова
11:36
поэтому Давайте будем показывать
11:48
Какие типы это будут чтобы нам помогал
11:57
дальше необходимо указывать количество страниц
12:02
которые будут я думаю не имеет смысл парсить все страницы когда будет очень много и
12:09
хотелось бы чтобы можно было указывать именно необходимое количество поэтому
12:15
заведем аккаунт и присвоему есть значение молчанию если
12:27
аргумент и также вы сами видели столкнулся с
12:32
такой проблемой что версия Хрома не совпадает то есть последние с моей
12:38
поэтому предлагаю как опционального указывать еще вот эту версию
12:45
мы присвоим начальное значение на
12:50
чтобы если она не указана она будет Это последняя
13:16
стандартные [музыка]
13:34
[музыка]
13:46
напишу так
13:53
это готово дальше в сетап мы будем непосредственно Запускать браузер
14:11
можно прямо здесь и скопировать
14:17
[музыка] только здесь мы будем передавать не версию 108 А именно ту версию которая
14:24
передает пользователь
14:30
в данном методе наверное имеет смысл сразу
14:37
вызвать первый урок по идее нам лучше написать еще
14:51
маленький метод который Каждый делает
14:56
руки руки в этой компании
15:02
в этой команде браузер перейдет на татуировал который нам передает пользователь
15:13
вебинат Давайте смотреть как у нас будет работать по кино
15:24
театр должен нажимать [музыка]
15:30
либо на цифру либо на кнопку следующее но логично все-таки сделать следующее
15:36
так если страницы закончится то есть пользователь ведет к примеру 50 страниц
15:43
всего 40 то кнопки следующий не будет и просто завершить свою работу
16:07
данным
16:14
Итак Давайте напишем пока
16:19
пока у нас есть такой элемент
16:27
только сделан такой интересный лайфхак с элемент давайте я сначала напишем Потом
16:32
объясню Вася селектор
17:07
[музыка]
17:16
как его надо импортировать но
17:25
откуда нам это сделать придется скажем так вспоминать вручную
17:32
этот мы можем уже удалить
17:44
У нас есть сразу один готовый драйвера
17:50
нам надо теперь найти где хранится бар
17:59
ни не очень хочет подсказывать
18:08
именно здесь он находится Да отлично теперь не
18:16
подчеркивает
18:24
что вот это все значит
18:34
смотрите у нас есть такая функция Fight Element то есть
18:40
найти один элемент мы можем пытаться найти вот этот элемент по
18:47
атрибуту datamarker которая равен если такой элемент есть все прекрасно он
18:55
его вернет Но если данного элемента нет у нас возникнет ошибка чтобы данная ошибки не возникло можно
19:04
использовать разные способы есть варианты примеру обернуть это в рай
19:10
как ошибку и сделать какие-то действия но есть вариант Россия
19:17
я довольно часто использую таких случаев мы пытаемся найти сразу несколько
19:23
элементов с таким атрибутом если данного элемента не будет то нам вернется пустой
19:30
список если у нас соответственно будет вернется список в котором есть один элемент и
19:36
ошибки у нас не будет вообще ни в каком случае То есть как раз то что нам необходимо
19:43
если перефразировать можно написать layoutube потому как это если есть
19:50
элемент форме труб если список будет пустой и у нас завершится
19:56
если у нас это есть значит необходимо кликнуть этот элемент
20:03
то есть еще раз находим но уже конкретно один это элемент мы уверены что он есть
20:10
и делаем Клик по нему [музыка]
20:21
так супер но не очень у нас есть
20:28
которые нас должен ограничивать То есть это количество страниц которые передают
20:35
пользователи давайте наверное [музыка]
20:41
здесь передать
20:52
и после каждой операции мы будем этот
21:03
то есть теперь два слоя что есть кнопка следующая и что есть
21:11
если все это есть мы будем
21:17
будем вызывать метод partspage
21:23
мы его сначала будем вызывать потому что явно на странице которая передал пользователь на первую будет а дальше
21:30
вот вопрос как-то так
21:36
что нам необходимо дальше нам необходимо
21:42
парсить как раз таки уже
21:51
Итак давайте смотреть как это все устроено
22:06
вот мы видим что каждая вот данный блок дата маркер
22:12
это отдельный товар и внутри него будет храниться вся
22:18
информация по ID моего явно не найдем потому что
22:23
они генерируются но по опять же по дата атрибуту дата маркер этим без проблем
22:31
это сделаем
22:39
Так давайте тогда назовем это будет
22:45
не самое хорошее Название но пусть будет
22:53
именно здесь нам элементы необходимо
23:02
и здесь
23:15
дата маркер
23:21
по нему будем наверное работать
23:26
вот мы нашли все элементы которые перечислены на данной странице Давайте
23:33
смотреть что что в нем есть Нам необходимо хотелось бы для начала
23:41
найти название [музыка]
23:53
[музыка] деревянные чехлы на iPhone даже есть
24:00
скорее всего поэтому будем мы искать Но кстати
24:07
можно искать и вот поэтому деревянные чехлы на iPhone в Красногорске это понимала это есть два варианта название
24:14
то есть название Просто есть название которое добавляется населенный пункт либо регион
24:24
наверное будет проще доставать текст
24:38
по каждому отдельно
24:48
так как в titles она содержится все элементы то это будет
24:56
это будет один элемент и мы можем если мы ранее писали sould Driver то Теперь
25:04
можно писать элемент
25:22
еще раз посмотрим
25:35
можно пару раз написать и все запомним и данного элемента мы Нам необходимо взять
25:50
и присвоему какой-то переменной
25:57
раз здесь написано мы будем не будем придумывать ничего и так далее Что
26:03
необходимо хотелось бы дальше хотелось бы описание
26:15
Да вот он описание опять же это простой текст
26:25
[музыка]
26:35
мы здесь можем найти по классу
26:42
Как видим в классе явно Здесь много чего автоматически
26:47
генерируется Но судя по всему этим description это будет
26:52
у нас описание в котором будет постоянно поэтому я думаю можно подвязаться под
26:59
него идея должна работать
27:08
разбираться будем потом description
27:14
здесь все то же самое
27:19
только здесь у нас будет класс
27:26
копируем один скрипш может хватило бы просто description но что-то мне
27:32
подсказывает что будет работать так и так есть правда
27:38
один нюанс у нас здесь смотрите вообще 4 класса
27:45
ни одного из них Явно был полностью указать не можем то есть мы можем Что
27:51
именно содержится в данном классе какой-то кусочек Поэтому чтобы сказать
27:57
примерно должно содержать можно поставить здесь и
28:04
он должен понять Итак что что нам нужно дальше вот сразу
28:12
ссылка попала в глаза Давайте пытаться Итак
28:29
можно склонировать соседнюю
28:35
верхнюю строку
28:42
ищем по Data Marker
28:52
Обратите внимание здесь это уже не текст вот здесь текст вот здесь текст
28:59
это просто атрибут который нам необходимо достать
29:06
с помощью метода тоже ничего сложного
29:12
усилением есть
29:19
он найдет вот этот элемент найдет
29:34
мы видим что с ценой здесь могут быть проблемы
29:40
Авито по мне очень понятно
29:47
Да ну вот смотрите airpods Не бесплатно То есть если в поиске Авито висит
29:54
бесплатно он отдает и вот объявление салон бесплатно есть есть
30:15
отлично
30:32
[музыка]
31:06
просто проверить работоспособность работы не работает
31:13
у нас еще все остальное не готово поэтому
31:19
в методе pars Нам необходимо вызвать
31:34
браузер дальше
31:47
[музыка]
31:53
вызывает
32:11
запустит наш скрипт
32:17
здесь мы вызов данных класса и вызов только необходимо
32:25
передать аргументы у нас равно
32:38
далее переводим аргумент у нас лишний раз оно ничего не брала
32:46
довольно быстро Отработал и версия Хрома У нас у меня
32:58
[музыка]
33:13
что мы
33:19
нравится здесь мы указали что
33:31
то как мы видим он сразу подчеркивает что я ожидаю список А
33:38
ты мне даешь строку очень приятно становится работать и так
33:44
давайте мы передадим
33:51
Кстати на самом деле не важно что мы здесь перед этим потому как входим это еще не задействовали
33:59
у нас нигде не сравнивается есть это в объявлении нет у нас должно вывести вообще все объявления
34:08
[музыка]
34:24
очень даже похоже на правду
34:49
Так нам необходимо куда-то сохранять результат
34:55
потому как Ну не в конце же вводить в консоль мы можем вывести просто для отладки Но для дальнейшем для
35:04
пользователя хотелось бы это все сохранять как-то файл Давайте назовем это
35:12
метод
35:18
и наверное предлагаю здесь
35:28
переменную в котором мы будем при необходимости сохранять
35:38
потому что будет нужно не все
35:45
здесь мы передадим
35:52
число довольно популярно и
36:01
довольно [музыка]
36:07
довольно просто
36:15
будем перезаписывать каждый раз То есть если несколько раз вызовет пользователь
36:22
данной скрипт оно не будет Дописать в конец будет удалять предыдущую как будто
36:28
оно не актуально и полностью перезаписывать указываем кодировку
36:34
кодировка у нас без всяких сюрпризов
36:44
конструкция очень полезно и желательно писать именно с ней
36:50
гарантирует то что будет закрыт в любом случае
37:09
нужно передать также открытый файл в данном случае у нас F или FP равно F
37:17
Можно также написать Ну и два параметра которые
37:23
я пишу всегда можно просто по умолчанию это все писать
37:31
значит что не нужно лишний раз кодировать и необходимо отступать
37:40
Давайте смотреть где мы будем сохранять но естественно я думаю будем
37:47
сохранять вот здесь то есть
37:59
[музыка]
38:05
наполнить это
38:10
каким-то
38:18
и у нас это будет словарь в котором
38:27
написано банальные вещи
38:42
обычно словарь для дальнейшего сохранения в формате json
38:51
[музыка] прайс соответственно
39:07
немного наверное не так сделал нам не нужно каждую операцию
39:15
сохранять нам здесь необходимо просто
39:21
дать то что у нас есть [музыка] добавлять с помощью метода
39:35
солдата каждую операцию мы будем добавлять
39:41
вот эти данные и после всего цикла
39:47
мы будем вызывать уже
39:55
так мы проверили что он работает запустим программу
40:03
если не будет ошибок на выходе Хотелось бы получить
40:10
Джейсон в котором будут все данные
40:17
[музыка]
40:52
всё это работает единственное Посмотрите ход запрос был бесплатно цена цена
40:59
То есть все почти идет с ценой [музыка]
41:05
нам не нравится [музыка]
41:11
Не это Мы хотели Но это работает
41:17
Итак давайте Теперь мы удостоверимся что в описании товара есть
41:25
ключевые слова которые передал пользователь
41:31
потому как принципе это наша главная задача
41:38
давайте так если в данном в описании есть данное слово то тогда мы
41:44
будем добавлять эти данные если их нет просто ничего не будем делать
41:54
чтобы это нам сделать [музыка] проще сделать
42:00
можно написать конечно еще один цикл
42:05
потому как пользователь может передать
42:13
несколько несколько значений сколько мы наверное
42:20
его ограничивать за данным не будем и скрипт должен перебрать их все То есть
42:26
если хотя бы одно есть в описании значит это нам нужно
42:36
есть очень красивый вариант с помощью
42:44
[музыка] я попытаюсь это сейчас написать
42:51
и надеюсь это сработает
42:59
[музыка]
43:21
Да так только что здесь Давайте попытаюсь
43:28
объяснить метод eny всегда принимать себя какой-то
43:35
и тренированный объект в данном случае у нас есть список и для каждого списка
43:48
пока еще для каждого элемента списка он проверяет
43:55
трон или false если хотя бы один из них он вернет
44:04
если все есть еще один оператор
44:12
в данном случае нам как раз подходит
44:17
здесь используется генератор списков
44:23
каждый проверяется Каждый элемент примеру iPhone есть в описании
44:32
нам наверное надо сделать все привести к нижнему регистру
44:39
потому как написать нужно по-разному
44:44
должно работать и нам необходимо проверить что цена
44:51
цена равна 0 потому как много где сами видели указана цена другая
45:02
цена выйдет как строка поэтому переводим ее в раз
45:11
если
45:17
[музыка]
45:59
так что-то первое нашел до чехол от телефона
46:06
телефон есть там iPhone есть а у нас iPhone и телевизор iPhone iPhone
46:18
Ну может быть но очень даже похоже на правду Давайте
46:24
посмотрим как это в этом выглядит отлично
46:31
все что необходимо описание ноль
46:40
Как нужно осталось последнее что хотелось бы сделать
46:47
это Запускать браузер [музыка]
47:02
это будет более красиво
47:07
так Заведем мы опцию делать довольно не сложно
47:16
если конечно печальная поможет протестные
47:24
Давайте сами портировать вручную
47:31
драйвер Chrome Optimus
47:38
можно далее
47:44
необходимо добавить аргумент
48:20
добавим два телефона берем и проверять и напишем
48:32
Что может быть бесплатно посмотрим что вообще здесь чехол чехол
48:42
Давайте пульт напишем мало ли может выпадет где-то будет
48:50
и попробуем спросить три страницы
48:56
так сказать итоговая проверка работ
49:07
да Как видим браузер не открывается
49:12
Но работает
49:42
пока оно работает Давайте подумаем как в дальнейшем можно использовать данную
49:48
программу данный скрипт в принципе вариант много есть вариант к
49:54
примеру запускать его через крон либо что-то схожее с какой-то
50:02
периодичностью то есть примеру чтобы раз пять минут запускался данный скрипт и
50:07
проверял если на Авито видеокарта уже Force 480 дешевле 20 тысяч рублей
50:17
и если есть информацию
50:27
очень даже удобно один из вариантов
50:34
но либо просто Просто иногда запускать вот так Ну да
50:39
вот нашел один всего телевизор то есть вот нам так повезло но в целом все
50:45
проверено все работает это принципе все что я хотел сегодня показать ссылка на данный библиотеку будет в
50:54
описании либо первом комментарии код будет доступен на github без ссылка тоже будет где-то рядом Если есть какие-то
51:02
вопросы пожелания оставлять в комментариях Всем спасибо всем