Мы запустили дрипы и взорвали нишу

В 2020 мы запустили линейку из двух вкусов дрип-кофе – Эфиопия и Бразилия. Мы не были первооткрыватели. Дрипы изобрели задолго до нас – еще японцы в 90-х. У зарубежных и локальных обжарщиков дрипы уже были. А когда у конкурентов уже есть продукт, который ты собираешься запускать на рынок, остается только одно – неизбежно делать его более качественн…

3

Telegram-бот для получения адреса по локации или координатам (Python)

Привет! Представь ситуацию, когда тебе скинули координаты или локацию, но ты хочешь срочно узнать адрес этого места.

Сегодня попробуем написать Telegram-бота для получения адреса по координатам или локации.

13

Как найти однотипную информацию в большом количестве файлов, используя Python?

Недавно мы решали следующую задачу – необходимо найти и удалить содержащие номера карт файлы, размещенные на общем ресурсе. Если нужно было бы искали что-то, определенное и однозначное, мы могли бы воспользоваться поиском в самой операционной системе (используя стандартны поиск текста в содержимом файла). Но, как правило, поиск стандартными средств…

5

Сбор данных с помощью API Вконтакте

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

Так вот, сделав несколько пробных выборок для анализа, мы поняли, что поиск по фамилии и имени дает…

4

Использование парсера для получения информации из открытых источников (проверки информации)

10000 кадастровых номеров, 30000 записей, источник — веб-сайт, дедлайн — конец рабочего дня. Как выгрузить такой объем данных?

Использование парсера для получения информации из открытых источников (проверки информации)
3
)==-1 and i.find('.xlsx.')==-1:\n open_arch(path+'/'+i) #Функция по обработке архивов\n else:\n #Если это директория, то проваливаемся в нее\n find_file(os.listdir(path+'/'+i),path+'/'+i)\n except Exception as err:\n print(err,path+'/'+i)","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Теперь напишем саму функцию, которая будет обрабатывать найденные по условию файлы:

"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"def open_arch(path_file):\n z = zipfile.ZipFile(path_file, 'r') #открываем архив\n files=z.namelist() #получаем список файлов в архиве\n try:\n for f in files:\n if f=='xl/sharedStrings.xml':\n if re.search(pattern_card16, z.read(f))!=None or re.search(pattern_card18, z.read(f))!=None:\n list_file.write(path_file+'\\n') #Если находит совпадение, то пишем путь в файл\n #print(re.findall(pattern_card16, z.read(r))) # если вам нужно \n #print(re.findall(pattern_card18, z.read(r))) # выводить совпадения\n except Exception as err:\n print(err, files)","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Определяем директорию для поиска и запускаем функцию для поиска:

"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"path='Y:' #указываем путь к общему ресурсу, здесь я его подцепил как диск Y: \n\nlist_file=open('list_file', 'w+') #открываем файл для записи\nfind_file(os.listdir(path), path) #запускаем обработку","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Резюме

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Наша работа сделана. Ждем, когда отработает скрипт и получим итоговый файл для анализа. Вы зададите вопрос, почему я сразу не стал удалять файлы? Потому что поиск основан на простом регулярном выражении и туда могут попасть номера заявок, договоров и т.д.

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

В результате нам удалось избежать ручного анализа более 154 тысяч файлов и сократить выборку более чем в 100 раз.

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Я надеюсь, моя инструкция была полезна. Спасибо за внимание.

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

#selectel_инструкция

"}}],"summaryContent":null,"isExistSummaryContent":false,"warningFromEditor":null,"warningFromEditorTitle":null,"counters":{"comments":0,"favorites":8,"reposts":0,"views":6,"hits":2345,"reads":null,"online":0},"dateFavorite":0,"hitsCount":2345,"isCommentsEnabled":true,"isLikesEnabled":true,"isRemovedByUserRequest":false,"isFavorited":false,"isPinned":false,"repostId":null,"repostData":null,"subscribedToTreads":false,"isEditorial":false,"isAudioAvailable":false,"audioUrl":null,"isAudioAvailableToGenerate":false,"commentEditor":{"enabled":true,"who":null,"text":"","until":null,"reason":null,"type":"everybody"},"isBlur":false,"isPublished":true,"isDisabledAd":false,"withheld":[],"ogTitle":null,"ogDescription":null,"url":"https://vc.ru/dev/156704-kak-naiti-odnotipnuyu-informaciyu-v-bolshom-kolichestve-failov-ispolzuya-python","author":{"id":447345,"name":"NTA","nickname":null,"description":null,"uri":"","avatar":{"type":"image","data":{"uuid":"e7175678-aaab-09f8-0271-7b3af7ac4670","width":1207,"height":1207,"size":83090,"type":"jpg","color":"e3ebf8","hash":"","external_service":[]}},"cover":{"cover":{"type":"image","data":{"uuid":"8575b55d-a1f0-53ee-9ad6-78268f9ea45c","width":1280,"height":373,"size":56005,"type":"jpg","color":"b0b9ca","hash":"","external_service":[]}},"cover_y":0},"achievements":[{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":4980908,"userId":447345,"count":0,"shareImage":"https://api.vc.ru/achievements/share/4980908"},{"title":"3 года на vc.ru","code":"registration_3_years","description":"Провёл 3 года вместе с vc.ru. Получена 23 июля 2025.","previewUuid":"d9d72ac5-bcb5-55e0-8c72-b99251e5cdd9","formats":{"glb":"https://static.vc.ru/achievements/shark.glb","usdz":"https://static.vc.ru/achievements/shark.usdz"},"viewData":{"contentColor":"#8E6F09","textMaxWidth":0.66796875,"textX":0.5205078125,"textY":0.341796875,"logoX":0.5205078125,"logoY":0.4609375,"logoXNoText":0.5,"logoYNoText":0.3662109375},"id":1356821,"userId":447345,"count":0,"shareImage":"https://api.vc.ru/achievements/share/1356821"},{"title":"5 лет на vc.ru","code":"registration_5_years","description":"Провёл 5 лет вместе с vc.ru. Получена 23 июля 2025.","previewUuid":"a9140d54-73b8-5f40-afa8-449fbaafd42b","formats":{"glb":"https://static.vc.ru/achievements/whale.glb","usdz":"https://static.vc.ru/achievements/whale.usdz"},"viewData":{"contentColor":"#8E6F09","textMaxWidth":0.66796875,"textX":0.533203125,"textY":0.658203125,"logoX":0.533203125,"logoY":0.77734375,"logoXNoText":0.4375,"logoYNoText":0.66015625},"id":130113,"userId":447345,"count":0,"shareImage":"https://api.vc.ru/achievements/share/130113"}],"lastModificationDate":1765058067,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"subsite":{"id":235819,"name":"Разработка","description":"Сообщество разработчиков: публикации о личном опыте, выдающиеся приёмы при решении рутинных задач, полезные материалы для профессионального роста.","uri":"/dev","avatar":{"type":"image","data":{"uuid":"fef5b5fb-e488-5b7f-8445-e3a26a910b44","width":1200,"height":1200,"size":7757,"type":"png","color":"343434","hash":"04042b2b1c1000","external_service":[]}},"cover":{"type":"image","data":{"uuid":"2a214cc5-35cc-58ca-bc07-fc1c892d2101","width":960,"height":280,"size":177,"type":"png","color":"343434","hash":"","external_service":[]}},"lastModificationDate":1642411346,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":false,"isDisabledAd":false,"nickname":"dev","isUnsubscribable":true,"badge":null,"badgeId":null,"isDonationsEnabled":false,"isOnline":false,"isPlus":false,"isUnverifiedBlogForCompanyWithoutPro":false,"isVerified":false,"isRemovedByUserRequest":false,"isFrozen":false,"isPro":false,"type":2,"subtype":"community"},"reactions":{"counters":[{"id":1,"count":5}],"reactionId":0},"isNews":false,"source":null,"clusters":[],"donations":{"amount":0,"isDonated":false},"commentsSeenCount":null}},{"type":"entry","data":{"id":131686,"customUri":null,"subsiteId":447345,"title":"Сбор данных с помощью API Вконтакте","date":1591184030,"dateModified":1591184030,"blocks":[{"type":"text","cover":true,"hidden":false,"anchor":"","data":{"text":"

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

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Так вот, сделав несколько пробных выборок для анализа, мы поняли, что поиск по фамилии и имени дает слишком ненадежные результаты, т.к. даты рождения многих пользователей скрыты, и даже выгрузив все совпадения по ФИ, вы все равно не сможете потом идентифицировать нужные данные.

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Важно: мы заметили, что при поиске по ФИ + ДР Вконтакте выдаст подходящих пользователей, даже если их дата рождения скрыта. Это можно было использовать, только нужно обеспечить связь с данными поискового запроса. Для работы с API VK мы решили использовать Python с библиотекой vk_api (установка: pip install vk_api). Итого нам потребуются 2 библиотеки:

"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"import pandas as pd\nimport vk_api","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Далее – импорт входных данных в формате ID, Имя, Фамилия, Отчество (можно оставить пустым, так как Вконтакте отчество отсутствует), День рождения, Месяц рождения, Год рождения. Пример: (0,Пет, Петрови, ,1,1,1950)

"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"data = pd.read_csv('in.txt', encoding = 'cp1251')","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Затем авторизация и получение токена VK:

"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"vk_session = vk_api.VkApi('+79XXXXXXXXXX', 'password')\nvk_session.auth()\nvk = vk_session.get_api()","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

После этого мы можем начинать выполнять запросы к API.

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Разберем для примера использование метода users.search и сохранение полученных результатов. Основные параметры это q – строка поискового запроса, так же для поиска нам понадобятся birth_day, birth_month, birth_year, count – количество результатов (поставим максимум – 1000), fields – список дополнительных полей, в примере укажем ‘bdate, city’. Результат будет возвращен в виде словаря Python. Разберем подробно:

"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"t={} #создаем словарь для хранения данных, получаемых от API VK\nfor j in range(0, len(data)): #запускаем поиск по массиву\n #Далее следует обращение к API с нашими параметрами:\n t[j]=vk.users.search(q = data['N'][j] + ' ' + data['F'][j], birth_day = data['D'][j], \\ birth_month = data['M'][j], birth_year = data['Y'][j], count = 1000, fields='bdate, city')\n for h in (t[j]['items']): #Сохраняем результаты поиска в файл\"users.txt\"\n with open('users.txt','a') as f1:\n f1.write((str(data['id'][j]) + ';' #ID исходный\n + str(t[j]['count']) + ';' #Количество найденных пользователей\n + str(h['id']) + ';' #ID пользователя VK\n + h['last_name'] + ';' #Фамилия\n + h['first_name'] + ';' #Имя\n + h.get('bdate','') + ';' #Дата рождения\n + h.get('city',{}).get('title','') #У города несколько параметров - нам нужно название: title\n + ';\\n').encode('cp1251', 'replace').decode('cp1251'))#Для удаления нестандартных символов, которые могут вызывать ошибки","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Далее мы можем в этом же цикле осуществить поиск и сохранение ID друзей пользователя, за это отвечает метод friends.get. Если друзей нет (или скрыты), метод вернет ошибку, поэтому используем try/except:

"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"try:\n m=vk.friends.get(user_id = str(h['id']), count = 50000)\n for q in m['items']: #Сохраняем ID друзей в файл \"friends.txt\"\n with open('friends.txt','a') as f2:\n f2.write(str(data['id'][j]) + ';' + str(h['id']) + ';' + str(q) + ';\\n')\nexcept: #Если друзей нет (или скрыты) пишем в файл 0 для этого ID\n with open('friends.txt','a') as f2:\n f2.write(str(data['id'][j]) + ';' + str(h['id']) + ';0;\\n')","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Если мы хотим выполнить большое количество запросов, нужно добавить паузу между ними, например, команда sleep библиотеки time. Без этого учетная запись VK может быть заблокирована. Экспериментальным путем подобраны значения 9 секунд для поиска без друзей и 5 для поиска с друзьями (меньше, т.к. получение и сохранение списка друзей занимает несколько секунд). Производительность при использовании одной учетной записи Вконтакте составляет 8-10 тыс. пользователей в сутки. Полученные результаты сохраняются в файлы users.txt и friends.txt и могут в дальнейшем быть обработаны в БД или средствами Python.

"}}],"summaryContent":null,"isExistSummaryContent":false,"warningFromEditor":null,"warningFromEditorTitle":null,"counters":{"comments":3,"favorites":15,"reposts":0,"views":5,"hits":16700,"reads":null,"online":0},"dateFavorite":0,"hitsCount":16700,"isCommentsEnabled":true,"isLikesEnabled":true,"isRemovedByUserRequest":false,"isFavorited":false,"isPinned":false,"repostId":null,"repostData":null,"subscribedToTreads":false,"isEditorial":false,"isAudioAvailable":false,"audioUrl":null,"isAudioAvailableToGenerate":false,"commentEditor":{"enabled":true,"who":null,"text":"","until":null,"reason":null,"type":"everybody"},"isBlur":false,"isPublished":true,"isDisabledAd":false,"withheld":[],"ogTitle":null,"ogDescription":null,"url":"https://vc.ru/dev/131686-sbor-dannyh-s-pomoshyu-api-vkontakte","author":{"id":447345,"name":"NTA","nickname":null,"description":null,"uri":"","avatar":{"type":"image","data":{"uuid":"e7175678-aaab-09f8-0271-7b3af7ac4670","width":1207,"height":1207,"size":83090,"type":"jpg","color":"e3ebf8","hash":"","external_service":[]}},"cover":{"cover":{"type":"image","data":{"uuid":"8575b55d-a1f0-53ee-9ad6-78268f9ea45c","width":1280,"height":373,"size":56005,"type":"jpg","color":"b0b9ca","hash":"","external_service":[]}},"cover_y":0},"achievements":[{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":4980908,"userId":447345,"count":0,"shareImage":"https://api.vc.ru/achievements/share/4980908"},{"title":"3 года на vc.ru","code":"registration_3_years","description":"Провёл 3 года вместе с vc.ru. Получена 23 июля 2025.","previewUuid":"d9d72ac5-bcb5-55e0-8c72-b99251e5cdd9","formats":{"glb":"https://static.vc.ru/achievements/shark.glb","usdz":"https://static.vc.ru/achievements/shark.usdz"},"viewData":{"contentColor":"#8E6F09","textMaxWidth":0.66796875,"textX":0.5205078125,"textY":0.341796875,"logoX":0.5205078125,"logoY":0.4609375,"logoXNoText":0.5,"logoYNoText":0.3662109375},"id":1356821,"userId":447345,"count":0,"shareImage":"https://api.vc.ru/achievements/share/1356821"},{"title":"5 лет на vc.ru","code":"registration_5_years","description":"Провёл 5 лет вместе с vc.ru. Получена 23 июля 2025.","previewUuid":"a9140d54-73b8-5f40-afa8-449fbaafd42b","formats":{"glb":"https://static.vc.ru/achievements/whale.glb","usdz":"https://static.vc.ru/achievements/whale.usdz"},"viewData":{"contentColor":"#8E6F09","textMaxWidth":0.66796875,"textX":0.533203125,"textY":0.658203125,"logoX":0.533203125,"logoY":0.77734375,"logoXNoText":0.4375,"logoYNoText":0.66015625},"id":130113,"userId":447345,"count":0,"shareImage":"https://api.vc.ru/achievements/share/130113"}],"lastModificationDate":1765058067,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"subsite":{"id":235819,"name":"Разработка","description":"Сообщество разработчиков: публикации о личном опыте, выдающиеся приёмы при решении рутинных задач, полезные материалы для профессионального роста.","uri":"/dev","avatar":{"type":"image","data":{"uuid":"fef5b5fb-e488-5b7f-8445-e3a26a910b44","width":1200,"height":1200,"size":7757,"type":"png","color":"343434","hash":"04042b2b1c1000","external_service":[]}},"cover":{"type":"image","data":{"uuid":"2a214cc5-35cc-58ca-bc07-fc1c892d2101","width":960,"height":280,"size":177,"type":"png","color":"343434","hash":"","external_service":[]}},"lastModificationDate":1642411346,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":false,"isDisabledAd":false,"nickname":"dev","isUnsubscribable":true,"badge":null,"badgeId":null,"isDonationsEnabled":false,"isOnline":false,"isPlus":false,"isUnverifiedBlogForCompanyWithoutPro":false,"isVerified":false,"isRemovedByUserRequest":false,"isFrozen":false,"isPro":false,"type":2,"subtype":"community"},"reactions":{"counters":[{"id":1,"count":4}],"reactionId":0},"isNews":false,"source":null,"clusters":[],"donations":{"amount":0,"isDonated":false},"commentsSeenCount":null}},{"type":"entry","data":{"id":125905,"customUri":null,"subsiteId":447345,"title":"Использование парсера для получения информации из открытых источников (проверки информации)","date":1588960828,"dateModified":1588960828,"blocks":[{"type":"text","cover":true,"hidden":false,"anchor":"","data":{"text":"

10000 кадастровых номеров, 30000 записей, источник — веб-сайт, дедлайн — конец рабочего дня. Как выгрузить такой объем данных?

"}},{"type":"media","cover":true,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"9f94355e-c4bb-f7cc-ee03-960c78c379a8","width":1280,"height":720,"size":526476,"type":"jpg","color":"096d66","hash":"","external_service":[]}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

В своей работе мы нередко встречаемся с необходимостью получить недостающую/обновить существующую информацию об исследуемом объекте. При условии, что нужная нам информация находится в открытых источниках, мы можем извлечь ее с помощью программы для сканирования веб-страниц (парсера).

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Рассмотрим пример парсинга сервиса Росреестра. В связи с большим количеством информации о технологии парсинга в сети интернет, сделаем акцент на практической реализации программного кода.

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Итак, нам необходимо получить информацию об адресе и типе объекта недвижимости, но известен только кадастровый номер. Необходимая информация содержится на сервисе rosreestr.NET.

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Алгоритм работы.

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

1) Перейти на сайт

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

2) Ввести кадастровый номер в поле поиска, нажать Enter;

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

3) В появившемся ниже поле определить проверяемый объект и нажать кнопку «выбрать»;

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

4) На странице объекта идентифицировать информацию (в нашем случае это тип, кадастровый номер, и адрес объекта недвижимости);

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

5) Сохранить результат.

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Для реализации инструмента нам необходим Python, библиотеки Selenium, Pandas, а также Google Chrome, ChromeDriver и базовые навыки HTML.

"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["Входные данные."],"type":"UL"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Кадастровые номера объектов находятся в таблице в формате Excel.Импортируем электронную таблицу, получаем список из кадастровых номеров.

"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"import pandas as pd\nimport numpy as np\n\nadres=pd.read_excel('kad.xlsx',header=None)\nllist=adres[]","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

2. Создадим функции.startChrome — функция запуска браузера.

"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"from selenium import webdriver\nfrom selenium.webdriver.common.by import By\nfrom selenium.webdriver.common.keys import Keys\nfrom selenium.webdriver.support.ui import WebDriverWait\nfrom selenium.webdriver.chrome.options import Options\nfrom selenium.webdriver.support import expected_conditions as EC\n\ndef startChrome():\n chrome_options = Options()\n driver = webdriver.Chrome(options=chrome_options)\n driver.set_page_load_timeout(30)\n WebDriverWait(driver, 2)\n return driver","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

wait_element и wait_element_text — функции обращения к веб-элементам:

"}},{"type":"list","cover":false,"hidden":false,"anchor":"","data":{"items":["основаны на явном ожидании (explicit waits) элементов, данная реализация позволяет избежать использования таймера, что ускоряет работу кода;","обращаются к элементу через XPath (язык запросов для извлечения элементов в XML документе)."],"type":"UL"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"def wait_element (path):\n try:\n WebDriverWait(driver, 30).until(\n EC.presence_of_element_located((By.XPATH, path)))\n except:\n driver.refresh()\n return driver.find_element_by_xpath(path)\n\ndef wait_element_text (path): \n try:\n element = WebDriverWait(driver, 30).until(\n EC.presence_of_element_located((By.XPATH, path)))\n except:\n aaa=np.nan\n else:\n aaa=driver.find_element_by_xpath(path).text\n return aaa","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

XPath можно написать вручную, предварительно ознакомившись с синтаксисом или воспользоваться встроенным в браузер решением.

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Нажать правой кнопкой на интересующий веб-элемент в окне браузера -> «Просмотр кода элемента».

"}},{"type":"media","cover":false,"hidden":false,"anchor":"","data":{"items":[{"title":"","image":{"type":"image","data":{"uuid":"b38a46ab-77c4-b8d5-c9ba-13a4cd8d7bd9","width":1024,"height":616,"size":559869,"type":"png","color":"dbdbe3","hash":"","external_service":[]}}}]}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

В появившейся справа консоли кликнуть правой кнопкой мыши по выбранному элементу -> выбрать «copy XPath».

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Скопированный XPath можно использовать в качестве входного параметра для переменной.

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

3. Запуск скрипта.Алгоритм приведенного скрипта работает в однопоточном режиме, извлекая информацию о каждом объекте недвижимости по кадастровому номеру, находящегося в исходной таблице kad.xlsx.

"}},{"type":"code","cover":false,"hidden":false,"anchor":"","data":{"text":"#создаем пустые таблицы\ndf=df_temp=pd.DataFrame() \n\n#запускаем браузер\ndriver = startChrome() \n#переходим на веб-страницу ранее упомняутого сервиса\ndriver.get('https://rosreestr.net/proverit-kvartiru') \n#циклически извлекаем кадастровые номера объектов недвижимости из списка\nfor i in list(range(0,len(llist))): \n #присваиваем пустые знаечния переменным\n a0=a1=a2=np.nan \n #вводим кадастровый номер в поле поиска и нажимаем Enter\n wait_element('//*[@id=\"search_main\"]').send_keys(str(llist[i]),Keys.RETURN) \n #используем функцию ожидания до тех пор пока не исчезнет таймер поиска\n while driver.find_element_by_xpath('//*[@id=\"table_search_timer\"]').is_displayed():\n time.sleep(1) \n else: \n #если совпадений не найдено, вывести сообщение\n if driver.find_element_by_xpath('//div[@class=\"table_search_not-title\"]').text \\\n =='Совпадений не найдено... Что делать?':\n print('table_search_not') \n #иначе\n else: \n print('table_search')\n try:\n #нажать на кнопку выбрать у проверяемого объекта\n wait_element('//a[contains(@href,\"/kadastr/\")] \\\n /div[@class=\"table__btn\"]').click() \n #задать переменной тип объекта\n a0=wait_element_text('//div[@class=\"test__data\"] \\\n /div[contains(text(),\"Тип\")]/strong') \n #задать переменной кадастрвый номер объекта\n a1=wait_element_text('//div[@class=\"test__data\"] \\\n /div[contains(text(),\"Кадастровый номер\")]/strong') \n #задать переменной адрес объекта\n a2=wait_element_text('//div[@class=\"test__data\"] \\ \n /div[contains(text(),\"Адрес полный\")]/strong') \n print(i,a0,a1,a2)\n except:\n print('no buton')\n #создать временную таблицу из набора переменных\n df_temp=pd.DataFrame([llist[i],a0,a1,a2]).transpose() \n #добавить временную таблицу в основную таблицу\n df=df.append(df_temp) \n#по завершению цикла закрыть браузер\ndriver.close() \n#сохранит результат в электронную таблицу \ndf.to_excel('result.xlsx', index=None)","lang":""}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

Результат в виде наборов параметров (тип, кадастровый номер, и адрес объекта недвижимости) сохраняется в таблицу result.xlsx.

"}},{"type":"text","cover":false,"hidden":false,"anchor":"","data":{"text":"

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

"}}],"summaryContent":null,"isExistSummaryContent":false,"warningFromEditor":null,"warningFromEditorTitle":null,"counters":{"comments":0,"favorites":6,"reposts":0,"views":0,"hits":2528,"reads":null,"online":0},"dateFavorite":0,"hitsCount":2528,"isCommentsEnabled":true,"isLikesEnabled":true,"isRemovedByUserRequest":false,"isFavorited":false,"isPinned":false,"repostId":null,"repostData":null,"subscribedToTreads":false,"isEditorial":false,"isAudioAvailable":false,"audioUrl":null,"isAudioAvailableToGenerate":false,"commentEditor":{"enabled":true,"who":null,"text":"","until":null,"reason":null,"type":"everybody"},"isBlur":false,"isPublished":true,"isDisabledAd":false,"withheld":[],"ogTitle":null,"ogDescription":null,"url":"https://vc.ru/id447345/125905-ispolzovanie-parsera-dlya-polucheniya-informacii-iz-otkrytyh-istochnikov-proverki-informacii","author":{"id":447345,"name":"NTA","nickname":null,"description":null,"uri":"","avatar":{"type":"image","data":{"uuid":"e7175678-aaab-09f8-0271-7b3af7ac4670","width":1207,"height":1207,"size":83090,"type":"jpg","color":"e3ebf8","hash":"","external_service":[]}},"cover":{"cover":{"type":"image","data":{"uuid":"8575b55d-a1f0-53ee-9ad6-78268f9ea45c","width":1280,"height":373,"size":56005,"type":"jpg","color":"b0b9ca","hash":"","external_service":[]}},"cover_y":0},"achievements":[{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":4980908,"userId":447345,"count":0,"shareImage":"https://api.vc.ru/achievements/share/4980908"},{"title":"3 года на vc.ru","code":"registration_3_years","description":"Провёл 3 года вместе с vc.ru. Получена 23 июля 2025.","previewUuid":"d9d72ac5-bcb5-55e0-8c72-b99251e5cdd9","formats":{"glb":"https://static.vc.ru/achievements/shark.glb","usdz":"https://static.vc.ru/achievements/shark.usdz"},"viewData":{"contentColor":"#8E6F09","textMaxWidth":0.66796875,"textX":0.5205078125,"textY":0.341796875,"logoX":0.5205078125,"logoY":0.4609375,"logoXNoText":0.5,"logoYNoText":0.3662109375},"id":1356821,"userId":447345,"count":0,"shareImage":"https://api.vc.ru/achievements/share/1356821"},{"title":"5 лет на vc.ru","code":"registration_5_years","description":"Провёл 5 лет вместе с vc.ru. Получена 23 июля 2025.","previewUuid":"a9140d54-73b8-5f40-afa8-449fbaafd42b","formats":{"glb":"https://static.vc.ru/achievements/whale.glb","usdz":"https://static.vc.ru/achievements/whale.usdz"},"viewData":{"contentColor":"#8E6F09","textMaxWidth":0.66796875,"textX":0.533203125,"textY":0.658203125,"logoX":0.533203125,"logoY":0.77734375,"logoXNoText":0.4375,"logoYNoText":0.66015625},"id":130113,"userId":447345,"count":0,"shareImage":"https://api.vc.ru/achievements/share/130113"}],"lastModificationDate":1765058067,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"subsite":{"id":447345,"name":"NTA","nickname":null,"description":null,"uri":"","avatar":{"type":"image","data":{"uuid":"e7175678-aaab-09f8-0271-7b3af7ac4670","width":1207,"height":1207,"size":83090,"type":"jpg","color":"e3ebf8","hash":"","external_service":[]}},"cover":{"cover":{"type":"image","data":{"uuid":"8575b55d-a1f0-53ee-9ad6-78268f9ea45c","width":1280,"height":373,"size":56005,"type":"jpg","color":"b0b9ca","hash":"","external_service":[]}},"cover_y":0},"achievements":[{"title":"Год на vc.ru","code":"registration_1_year","description":"Первый год с vc.ru. Получена 24 июля 2025.","previewUuid":"0d11c244-49de-50e7-894e-b9b27945d42b","formats":{"glb":"https://static.vc.ru/achievements/fish.glb","usdz":"https://static.vc.ru/achievements/fish.usdz"},"viewData":{"contentColor":"#C67AA3","textMaxWidth":0.634765625,"textX":0.5888671875,"textY":0.54296875,"logoX":0.5859375,"logoY":0.6669921875,"logoXNoText":0.6044921875,"logoYNoText":0.5439453125},"id":4980908,"userId":447345,"count":0,"shareImage":"https://api.vc.ru/achievements/share/4980908"},{"title":"3 года на vc.ru","code":"registration_3_years","description":"Провёл 3 года вместе с vc.ru. Получена 23 июля 2025.","previewUuid":"d9d72ac5-bcb5-55e0-8c72-b99251e5cdd9","formats":{"glb":"https://static.vc.ru/achievements/shark.glb","usdz":"https://static.vc.ru/achievements/shark.usdz"},"viewData":{"contentColor":"#8E6F09","textMaxWidth":0.66796875,"textX":0.5205078125,"textY":0.341796875,"logoX":0.5205078125,"logoY":0.4609375,"logoXNoText":0.5,"logoYNoText":0.3662109375},"id":1356821,"userId":447345,"count":0,"shareImage":"https://api.vc.ru/achievements/share/1356821"},{"title":"5 лет на vc.ru","code":"registration_5_years","description":"Провёл 5 лет вместе с vc.ru. Получена 23 июля 2025.","previewUuid":"a9140d54-73b8-5f40-afa8-449fbaafd42b","formats":{"glb":"https://static.vc.ru/achievements/whale.glb","usdz":"https://static.vc.ru/achievements/whale.usdz"},"viewData":{"contentColor":"#8E6F09","textMaxWidth":0.66796875,"textX":0.533203125,"textY":0.658203125,"logoX":0.533203125,"logoY":0.77734375,"logoXNoText":0.4375,"logoYNoText":0.66015625},"id":130113,"userId":447345,"count":0,"shareImage":"https://api.vc.ru/achievements/share/130113"}],"lastModificationDate":1765058067,"isSubscribed":false,"isSubscribedToNewPosts":false,"isMuted":false,"isAvailableForMessenger":true,"badgeId":null,"isDonationsEnabled":false,"isPlusGiftEnabled":true,"isUnverifiedBlogForCompanyWithoutPro":true,"isRemovedByUserRequest":false,"isFrozen":false,"isDisabledAd":false,"isPlus":false,"isVerified":false,"isPro":false,"yandexMetricaId":null,"badge":null,"isOnline":false,"tgChannelShortname":null,"isUnsubscribable":true,"type":1,"subtype":"personal_blog"},"reactions":{"counters":[{"id":1,"count":3}],"reactionId":0},"isNews":false,"source":null,"clusters":[],"donations":{"amount":0,"isDonated":false},"commentsSeenCount":null}}],"ogTitle":null,"ogDescription":null,"isAnonymized":true}};