{"componentChunkName":"component---src-templates-category-js","path":"/workshops/index.html","result":{"pageContext":{"pageParameters":{"isPreview":false,"isMirror":true,"delay_to_show_donate_popup_seconds":7,"about_page":false,"games_page":true,"games_page_link_in_header":false,"donate_popup_show_ru":true,"donate_popup_title_ru":"Без вас — нас не будет","donate_popup_content_ru":"Помогите нам добывать и рассказывать важные истории. Участие каждого — важно!","donate_popup_show_en":true,"donate_popup_title_en":"We can’t do it alone!","donate_popup_content_en":"Help us uncover and share the stories that matter. Every contribution makes a difference","display_regular_donors_banner":false,"showPatreonMethod":true,"useNewMaterialDonationBanner":true,"new_donations_page_design":true,"donations_popup_variants":{"ru":[{"id":"kc19b","title":"Сохраните журналистику для людей в России ","subtitle":"Читают нас прежде всего люди в России, но будущее «Важных историй» зависит от тех, кто живет за пределами страны. Поддержите нас ежемесячным донатом — сохраните независимую журналистику для ваших близких, которые остаются в России.","is_active":true,"background":"linear-gradient(10deg, #421f20 5%, #994146)"},{"id":"33tc9","title":"У пропаганды есть миллиарды из бюджета. У нас — только вы","subtitle":"Перемены возможны, если независимые от власти журналисты продолжают свою работу день за днем, год за годом. Мы рассказываем важные истории уже шесть лет. Помогите нам продолжать.","is_active":true,"background":"linear-gradient(10deg, #421f20 5%, #994146)"}],"en":[{"id":"nj1py","title":"Important stories don’t tell themselves","subtitle":"Independent journalism comes at a cost. We answer to no owners or advertisers — only to you, our readers.  Your ongoing support allows us to keep exposing the truth. Without you, we won’t be here.","is_active":true,"background":"linear-gradient(10deg, #421f20 5%, #994146)"},{"id":"xdfc1","title":"Help us outlast the Kremlin censorship","subtitle":"Censorship lose to journalism that keeps showing up, year after year. Monthly donors are what make that possible","is_active":true,"background":"linear-gradient(10deg, #421f20 5%, #994146)"},{"id":"ck121","title":"State propaganda has billions to spend. We have only you to rely on","subtitle":"Change happens when independent journalists keep showing up — day after day, year after year. Six years in, we're still showing up. Help us keep going with a monthly donation.","is_active":true,"background":"linear-gradient(10deg, #421f20 5%, #994146)"}]},"feedback_page":true,"donorsCount":0,"showAuthorsRequestAfterMaterial":true,"radioPage":true,"radioExists":{"ru":true,"en":false},"singlePlaylistPath":{"ru":"/radio/2025/12/22/razgovori-ovazhnikh/index.html"},"with_bookmarks":true,"news_feed":true,"news_feed_skeleton":false,"news_page_redesign":true,"with_topics":true,"materials_topics":false,"topics_page":true,"with_pdf_share":false,"with_native_share":false,"preferred_source_page":true,"charon_new_form":true,"preferred_source_promos":true,"charon_en_page":true},"materials":[{"id":8286,"header":"Стажировка в дата-отделе «Важных историй». Набор закрыт","_path":"/workshops/2025/09/29/stazhirovka-v-data-otdele-vazhnikh-istorii-nabor-otkrit/","lead":"Дедлайн: 10 октября 2025","entry_image":[],"entry_image_credit":"","created_at_date":"2025-09-29","created_at_date_time":"2025-09-29T15:14:51.015Z","updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[],"external_authors_list":[{"id":78,"first_name":"Дата-отдел","last_name":" ","first_name_en":null,"last_name_en":null,"company":"Важные истории","company_en":null,"company_link":null,"ordering":1}],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Год назад дата-отдел «Важных историй» провел первый сезон стажировок. Пять стажеров полгода работали под руководством журналисток нашего дата-отдела, выпустили исследования, которые цитировались другими СМИ, а результатом одного из них стали санкции.\n\nХотите научиться делать также? Присоединяйтесь к новому потоку стажеров!\n\nОтправить заявку\n\nЧто ждет стажеров: \n16 недель (с перерывом на новогодние праздники) работы бок о бок с дата-журналистами «Важных историй»;\nстажировка будет занимать у вас около 10 часов в неделю, из которых 1 час — еженедельная планерка;\nсерия онлайн мастер-классов, чтобы лучше разобраться в работе с данными и программировании;\nпубликация в «Важных историях»: мы рассчитываем, что за время стажировки вы выпустите одно исследование и одну новость на данных;\nгонорары за опубликованные истории.\n\nИ главное: практика, практика, практика!\n\nУсловия для заявки на участие: \nвы не в России («Важные истории» объявлены «нежелательной организацией», мы не хотим подвергать риску тех, кто находится в РФ).\nопыт в журналистике — от года.\nна базовом уровне умеете работать с данными и не боитесь Google Sheets.\n\nЕсли это вы — отправляйте заявку на участие. И, возможно, одно из 5 стажерских мест — ваше!\n\nДедлайн для заявки: 10 октября 2025","blocks":[{"data":"Год назад дата-отдел «Важных историй» провел первый сезон стажировок. Пять стажеров полгода работали под руководством журналисток нашего дата-отдела, выпустили исследования, которые цитировались другими СМИ, а результатом одного из них стали санкции.","type":"p","className":""},{"data":"Хотите научиться делать также? Присоединяйтесь к новому потоку стажеров!","type":"p","className":""},{"data":"<a href=\"https://forms.gle/rDFT6r7E2RP79edr6\" data-type=\"usual\" target=\"_blank\"><strong>Отправить заявку</strong></a>","type":"p","className":""},{"data":"<strong>Что ждет стажеров:&nbsp;</strong>","type":"p","className":""},{"data":"<li>16 недель (с перерывом на новогодние праздники) работы бок о бок с дата-журналистами «Важных историй»;</li><li>стажировка будет занимать у вас около 10 часов в неделю, из которых 1 час — еженедельная планерка;</li><li>серия онлайн мастер-классов, чтобы лучше разобраться в работе с данными и программировании;</li><li>публикация в «Важных историях»: мы рассчитываем, что за время стажировки вы выпустите одно исследование и одну новость на данных;</li><li>гонорары за опубликованные истории.</li>","type":"ul","className":""},{"data":"И главное: практика, практика, практика!","type":"p","className":""},{"data":"<strong>Условия для заявки на участие:</strong>&nbsp;","type":"p","className":""},{"data":"<li>вы не в России («Важные истории» объявлены «нежелательной организацией», мы не хотим подвергать риску тех, кто находится в РФ).</li><li>опыт в журналистике — от года.</li><li>на базовом уровне умеете работать с данными и не боитесь Google Sheets.</li>","type":"ul","className":""},{"data":"Если это вы — <a href=\"https://forms.gle/rDFT6r7E2RP79edr6\" data-type=\"usual\" target=\"_blank\">отправляйте заявку на участие</a>. И, возможно, одно из 5 стажерских мест — ваше!","type":"p","className":""},{"data":"<strong>Дедлайн для заявки: 10 октября 2025</strong>","type":"p","className":""}]},{"id":453,"header":"Система контроля версий Git. Урок 4","_path":"/workshops/2022/02/18/sistema-kontrolya-versii-git-urok-4/","lead":"Разбираем команду git pull и механизм Pull request","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/bd16d73cfba94a0cab300d77bcb66dd0-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2022-02-18","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":2517,"last_name":"","first_name":"Редакция","last_name_en":"","first_name_en":"Editors","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Мы продолжаем изучать систему контроля версий git. Сегодня разбираемся, как организовать совместную работу над проектом с вашими коллегами.\n\nGit pull\n\nПодключить новых участников к вашему репозиторию можно в меню Settings → Collaborators → Add People.\n\nМы можем добавлять других участников по их email или никнеймам. Когда они примут наше приглашение, они смогут вносить изменения в проект.\n\n\n\n\nСымитируем компьютер другого человека, создав вторую папку на нашем компьютере. Назовем ее «Второй участник». Открываем терминал по адресу папки, копируем ссылку на репозиторий на git hub.\n\n\n  \nКлонируем репозиторий по ссылке: git clone <ссылка на репозиторий>. \nПроверим, как называется появившаяся папка с репозиторием: ls. \nЗаходим в нее: cd git_tutorial. \n\nВключаем отображение веток в терминале: source ~/.zchrc. Подробнее про отображение веток мы рассказывали в прошлом уроке. \n\n\n\n\nПредставим, что второй участник решил внести изменения. Он открыл файл в редакторе и добавил в начало кода импорт библиотеки datetime: from datetime import datetime.  А последней строкой настроил вывод даты: print(\"Today: \", datetime.today().strftime('%d/%m/%Y'))\n\nОн коммитит изменения в терминале: git commit -a -m \"Add datetime\".\nЗаливает их на Github: git push.\n\n\n\n\nПредставим, что мы не знаем, что такие изменения были внесены, и продолжаем работать над проектом локально. Открываем проект в редакторе, добавляем одну строку:  print(\"Our project: Git_Tutorial\").\n\n\nОткрываем терминал по адресу нашей основной папки Git_Tutorial, в которой начинали работать над проектом. Коммитим изменения: git commit -a -m \"Project name\".\n\nПытаемся передать изменения на удаленный репозиторий: git push. Не получается. Git пишет, что версия проекта на нашем компьютере не совпадает с версией на удаленном репозитории. Так получилось, потому что другой участник проекта уже внес какие-то изменения. \n\n\n\n\nЧтобы синхронизировать локальную версию с удаленной, git предлагает команду git pull. Применяем ее: git pull. \n\nВидим сообщение о конфликте в файле test.py. \n\n\nЧтобы разрешить конфликт, переходим в редактор. Зеленым подсвечены наши изменения, синим — изменения, которые добавил в проект кто-то другой. \n\n\nVSCode предлагает несколько вариантов, в каком виде сохранить код. В нашей ситуации нам подходит принять все изменения. Выбираем accept both changes. Сохраняем изменения в редакторе.\n\nКоммитим изменения в терминале: git commit -a -m \"Add project name\". Отправляем на GitHub: git push.\n\nIssues\nКогда мы работаем в команде, удобно, когда каждый участник понимает, что происходит с кодом и кто какие изменения собирается вносить. Обсуждать развитие проекта, указывать на ошибки в коде, предлагать улучшения удобно во вкладке issues. \n\nСоздадим вкладку issue, чтобы обсуждать изменения в проекте с другими участниками. Нажимаем на зеленую кнопку, пишем название: delete input. Добавляем описание: предлагаю убрать input и переписать первую строку вывода, чтобы не вводить имя каждый раз. Здесь используется тот же язык markdown, как и в файле с описанием проекта README.\n\n\n\n\nВ описании можем ссылаться на конкретных людей и на конкретные коммиты, для этого нужно использовать их хэш-код. Можно сослаться и на  куски кода. Зайдем в наш файл test.py и выберем строку с запросом информации с клавиатуры, который нам кажется неудобным. Нажмем на три точки рядом с выделенными строками, копируем permalink. Вставим ссылку в issue. \n\n\n\n\nПосмотрим в режиме предпросмотре, как выглядит наш Issue. Если все устраивает, можем нажать submit.\n\nAssignees — на кого назначаем вопрос. Можем выбрать любого участника проекта. В нашем проекте пока только мы, поэтому задача назначится на нас. Если вы назначили задачу на кого-то другого, он увидит уведомление об этом на своей странице Git Hub. \n\nLabel — тема нашего issue. Выберем bug. Labels можно настроить под себя. \n\n\n\n\nProject и milestones — проекты и вехи. В рамках одного большого репозитория может быть несколько проектов и вех. Разные issue можно привязывать к этим вехам и проектам. Сейчас мы этот шаг пропускаем.\n \nСоздаем issue.\n\nPull Requests\nВ командной работе удобно объединять изменения не на локальном репозитории каждого участника, а на удаленном. Для этого существует функция Pull Request, то есть запрос на изменения. Работа выстраивается так: хотим добавить изменения — создаем в проекте на нашем компьютере ветку, в ветке вносим изменения, коммитим их, отправляем запрос на принятие этих изменений на сервер.  \n\nПредложенные изменения можно обсудить с другими участниками проекта в комментариях. Если с изменениями все согласны, запрос принимается. \n\nПредставим, что и мы решили исправить код, как написано в Issue. Откроем терминал. Создадим ветку для изменений del_input и перейдем в нее: git checkout -b del_input.\n\nПерейдем в редактор и удалим input, изменим приветствие. Сохраним изменения. \n\nВернемся в терминал и закоммитим изменения: git commit -a -m \"Delete input\". Отправим изменения на сервер. Так как мы отправляем изменения не с основной ветки, обязательно прописать название удаленного репозиторий (origin) и название ветки, с которой отправляем изменения: git push -u origin del_input. Ветка с изменениями появилась на GitHub.\n\nВнесем еще одно изменение. Вернемся в основную ветку: git checkout main. Создадим новую ветку update_test: git checkout -b update_test. \n\nПерейдем в редактор и внесем новые изменения, сохраним их.\n\nВернемся в терминал и закоммитим изменения: git commit -a -m \"Update test\".\n\nОтправим изменения на сервер: git push -u origin update_test.\n\nКак только в удаленном репозитории появляется больше одной ветки, Git Hub предлагает объединить изменения из разных веток с помощью функции Pull Request. \n\n\n\n\nНажимаем compare and pull request. Base — куда мы переносим изменения, compare — откуда. Сначала заберем изменения из ветки del_input в main. Git Hub сам проверяет можно ли сделать слияние без конфликтов и помечает их галочкой. Если видим галочку, значит можно слить ветки без конфликтов. \n\nМожем добавить какое-то описание к слиянию веток, reviewers — участники команды, которым мы даем доступ к этому pull request. Они могут просматривать его и комментировать. В Assignees можем указать, кому именно адресуем запрос на изменения. \n\nСейчас мы это пропустим и нажмем create pull request. \n\n\n\n\nНажав на сообщение о коммите, мы можем посмотреть, какие именно изменения предлагаются. Если у нас есть права на подтверждение pull request, мы можем слить две ветки сразу. Сольем две ветки: нажимаем merge pull request. \n\n\n\n\nТеперь код попал в основную ветку. Ветку, которую мы создавали для изменений можно удалить. \n\nМы можем не сливать ветки сразу, а дождаться обсуждения с другими участниками проекта. Тогда Pull request будет висеть в соответствующей вкладке.\n\nПопробуем теперь добавить ветку update_test. Нажимаем compare and pull request. \n\nВетки автоматически не сливаются, возник конфликт. Все равно создаем запрос на изменения. Решить конфликт можно на странице GitHub. Нажимаем resolve conflict. \n\n\n\nПриводим код к нужному виду. Нажимаем mark as resolved → commit merge. Теперь ветки можно слить. Все изменения добавятся в основную ветку.\n\nЕсли возникают ошибки, попробуйте найти решение в интернете. Часто достаточно вбить код ошибки в поисковик и уже в одной из первых ссылок будет решение. Если все же не получается найти ответ, пишите нам в чате в Telegram.","blocks":[{"data":"&nbsp;Мы продолжаем изучать систему контроля версий git. Сегодня разбираемся, как организовать совместную работу над проектом с вашими коллегами.","type":"p","className":""},{"data":{"id":4096,"data":{"url":"https://www.youtube.com/embed/xDPWFkLX9Z8","text":"съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=xDPWFkLX9Z8","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"<strong>Git pull</strong>","type":"h2","className":""},{"data":"Подключить новых участников к вашему репозиторию можно в меню Settings → Collaborators → Add People.","type":"p","className":""},{"data":"Мы можем добавлять других участников по их email или никнеймам. Когда они примут наше приглашение, они смогут вносить изменения в проект.","type":"p","className":""},{"data":{"id":4097,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/0ff819dce2ab4f40b2fdbe99b09550fd-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/0ff819dce2ab4f40b2fdbe99b09550fd-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":570,"real_height_2x":1139},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/0ff819dce2ab4f40b2fdbe99b09550fd-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/0ff819dce2ab4f40b2fdbe99b09550fd-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":570,"real_height_2x":1139}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Сымитируем компьютер другого человека, создав вторую папку на нашем компьютере. Назовем ее «Второй участник». Открываем терминал по адресу папки, копируем ссылку на репозиторий на git hub.","type":"p","className":""},{"data":{"id":4098,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f57eaa451d8b4bf39f15b31289cb94db-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f57eaa451d8b4bf39f15b31289cb94db-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":667,"real_height_2x":1334},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f57eaa451d8b4bf39f15b31289cb94db-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f57eaa451d8b4bf39f15b31289cb94db-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":667,"real_height_2x":1334}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"  ","type":"p","className":""},{"data":"Клонируем репозиторий по ссылке: <strong>git clone &lt;ссылка на репозиторий&gt;</strong>. ","type":"p","className":""},{"data":"Проверим, как называется появившаяся папка с репозиторием:<strong> ls</strong>. ","type":"p","className":""},{"data":"Заходим в нее:<strong> cd git_tutorial</strong>.&nbsp;","type":"p","className":""},{"data":"Включаем отображение веток в терминале: <strong>source ~/.zchrc. </strong>Подробнее про отображение веток мы рассказывали в прошлом <a href=\"https://istories.media/workshops/2022/02/11/sistema-kontrolya-versii-git-urok-3/\" data-type=\"usual\" target=\"_blank\">уроке</a>. ","type":"p","className":""},{"data":{"id":4099,"data":{"images":[{"caption":"Имитируем действия другого участника","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ef997e8ceba844aa872db552e850bc9a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ef997e8ceba844aa872db552e850bc9a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":535,"real_height_2x":1070},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ef997e8ceba844aa872db552e850bc9a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ef997e8ceba844aa872db552e850bc9a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":535,"real_height_2x":1070}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Представим, что второй участник решил внести изменения.&nbsp;Он открыл файл в редакторе и добавил в начало кода импорт библиотеки datetime: <strong>from datetime import datetime</strong>. &nbsp;А последней строкой настроил вывод даты:&nbsp;<strong>print(\"Today: \", datetime.today().strftime('%d/%m/%Y')</strong>)","type":"p","className":""},{"data":"Он коммитит изменения в терминале: <strong>git commit -a -m \"Add datetime\".</strong>","type":"p","className":""},{"data":"Заливает их на Github: <strong>git push</strong>.","type":"p","className":""},{"data":{"id":4100,"data":{"images":[{"caption":"Имитируем действия другого участника","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/509d51eeece946b2b21a60166fffa9e2-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/509d51eeece946b2b21a60166fffa9e2-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":494,"real_height_2x":989},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/509d51eeece946b2b21a60166fffa9e2-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/509d51eeece946b2b21a60166fffa9e2-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":494,"real_height_2x":989}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Представим, что мы не знаем, что такие изменения были внесены, и продолжаем работать над проектом локально. Открываем проект в редакторе, добавляем одну строку: &nbsp;<strong>print(\"Our project: Git_Tutorial\").</strong>","type":"p","className":""},{"data":{"id":4101,"data":{"images":[{"caption":"Работаем с проектом в нашей основной папке","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e2603ac41f034f729fbfd38a7808a28d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e2603ac41f034f729fbfd38a7808a28d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":540,"real_height_2x":1080},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e2603ac41f034f729fbfd38a7808a28d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e2603ac41f034f729fbfd38a7808a28d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":540,"real_height_2x":1080}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Открываем терминал по адресу нашей основной папки Git_Tutorial, в которой начинали работать над проектом. Коммитим изменения: <strong>git commit -a -m \"Project name\".</strong>","type":"p","className":""},{"data":"Пытаемся передать изменения на удаленный репозиторий: <strong>git push</strong>. Не получается. Git пишет, что версия проекта на нашем компьютере не совпадает с версией на удаленном репозитории. Так получилось, потому что другой участник проекта уже внес какие-то изменения.&nbsp;","type":"p","className":""},{"data":{"id":4102,"data":{"images":[{"caption":"Работаем с проектом из нашей основной папки","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9064e9dbcde94bc784f1173625a62256-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9064e9dbcde94bc784f1173625a62256-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":514,"real_height_2x":1028},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9064e9dbcde94bc784f1173625a62256-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9064e9dbcde94bc784f1173625a62256-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":514,"real_height_2x":1028}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы синхронизировать локальную версию с удаленной, git предлагает команду git pull. Применяем ее: <strong>git pull</strong>.&nbsp;","type":"p","className":""},{"data":"Видим сообщение о конфликте в файле test.py. ","type":"p","className":""},{"data":{"id":4103,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/750b7451f6ce4726993069526bebea50-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/750b7451f6ce4726993069526bebea50-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":658,"real_height_2x":1316},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/750b7451f6ce4726993069526bebea50-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/750b7451f6ce4726993069526bebea50-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":658,"real_height_2x":1316}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы разрешить конфликт, переходим в редактор. Зеленым подсвечены наши изменения, синим — изменения, которые добавил в проект кто-то другой. ","type":"p","className":""},{"data":{"id":4104,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/27ab8cc1880c488ba0058d4b00363f57-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/27ab8cc1880c488ba0058d4b00363f57-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":532,"real_height_2x":1063},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/27ab8cc1880c488ba0058d4b00363f57-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/27ab8cc1880c488ba0058d4b00363f57-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":532,"real_height_2x":1063}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"VSCode предлагает несколько вариантов, в каком виде сохранить код. В нашей ситуации нам подходит принять все изменения. Выбираем accept both changes. Сохраняем изменения в редакторе.","type":"p","className":""},{"data":"Коммитим изменения в терминале: <strong>git commit -a -m \"Add project name\".</strong> Отправляем на GitHub: <strong>git push</strong>.","type":"p","className":""},{"data":"<strong>Issues</strong>","type":"h2","className":""},{"data":"Когда мы работаем в команде, удобно, когда каждый участник понимает, что происходит с кодом и кто какие изменения собирается вносить. Обсуждать развитие проекта, указывать на ошибки в коде, предлагать улучшения удобно во вкладке issues.&nbsp;","type":"p","className":""},{"data":"Создадим вкладку issue, чтобы обсуждать изменения в проекте с другими участниками. Нажимаем на зеленую кнопку, пишем название:&nbsp;delete input. Добавляем описание: предлагаю убрать input и переписать первую строку вывода, чтобы не вводить имя каждый раз. Здесь используется тот же язык markdown, как и в файле с описанием проекта README.","type":"p","className":""},{"data":{"id":4105,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/0e9626d9a1ad410c983ef8cd0ec48886-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/0e9626d9a1ad410c983ef8cd0ec48886-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":534,"real_height_2x":1070},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/0e9626d9a1ad410c983ef8cd0ec48886-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/0e9626d9a1ad410c983ef8cd0ec48886-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":534,"real_height_2x":1070}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В описании можем ссылаться на конкретных людей и на конкретные коммиты, для этого нужно использовать их хэш-код. Можно сослаться и на  куски кода. Зайдем в наш файл test.py и выберем строку с запросом информации с клавиатуры, который нам кажется неудобным. Нажмем на три точки рядом с выделенными строками, копируем permalink. Вставим ссылку в issue.&nbsp;","type":"p","className":""},{"data":{"id":4106,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/6d464a5131da4855b06cb2ef4b48c7f1-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/6d464a5131da4855b06cb2ef4b48c7f1-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":589,"real_height_2x":1178},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/6d464a5131da4855b06cb2ef4b48c7f1-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/6d464a5131da4855b06cb2ef4b48c7f1-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":589,"real_height_2x":1178}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Посмотрим в режиме предпросмотре, как выглядит наш Issue. Если все устраивает, можем нажать submit.","type":"p","className":""},{"data":"Assignees — на кого назначаем вопрос. Можем выбрать любого участника проекта. В нашем проекте пока только мы, поэтому задача назначится на нас. Если вы назначили задачу на кого-то другого, он увидит уведомление об этом на своей странице Git Hub.&nbsp;","type":"p","className":""},{"data":"Label — тема нашего issue. Выберем bug. Labels можно настроить под себя.&nbsp;","type":"p","className":""},{"data":{"id":4107,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ff3fad702e6a4a83a7a5db5fbcfdff83-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ff3fad702e6a4a83a7a5db5fbcfdff83-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1098,"real_height_2x":2196},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ff3fad702e6a4a83a7a5db5fbcfdff83-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ff3fad702e6a4a83a7a5db5fbcfdff83-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1098,"real_height_2x":2196}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Project и milestones — проекты и вехи. В рамках одного большого репозитория может быть несколько проектов и вех. Разные issue можно привязывать к этим вехам и проектам. Сейчас мы этот шаг пропускаем.","type":"p","className":""},{"data":"&nbsp;","type":"p","className":""},{"data":"Создаем issue.","type":"p","className":""},{"data":"<strong>Pull Requests</strong>","type":"h2","className":""},{"data":"В командной работе удобно объединять изменения не на локальном репозитории каждого участника, а на удаленном. Для этого существует функция Pull Request, то есть запрос на изменения. Работа выстраивается так: хотим добавить изменения — создаем в проекте на нашем компьютере ветку, в ветке вносим изменения, коммитим их, отправляем запрос на принятие этих изменений на сервер.&nbsp;&nbsp;","type":"p","className":""},{"data":"Предложенные изменения можно обсудить с другими участниками проекта в комментариях. Если с изменениями все согласны, запрос принимается.&nbsp;","type":"p","className":""},{"data":"Представим, что и мы решили исправить код, как написано в Issue.&nbsp;Откроем терминал. Создадим ветку для изменений del_input и перейдем в нее: <strong>git checkout -b del_input</strong>.","type":"p","className":""},{"data":"Перейдем в редактор и удалим input, изменим приветствие. Сохраним изменения.&nbsp;","type":"p","className":""},{"data":"Вернемся в терминал и закоммитим изменения:<strong> git commit -a -m \"Delete input\"</strong>. Отправим изменения на сервер. Так как мы отправляем изменения не с основной ветки, обязательно прописать название удаленного репозиторий (origin) и название ветки, с которой отправляем изменения: <strong>git push -u origin del_input</strong>. Ветка с изменениями появилась на GitHub.","type":"p","className":""},{"data":"Внесем еще одно изменение. Вернемся в основную ветку: <strong>git checkout main</strong>. Создадим новую ветку update_test: <strong>git checkout -b update_test</strong>. ","type":"p","className":""},{"data":"Перейдем в редактор и внесем новые изменения, сохраним их.","type":"p","className":""},{"data":"Вернемся в терминал и закоммитим изменения: <strong>git commit -a -m \"Update test\"</strong>.","type":"p","className":""},{"data":"Отправим изменения на сервер: <strong>git push -u origin update_test</strong>.","type":"p","className":""},{"data":"Как только в удаленном репозитории появляется больше одной ветки, Git Hub предлагает объединить изменения из разных веток с помощью функции Pull Request.&nbsp;","type":"p","className":""},{"data":{"id":4108,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ec473a0d720741d3a2f6ab64cfcdc2a7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ec473a0d720741d3a2f6ab64cfcdc2a7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":715,"real_height_2x":1430},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ec473a0d720741d3a2f6ab64cfcdc2a7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ec473a0d720741d3a2f6ab64cfcdc2a7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":715,"real_height_2x":1430}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Нажимаем compare and pull request. Base — куда мы переносим изменения, compare — откуда. Сначала заберем изменения из ветки del_input в main. Git Hub сам проверяет можно ли сделать слияние без конфликтов и помечает их галочкой. Если видим галочку, значит можно слить ветки без конфликтов.&nbsp;","type":"p","className":""},{"data":"Можем добавить какое-то описание к слиянию веток, reviewers — участники команды, которым мы даем доступ к этому pull request. Они могут просматривать его и комментировать. В Assignees можем указать, кому именно адресуем запрос на изменения.&nbsp;","type":"p","className":""},{"data":"Сейчас мы это пропустим и нажмем create pull request.&nbsp;","type":"p","className":""},{"data":{"id":4109,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bccf03c58a0d4509aa1fea265f3a0046-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bccf03c58a0d4509aa1fea265f3a0046-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":497,"real_height_2x":994},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bccf03c58a0d4509aa1fea265f3a0046-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/bccf03c58a0d4509aa1fea265f3a0046-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":497,"real_height_2x":994}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Нажав на сообщение о коммите, мы можем посмотреть, какие именно изменения предлагаются. Если у нас есть права на подтверждение pull request, мы можем слить две ветки сразу. Сольем две ветки: нажимаем merge pull request. ","type":"p","className":""},{"data":{"id":4110,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/58c2a757393c4df1b947a1d804996384-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/58c2a757393c4df1b947a1d804996384-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":618,"real_height_2x":1236},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/58c2a757393c4df1b947a1d804996384-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/58c2a757393c4df1b947a1d804996384-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":618,"real_height_2x":1236}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь код попал в основную ветку. Ветку, которую мы создавали для изменений можно удалить.&nbsp;","type":"p","className":""},{"data":"Мы можем не сливать ветки сразу, а дождаться обсуждения с другими участниками проекта. Тогда Pull request будет висеть в соответствующей вкладке.","type":"p","className":""},{"data":"Попробуем теперь добавить ветку update_test. Нажимаем compare and pull request. ","type":"p","className":""},{"data":"Ветки автоматически не сливаются, возник конфликт. Все равно создаем запрос на изменения. Решить конфликт можно на странице GitHub. Нажимаем resolve conflict. ","type":"p","className":""},{"data":{"id":4111,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d615ec40acd44761a57b5edbe64395aa-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d615ec40acd44761a57b5edbe64395aa-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":733,"real_height_2x":1466},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/d615ec40acd44761a57b5edbe64395aa-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/d615ec40acd44761a57b5edbe64395aa-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":733,"real_height_2x":1466}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Приводим код к нужному виду.&nbsp;Нажимаем mark as resolved → commit merge. Теперь ветки можно слить. Все изменения добавятся в основную ветку.","type":"p","className":""},{"data":"Если возникают ошибки, попробуйте найти решение в интернете. Часто достаточно вбить код ошибки в поисковик и уже в одной из первых ссылок будет решение. Если все же не получается найти ответ, пишите нам в <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">чате</a> в Telegram.","type":"p","className":""}]},{"id":450,"header":"Система контроля версий Git. Урок 3","_path":"/workshops/2022/02/11/sistema-kontrolya-versii-git-urok-3/","lead":"Учимся работать с ветками","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2022-02-11","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":2517,"last_name":"","first_name":"Редакция","last_name_en":"","first_name_en":"Editors","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Мы продолжаем курс по системе контроля версий git. Сегодня разберемся, как работать с ветками. Ветки позволяют работать над кодом так, чтобы на время разработки, основная версия проекта оставалась без изменений.\n\nПредставьте, что у вас есть код, который работает. В какой-то момент вы решили добавить в него изменения. Работа над изменениями может занять некоторое время, в какой-то момент код может даже перестать работать. А вам нужно, чтобы в любой момент можно было воспользоваться рабочей версией проекта. В таких ситуациях могут помочь ветки. \n\n\n\nКак настроить отображение веток\n\nGit изначально настроен на работу с ветками. Когда мы создавали репозиторий, у нас автоматически появилась ветка main, в которую и коммитились все наши изменения. Важно всегда понимать, в какой ветке мы сейчас находимся. В git для этого есть понятие current branch. \n\nОткроем терминал по адресу нашей папки. На Windows вы сразу увидите, в какой ветке находитесь. На mac это нужно настроить. \nСоздадим файл: touch ~/.zchrc.\nОткроем ее: open ~/.zchrc.\nВведем в открывшийся редактор кусок кода:\n\nfunction parse_git_branch() {\n    git branch 2> /dev/null | sed -n -e 's/^\\* \\(.*\\)/[\\1]/p'\n}\n\nCOLOR_DEF=$'\\e[0m'\nCOLOR_USR=$'\\e[38;5;243m'\nCOLOR_DIR=$'\\e[38;5;197m'\nCOLOR_GIT=$'\\e[38;5;39m'\nsetopt PROMPT_SUBST\nexport PROMPT='${COLOR_USR}%n ${COLOR_DIR}%~ ${COLOR_GIT}$(parse_git_branch)${COLOR_DEF} $ '\n\n\nСохраним изменения в файле и вернемся в терминал. \nВводим команду source ~/.zchrc. Обозначение ветки появилось.\nКогда в следующий раз будем открывать терминал, достаточно ввести только последнюю команду. \n\n\n\nКак создать ветку в Git\n\nПредставим, что мы хотим добавить в код input, чтобы пользователь вводил свое имя с клавиатуры. Пробовать изменения мы будем в отдельной ветке. \nСоздать новую ветку можно с помощью команды git branch <название ветки>. Важно, чтобы название было понятным для вас и других участников проекта. \nСоздадим новую ветку для проекта: git branch input.\n\nПереключимся на новую ветку с помощью команды git checkout input. (Чтобы создать ветку и переключиться на нее за одно действие, можно воспользоваться флагом -b: git checkout -b <название ветки>.)\n\nВнесем изменения в наш файл в ветке input. Для этого перейдем в редактор. Пусть код запрашивает имя пользователя, а потом здоровается с ним. \nДобавим в начало запрос на ввод: name = input(\"What's your name? \")\nИ изменим первую строку вывода: print(\"Hello, \", name,\"!\")\n\n\n\nПроверим, как работает наш код. Для этого нужно нажать на значок play в верхнем правом углу редактора. Код сначала просит нас ввести имя, а потом выводит нужную информацию. Изменения удались. \n\n\n\n\nЗакоммитим изменения: git commit -a -m “Add input”.\n\nПроверим git status, убедимся, что рабочее дерево чистое. Проверим историю: git log. Видим весь путь работы: последнее изменение и все изменения, которые были еще до ответвления. Чтобы выйти из истории, нужно нажать q в английской раскладке. \n\n\nВернемся в основную ветку с помощью команды git checkout main и зайдем в редактор. Изменения пропали, потому что в основную ветку мы их еще не добавляли. Проверяем историю: git log. В ветке main видим только старые коммиты, до ответвления. \n\n\n\nКак сливать ветки и решать конфликты \n\nКогда мы сделали все нужные изменения в коде, проверили, что они работают так, как мы хотим, можно переносить изменения в основной код. \n\nСначала нужно переключиться на основную ветку: git checkout main.\nТеперь можем забрать изменения из ветки input: git merge --no-ff <название ветки, изменения из которой забираем> -m “Сообщение о слиянии веток”.\n\nТакая команда создаст новый коммит, в котором объединятся две ветки.\n\nФлаг --no-ff отменяет механизм fast-forward, который стоит в git по умолчанию. Если его не отменить, git не будет создавать новый коммит, в котором объединятся две ветки, а просто сделает дополнительную ветку веткой main. Иногда такой механизм полезен, но сейчас он нас запутает, поэтому отключаем его. Вы можете поэкспериментировать и посмотреть, в какой ситуации какой механизм вам больше подходит. \n\nВ нашем случае git понял, как нужно совместить две ветки. Проверим редактор, чтобы убедиться, что результат тот, который нам нужен. \n\n\n\n\nИногда Git не понимает, как именно нужно объединить ветки и выводит сообщение о конфликте. В таких ситуациях, мы должны показать ему это. Для этого переходим в редактор, удаляем лишние символы и приводим код к тому виду, который нам нужен.  Сохраняем файл в редакторе, проверяем git status — увидим сообщение о конфликте. Чтобы показать Git, что мы разрешили конфликт, просто закоммитим изменения: git commit -a -m «Add input in main».\n\nПроверим историю: git log. Если видим сообщение о коммите, в котором сливаются две ветки, значит, все получилось. \n\n\nИсторию изменений, создания новых веток и слияния можно визуализировать: git log --oneline --graph. \nЗвездочкой показан каждый коммит, мы видим, что происходило на каждом шаге, в какой момент появилась новая ветка и что мы в ней делали, в какой момент слили ветки. \n\n\n\n\nКак залить изменения на GitHub\n\nОтправляем изменения на удаленный репозиторий: git push.\n\nПроверяем GitHub. Изменения появились, но залилась только ветка main. Другие ветки нужно заливать отдельно: git push -u origin <название ветки>.\nЗальем ветку input: git push -u origin input. Видим, что на GitHub появились две ветки. Переключиться между ветками можно в меню branch.\n\n\n\nКак перемещаться по коммитам \n \nЕще один важный указатель в git — это head. Он указывает, на какой ветке мы находимся. Если мы перейдем в историю, увидим, что head указывает на ветку main и на удаленную ветку origin_main. Это значит, наш локальный и удаленный репозитории синхронизированы. \nПерейдем на другую ветку командой git checkout input, и в истории head будет указывать уже на input.\n\n\n\n\nМы можем перейти не только на другую ветку, но и на отдельный коммит. Будто перенестись в прошлое и посмотреть, как работал наш код на одном из этапов разработки. Сначала переключимся на основную ветку. \n\nПосмотрим историю изменений: git log --oneline. (Эта команда дает более компактное отображение истории по сравнению с git log.)\n\nПереходим на один из первых коммитов: git checkout <первые символы кода идентификатора>. Head уже будет указывать на отдельный коммит, а в редакторе код тоже вернулся на тот этап. \n\n\n\nС помощью таких перемещений по коммитам, мы можем искать ошибки, понимать, в какой момент код работал хорошо, а с какого этапа что-то пошло не так. Мы можем даже вносить изменения на этом этапе, но для этого нужно создать отдельную ветку. \n\nСоздадим новую ветку и переключимся на нее в одно действие с помощью флага -b: git checkout -b calc. \nДобавим изменения в редактор: допишем строку 2+2. Сохраняем изменения в редакторе. \nДобавим файл в отслеживание и коммитим изменения: git commit -a -m “Add calculation”.\n\nВернемся в основную ветку: git checkout main.  Посмотрим все ветки: git branch. Видим, что появилась новая ветка calc. \n\n\n\nСделаем визуализацию наших изменений:  git log --oneline --graph --all. Видим, что со второго коммита ответвилась еще одна ветка. \n\n\n\nКак удалить ветку в Git \n\nЕсли мы понимаем, что ветка больше не нужна, можно ее удалить.  При этом удаляемая ветка не должна быть той веткой, в которой мы находимся. Удалим ветку calc: git branch -d calc. Git предупреждает, что ветка еще не объединена с основной веткой и что удалять ее опасно. Но мы уверены, что хотим удалить ветку, поэтому вводим еще одну команду, которую нам подсказывает git: git branch -D calc.\n\nТеперь удалим ветку input. Она уже залита на GitHub, поэтому сначала удалим ее с удаленного репозитория: git push --delete origin input\nПроверим Git Hub: ветка удалилась. Теперь удаляем ветку локально: git branch -d input.\n\nПроверим наши ветки: git branch. Ветки удалились, осталась только ветка main.\n\n\n\n\n\nЕсли по ходу работы у вас появляются ошибки, попробуйте найти решение в интернете. Часто достаточно скопировать полученную ошибку и вбить ее в поиск в браузере. Если все же не получается найти ответ, пишите нам в чате в Telegram.","blocks":[{"data":"Мы продолжаем курс по системе контроля версий git. Сегодня разберемся, как работать с ветками. Ветки позволяют работать над кодом так, чтобы на время разработки, основная версия проекта оставалась без изменений.","type":"p","className":""},{"data":"Представьте, что у вас есть код, который работает. В какой-то момент вы решили добавить в него изменения. Работа над изменениями может занять некоторое время, в какой-то момент код может даже перестать работать. А вам нужно, чтобы в любой момент можно было воспользоваться рабочей версией проекта. В таких ситуациях могут помочь ветки. ","type":"p","className":""},{"data":{"id":4027,"data":{"url":"https://www.youtube.com/embed/1HGJHLoDYD8","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=1HGJHLoDYD8","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Как настроить отображение веток","type":"h2","className":""},{"data":"Git изначально настроен на работу с ветками. Когда мы создавали репозиторий, у нас автоматически появилась ветка main, в которую и коммитились все наши изменения. Важно всегда понимать, в какой ветке мы сейчас находимся. В git для этого есть понятие current branch.&nbsp;","type":"p","className":""},{"data":"Откроем терминал по адресу нашей папки. На Windows вы сразу увидите, в какой ветке находитесь. На mac это нужно настроить.&nbsp;","type":"p","className":""},{"data":"Создадим файл: <strong>touch ~/.zchrc.</strong>","type":"p","className":""},{"data":"Откроем ее:<strong> open ~/.zchrc.</strong>","type":"p","className":""},{"data":"Введем в открывшийся редактор кусок кода:","type":"p","className":""},{"data":"<em>function parse_git_branch() {</em>","type":"p","className":""},{"data":"<em>&nbsp;&nbsp;&nbsp;&nbsp;git branch 2&gt; /dev/null | sed -n -e 's/^\\* \\(.*\\)/[\\1]/p'</em>","type":"p","className":""},{"data":"<em>}</em>","type":"p","className":""},{"data":"<em>COLOR_DEF=$'\\e[0m'</em>","type":"p","className":""},{"data":"<em>COLOR_USR=$'\\e[38;5;243m'</em>","type":"p","className":""},{"data":"<em>COLOR_DIR=$'\\e[38;5;197m'</em>","type":"p","className":""},{"data":"<em>COLOR_GIT=$'\\e[38;5;39m'</em>","type":"p","className":""},{"data":"<em>setopt PROMPT_SUBST</em>","type":"p","className":""},{"data":"<em>export PROMPT='${COLOR_USR}%n ${COLOR_DIR}%~ ${COLOR_GIT}$(parse_git_branch)${COLOR_DEF} $ '</em>","type":"p","className":""},{"data":"Сохраним изменения в файле и вернемся в терминал. ","type":"p","className":""},{"data":"Вводим команду <strong>source ~/.zchrc</strong>. Обозначение ветки появилось.","type":"p","className":""},{"data":"Когда в следующий раз будем открывать терминал, достаточно ввести только последнюю команду.&nbsp;","type":"p","className":""},{"data":{"id":4026,"data":{"images":[{"caption":"Добавляем код в открывшийся редактор","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/31ea69018c24419383bdfce142990bd9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/31ea69018c24419383bdfce142990bd9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":425,"real_height_2x":850},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/31ea69018c24419383bdfce142990bd9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/31ea69018c24419383bdfce142990bd9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":425,"real_height_2x":850}]},{"caption":"Наш терминал","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12bd8fdec06a42268f9c7a339fd04268-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12bd8fdec06a42268f9c7a339fd04268-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":460,"real_height_2x":922},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/12bd8fdec06a42268f9c7a339fd04268-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/12bd8fdec06a42268f9c7a339fd04268-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":460,"real_height_2x":922}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Как создать ветку в Git","type":"h2","className":""},{"data":"Представим, что мы хотим добавить в код input, чтобы пользователь вводил свое имя с клавиатуры. Пробовать изменения мы будем в отдельной ветке.&nbsp;","type":"p","className":""},{"data":"Создать новую ветку можно с помощью команды <strong>git branch &lt;название ветки&gt;</strong>. Важно, чтобы название было понятным для вас и других участников проекта.&nbsp;","type":"p","className":""},{"data":"Создадим новую ветку для проекта: <strong>git branch input.</strong>","type":"p","className":""},{"data":"Переключимся на новую ветку с помощью команды <strong>git checkout input.</strong> <em>(Чтобы создать ветку и переключиться на нее за одно действие, можно воспользоваться флагом -b: </em><strong><em>git checkout -b &lt;название ветки&gt;.</em></strong><em>)</em>","type":"p","className":""},{"data":"Внесем изменения в наш файл в ветке input. Для этого перейдем в редактор. Пусть код запрашивает имя пользователя, а потом здоровается с ним.&nbsp;","type":"p","className":""},{"data":"Добавим в начало запрос на ввод: <strong>name = input(\"What's your name? \")</strong>","type":"p","className":""},{"data":"И изменим первую строку вывода: <strong>print(\"Hello, \", name,\"!\")</strong>","type":"p","className":""},{"data":{"id":4028,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/453245c4be6b462faf252da3e7adc40e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/453245c4be6b462faf252da3e7adc40e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":524,"real_height_2x":1049},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/453245c4be6b462faf252da3e7adc40e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/453245c4be6b462faf252da3e7adc40e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":524,"real_height_2x":1049}]},{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/65dffb4146f249b99da3d5d892c5355a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/65dffb4146f249b99da3d5d892c5355a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":498,"real_height_2x":996},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/65dffb4146f249b99da3d5d892c5355a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/65dffb4146f249b99da3d5d892c5355a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":498,"real_height_2x":996}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Проверим, как работает наш код. Для этого нужно нажать на значок play в верхнем правом углу редактора. Код сначала просит нас ввести имя, а потом выводит нужную информацию. Изменения удались. ","type":"p","className":""},{"data":{"id":4031,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ceb46ef9564b4c498fa294ccecbf668f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ceb46ef9564b4c498fa294ccecbf668f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":314,"real_height_2x":630},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ceb46ef9564b4c498fa294ccecbf668f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ceb46ef9564b4c498fa294ccecbf668f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":314,"real_height_2x":630}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Закоммитим изменения: <strong>git commit -a -m “Add input”.</strong>","type":"p","className":""},{"data":"Проверим <strong>git status, </strong>убедимся, что рабочее дерево чистое. Проверим историю: <strong>git log.</strong> Видим весь путь работы: последнее изменение и все изменения, которые были еще до ответвления.&nbsp;Чтобы выйти из истории, нужно нажать <strong>q</strong> в английской раскладке. ","type":"p","className":""},{"data":{"id":4029,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4ce16b3d1c8049e8b1c1b86fe9d3363b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4ce16b3d1c8049e8b1c1b86fe9d3363b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":620,"real_height_2x":1240},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4ce16b3d1c8049e8b1c1b86fe9d3363b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4ce16b3d1c8049e8b1c1b86fe9d3363b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":620,"real_height_2x":1240}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Вернемся в основную ветку с помощью команды <strong>git checkout main</strong> и зайдем в редактор. Изменения пропали, потому&nbsp;что в основную ветку мы их еще не добавляли. Проверяем историю: <strong>git log. </strong>В ветке main видим только старые коммиты, до ответвления.&nbsp;","type":"p","className":""},{"data":{"id":4030,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b5285fb1bb42498c83e885418fa6f242-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b5285fb1bb42498c83e885418fa6f242-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":428,"real_height_2x":856},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b5285fb1bb42498c83e885418fa6f242-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b5285fb1bb42498c83e885418fa6f242-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":428,"real_height_2x":856}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Как сливать ветки и решать конфликты ","type":"h2","className":""},{"data":"Когда мы сделали все нужные изменения в коде, проверили, что они работают так, как мы хотим, можно переносить изменения в основной код.&nbsp;","type":"p","className":""},{"data":"Сначала нужно переключиться на основную ветку:<strong> git checkout main.</strong>","type":"p","className":""},{"data":"Теперь можем забрать изменения из ветки input:&nbsp;<strong>git merge --no-ff&nbsp;&lt;название ветки, изменения из которой забираем&gt; -m “Сообщение о слиянии веток”.</strong>","type":"p","className":""},{"data":"Такая команда создаст новый коммит, в котором объединятся две ветки.","type":"p","className":""},{"data":"Флаг --no-ff отменяет механизм fast-forward, который стоит в git по умолчанию. Если его не отменить, git не будет создавать новый коммит, в котором объединятся две ветки, а просто сделает дополнительную ветку веткой main. Иногда такой механизм полезен, но сейчас он нас запутает, поэтому отключаем его. Вы можете поэкспериментировать и посмотреть, в какой ситуации какой механизм вам больше подходит.&nbsp;","type":"p","className":""},{"data":"В нашем случае git понял, как нужно совместить две ветки. Проверим редактор, чтобы убедиться, что результат тот, который нам нужен. ","type":"p","className":""},{"data":{"id":4032,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/84ed27368d0d4e4485050029ea70e2f2-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/84ed27368d0d4e4485050029ea70e2f2-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":378,"real_height_2x":758},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/84ed27368d0d4e4485050029ea70e2f2-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/84ed27368d0d4e4485050029ea70e2f2-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":378,"real_height_2x":758}]},{"caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a459a563c5ed41869872f386d903e4fd-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a459a563c5ed41869872f386d903e4fd-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":422,"real_height_2x":844},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a459a563c5ed41869872f386d903e4fd-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a459a563c5ed41869872f386d903e4fd-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":422,"real_height_2x":844}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Иногда Git не понимает, как именно нужно объединить ветки и выводит сообщение о конфликте. В таких ситуациях, мы должны показать ему это. Для этого переходим в редактор, удаляем лишние символы и приводим код к тому виду, который нам нужен. &nbsp;Сохраняем файл в редакторе, проверяем <strong>git status</strong> — увидим сообщение о конфликте.&nbsp;Чтобы показать Git, что мы разрешили конфликт, просто закоммитим изменения: <strong>git commit -a -m «Add input in main».</strong>","type":"p","className":""},{"data":"Проверим историю: <strong>git log</strong>. Если видим сообщение о коммите, в котором сливаются две ветки, значит, все получилось. ","type":"p","className":""},{"data":{"id":4033,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9352183cad204ff0880acaff5eaacfc8-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9352183cad204ff0880acaff5eaacfc8-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":463,"real_height_2x":926},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9352183cad204ff0880acaff5eaacfc8-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9352183cad204ff0880acaff5eaacfc8-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":463,"real_height_2x":926}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Историю изменений, создания новых веток и слияния можно визуализировать: <strong>git log --oneline --graph</strong>. ","type":"p","className":""},{"data":"Звездочкой показан каждый коммит, мы видим, что происходило на каждом шаге, в какой момент появилась новая ветка и что мы в ней делали, в какой момент слили ветки. ","type":"p","className":""},{"data":{"id":4034,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7f16090d8d024c139201afd82babe29d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7f16090d8d024c139201afd82babe29d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":448,"real_height_2x":897},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7f16090d8d024c139201afd82babe29d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7f16090d8d024c139201afd82babe29d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":448,"real_height_2x":897}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Как залить изменения на GitHub","type":"h2","className":""},{"data":"Отправляем изменения на удаленный репозиторий: <strong>git push.</strong>","type":"p","className":""},{"data":"Проверяем GitHub. Изменения появились, но залилась только ветка main. Другие ветки нужно заливать отдельно: <strong>git push -u origin &lt;название ветки&gt;.</strong>","type":"p","className":""},{"data":"Зальем ветку input: <strong>git push -u origin input. </strong>Видим, что на GitHub появились две ветки. Переключиться между ветками можно в меню branch.","type":"p","className":""},{"data":{"id":4035,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c65fb8dbe8ae4f279267c895ca27fc6d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c65fb8dbe8ae4f279267c895ca27fc6d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":597,"real_height_2x":1194},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/c65fb8dbe8ae4f279267c895ca27fc6d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/c65fb8dbe8ae4f279267c895ca27fc6d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":597,"real_height_2x":1194}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Как перемещаться по коммитам &nbsp;","type":"h2","className":""},{"data":"Еще один важный указатель в git — это head. Он указывает, на какой ветке мы находимся. Если мы перейдем в историю, увидим, что head указывает на ветку main и на удаленную ветку origin_main. Это значит, наш локальный и удаленный репозитории синхронизированы.&nbsp;","type":"p","className":""},{"data":"Перейдем на другую ветку командой<strong> git checkout input, </strong>и в истории head будет указывать уже на input.","type":"p","className":""},{"data":{"id":4036,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/de7f7b9ec21d43e8840d760aa7b1dcad-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/de7f7b9ec21d43e8840d760aa7b1dcad-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":334,"real_height_2x":668},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/de7f7b9ec21d43e8840d760aa7b1dcad-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/de7f7b9ec21d43e8840d760aa7b1dcad-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":334,"real_height_2x":668}]},{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7a97d436e0ba47869c561af12c4a9ac8-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7a97d436e0ba47869c561af12c4a9ac8-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":310,"real_height_2x":621},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7a97d436e0ba47869c561af12c4a9ac8-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7a97d436e0ba47869c561af12c4a9ac8-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":310,"real_height_2x":621}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Мы можем перейти не только на другую ветку, но и на отдельный коммит. Будто перенестись в прошлое и посмотреть, как работал наш код на одном из этапов разработки.&nbsp;Сначала переключимся на основную ветку. ","type":"p","className":""},{"data":"Посмотрим историю изменений: <strong>git log --oneline. </strong><strong><em>(</em></strong><em>Эта команда дает более компактное отображение истории по сравнению с git log.)</em>","type":"p","className":""},{"data":"Переходим на один из первых коммитов: <strong>git checkout &lt;первые символы кода идентификатора&gt;</strong>. Head уже будет указывать на отдельный коммит, а в редакторе код тоже вернулся на тот этап.&nbsp;","type":"p","className":""},{"data":{"id":4037,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/56a225abcb3d4f5e970ab040f2a58e57-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/56a225abcb3d4f5e970ab040f2a58e57-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":482,"real_height_2x":965},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/56a225abcb3d4f5e970ab040f2a58e57-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/56a225abcb3d4f5e970ab040f2a58e57-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":482,"real_height_2x":965}]},{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/228118a06a4948cba486aaea3cd25f5a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/228118a06a4948cba486aaea3cd25f5a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":438,"real_height_2x":875},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/228118a06a4948cba486aaea3cd25f5a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/228118a06a4948cba486aaea3cd25f5a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":438,"real_height_2x":875}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"С помощью таких перемещений по коммитам, мы можем искать ошибки, понимать, в какой момент код работал хорошо, а с какого этапа что-то пошло не так.&nbsp;Мы можем даже вносить изменения на этом этапе, но для этого нужно создать отдельную ветку. ","type":"p","className":""},{"data":"Создадим новую ветку и переключимся на нее в одно действие с помощью флага -b: <strong>git checkout -b calc</strong>. ","type":"p","className":""},{"data":"Добавим изменения в редактор: допишем строку <strong>2+2. </strong>Сохраняем изменения в редакторе. ","type":"p","className":""},{"data":"Добавим файл в отслеживание и коммитим изменения: <strong>git commit -a -m “Add calculation”.</strong>","type":"p","className":""},{"data":"Вернемся в основную ветку: <strong>git checkout main</strong>.  Посмотрим все ветки: <strong>git branch</strong>. Видим, что появилась новая ветка calc. ","type":"p","className":""},{"data":{"id":4038,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/dd768ac8047948ff91bcbd0e20507552-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/dd768ac8047948ff91bcbd0e20507552-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":573,"real_height_2x":1146},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/dd768ac8047948ff91bcbd0e20507552-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/dd768ac8047948ff91bcbd0e20507552-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":573,"real_height_2x":1146}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Сделаем визуализацию наших изменений:  <strong>git log --oneline --graph --all. </strong>Видим, что со второго коммита ответвилась еще одна ветка. ","type":"p","className":""},{"data":{"id":4039,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/dd4d84f571ff4387856373eb0d574187-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/dd4d84f571ff4387856373eb0d574187-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":520,"real_height_2x":1041},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/dd4d84f571ff4387856373eb0d574187-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/dd4d84f571ff4387856373eb0d574187-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":520,"real_height_2x":1041}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Как удалить ветку в Git ","type":"h2","className":""},{"data":"Если мы понимаем, что ветка больше не нужна, можно ее удалить. &nbsp;При этом удаляемая ветка не должна быть той веткой, в которой мы находимся. Удалим ветку calc:<strong> git branch -d calc. </strong>Git предупреждает, что ветка еще не объединена с основной веткой и что удалять ее опасно. Но мы уверены, что хотим удалить ветку, поэтому вводим еще одну команду, которую нам подсказывает git: <strong>git branch -D calc.</strong>","type":"p","className":""},{"data":"Теперь удалим ветку input. Она уже залита на GitHub, поэтому сначала удалим ее с удаленного репозитория: <strong>git push --delete origin input</strong>","type":"p","className":""},{"data":"Проверим Git Hub: ветка удалилась. Теперь удаляем ветку локально: <strong>git branch -d input.</strong>","type":"p","className":""},{"data":"Проверим наши ветки: <strong>git branch</strong>. Ветки удалились, осталась только ветка main.","type":"p","className":""},{"data":{"id":4040,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a55ef55c074243bcbd8bd39e46df6c7d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a55ef55c074243bcbd8bd39e46df6c7d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":584,"real_height_2x":1169},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a55ef55c074243bcbd8bd39e46df6c7d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a55ef55c074243bcbd8bd39e46df6c7d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":584,"real_height_2x":1169}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если по ходу работы у вас появляются ошибки, попробуйте найти решение в интернете. Часто достаточно скопировать полученную ошибку и вбить ее в поиск в браузере. Если все же не получается найти ответ, пишите нам в чате в Telegram.","type":"p","className":""}]},{"id":442,"header":"Система контроля версий Git. Урок 2","_path":"/workshops/2022/02/04/sistema-kontrolya-versii-git-urok-2/","lead":"Заливаем репозиторий на GitHub","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/adf75c22c731466aa4408504c0daf4d7-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2022-02-04","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":2517,"last_name":"","first_name":"Редакция","last_name_en":"","first_name_en":"Editors","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Продолжаем изучать систему контроля версий git. Сегодня говорим про GitHub. На прошлом уроке мы создали локальный репозиторий для проекта. Но хранить данные только на компьютере опасно, если папка с репозиторием удалится или потеряется, весь проект пропадет. Поэтому важно дублировать все файлы и историю их изменений на сервере. Самая популярная платформа, на которой разработчики размещают репозитории — GitHub. Зарегистрируйтесь на нем. Это так же просто, как создать аккаунт в соцсетях. \n\n\n\n\nНастраиваем доступ по токену\nКогда вы зарегистрировались и зашли в аккаунт, стоит настроить доступ по токену. Это важная мера безопасности. Даже если ваш пароль кто-то украдет, зайти в аккаунт он не сможет. Токен — более продвинутый метод защиты, чем пароль. Аутентификация по токену генерирует входные данные отдельно для каждого устройства и сеанса. У токенов можно менять права доступа или отзывать их. Подобрать токен перебором невозможно.\nПереходим в меню под фото профиля. Settings → Developer settings → Personal access tokens → Create new token. \n\n\nРазные токены нужны для разных доступов, чтобы не запутаться, давайте дадим нашему токену название tutorial. В настройках для начала достаточно поставить галочку рядом с repo. Создаем токен. Получившийся токен нужно обязательно сохранить в какой-то надежный файл, а лучше в менеджер паролей. \nОткроем терминал по адресу нашего проекта. На mac нужно выбрать «новый терминал по адресу папки». На Windows будет вариант «GitBush here».\nЧтобы настроить доступ по токену, воспользуемся уже известной утилитой git config: git config --global user.name <username, который задавали при регистрации>\nТеперь вводим токен: git config --global user.password <ваш токен>\n\n\n\n \nУстанавливаем двухфакторную аутентификацию\nВторая важная настройка безопасности — двухфакторная аутентификация. Settings → Password and Autentication → Enable Two-Factor Authentication. \nВ качестве второго фактора лучше использовать не SMS, а приложение, например Google Аuthenticator. Его нужно скачать на телефон, нажать на плюс, чтобы добавить новый код, затем отсканировать qr-код, который появится на сайте, и ввести сгенерированный шестизначный код. После этого нужно скачать коды восстановления и сохранить их в надежное место. \n \n \nСоздаем репозиторий на GitHub\nМожем создать первый удаленный репозиторий. Нажимаем на + в правом верхнем углу, выбираем New repository. \n\n\nЗадаем имя репозитория, например, git_tutorial. \nМожем добавить описание: «Учимся работать с удаленным репозиторием».\nGitHub предлагает нам сразу создать два базовых файла README.md и .gitignore. Но у нас уже есть локальный репозиторий, с которым мы начали работать, добавим эти файлы в него. А на этом шаге просто нажимаем create repository. \n\n\n\n \nФайлы README и gitignore \nФайл README.md — это текстовый файл, в котором на языке markdown можно добавить описание проекта. Файл README необязателен, но помогает лучше ориентироваться в своих и чужих репозиториях. Давайте его добавим в нашу папку с проектом. Напишем заголовок «Тестовый репозиторий» и описание: «Это тестовый репозиторий, в котором я учусь работать с git». \n\n\nОписания могут быть и гораздо более подробными, содержать картинки, ссылки, вставки кода. Подробнее о языке markdown можно прочитать в официальном гайде. \n\nВ проекте появился новый файл. Вернемся в терминал и добавим его в отслеживание: git add README.md\nЗакоммитим: git commit -m “Add README”\n \nФайл .gitignore нужен, чтобы прописать те файлы, которые мы не хотим отслеживать. Это могут быть конфигурационные или временные файлы, которые автоматически создаются по ходу работы. Учесть все ненужные файлы, которые могут появиться, и самостоятельно создать gitignore-документ сложно. Поэтому можно использовать шаблоны, а потом уже дополнять их самостоятельно по ходу работы. Мы программируем на python, поэтому для примера я нашла gitignore для python. Создадим файл .gitignore в нашей папке и скопируем в него названия файлов. \n\n\nДобавим новый файл в отслеживание и закоммитим изменения. \ngit add .gitignore\ngit commit -m “Add gitignore”\nПроверим git status. Все закоммичено.\n\nТеперь в репозитории есть все нужные файлы, можем добавить его на GitHub. GitHub можно использовать как обычное хранилище и загружать почти любые файлы. Для этого нужно нажать «загрузка нового файла» и выбрать, что мы хотим загрузить. \n\n\nМожно таким путем добавить и наш репозиторий. Но так файлы просто скопируются из одного место в другое, а нам нужно привязать локальный репозиторий к серверу. \n \nПросматриваем историю изменений\nВернемся в терминал. Вспомним, какие изменения мы уже локально коммитили на прошлом уроке. Посмотреть все коммиты можно с помощью команды git log. Сейчас мы видим все коммиты.\n\n\nУ каждого коммита есть уникальный идентификатор — набор цифр и букв. Мы видим кто и когда сделал каждый коммит, какое сообщение он написал. Подробнее посмотреть информацию о конкретном коммите можно с помощью команды: git show <5 первых символов идентификатора>\nВ таком режиме мы видим, какие изменения были внесены.\nЗеленые плюсы — какие строки добавились, красные минусы — какие удалились. \n\n\nЧтобы выйти из log, нужно нажать q в английской раскладке.\nЕще раз посмотрим всю историю: git log. Наши изменения лежат в ветке master (на Windows будет ветка main), подробнее про ветки мы еще будем говорить на следующем занятии. Сейчас достаточно знать, что это основная ветка. Но на GitHub основная ветка называется main. \nЧтобы не возникало проблем при сохранении проекта на сервере, переименуем нашу локальную ветку: git branch -m master main. (Для Windows это делать не нужно)\nПроверим историю: git log. Видим, что ветка переименовалась.\n \n\nПередаем репозиторий на сервер\nПередадим наш репозиторий на сервер. Связаться с удаленным репозиторием можно по ссылке. Откроем репозиторий на GitHub и скопируем ссылку. \n\n\nВ открытом терминале пишем команду:\ngit remote add origin <ссылка на репозиторий> \n(Чтобы вставить скопированную ссылку в терминал на Windows, нужно зажать ctrl и нажать левой кнопкой мыши или тачпада.)\nOrigin — это имя удаленного репозитория, которое мы будем дальше использовать вместо ссылки. Проверим, подключился ли репозиторий. Команда git remote -v показывает, какие удаленные репозитории присоединены. Мы видим присоединенный репозиторий. \n\n\nТеперь можем отправить на него наш локальный репозиторий: git push -u origin main \n\n\nОбновим страницу: наш репозиторий появился на сайте.\n\n\nВ заголовке видим последний коммит. Если нажмем на часы — увидим историю коммитов. Такую же, как в git log.\nТеперь пройдем весь путь от внесения изменений, до передачи их на сервер.\n \nВносим изменения и исправляем ошибки\nВносим изменения в наш файл test.py: print(“We learn GitHub”)  \nДобавляем изменение в отслеживание и закоммитим: git commit -a -m “Add third line”\nВ работе над реальным проектом, важно емко описывать изменения, которые вы внесли. Это поможет лучше ориентироваться в репозитории. \n\nТеперь давайте представим, что мы закоммитили ошибочное изменение. Допишем в файл строку: print(“False line”)\n\n\nДобавим изменение в отслеживание и закоммитим: git commit -a -m “False commit”\nПроверим историю: git log\nМы видим ошибочный коммит. \n\n\nЧтобы отменить его, воспользуемся командой: git revert <первые 5 символов идентификатора коммита>\nМы попали в текстовый редактор, где уже есть сообщение об отмене коммита, можем написать другое сообщение или сохранить предложенное, чтобы выйти из текстового редактора нажмем cmd+X, затем y и enter.\n\n\nПроверим историю: git log. Мы видим, что git создал новое сохранение с отменой коммита, а в файле ненужная строка удалилась. \n\n\n\n \nЗаливаем изменения на сервер\nПроверим git status. Дерево чистое, можем заливать коммиты на сервер: git push. Нам не нужно еще раз писать origin main, потому изменения из ветки main на ветку origin мы уже передавали в прошлый раз. Откроем наш репозиторий на сайте. Зайдем в файл test.py. Видим, что третья строка появилась, а четвертая ошибочная строка не закоммитилась, как нам и было нужно. \n\n\n \nКопируем удаленные репозитории\nGitHub позволяет не только создавать свои репозитории, но и копировать чужие. Зайдем на GitHub «Важных историй», выберем любой репозиторий. Скопируем ссылку. \n\n\nСоздадим папку на компьютере для этого репозитория. Откроем терминал в этой папке. Введем команду git clone <ссылка на репозиторий>  \nВы можете просто открыть папку и проверить, что в нее скопировались все файлы из репозитория.\nМожно это сделать и в терминале, просмотрев все внутренние папки: ls\nПерейдем в репозиторий: cd <название клонированной папки с репозиторием>\n\n\nТеперь мы можем работать с этим репозиторием локально: вносить изменения, просматривать историю коммитов.\n \nЕсли у вас появятся вопросы, попробуйте найти ответ в интернете. Часто достаточно скопировать полученную ошибку и забить ее в поиск в браузере. Если все же не получается найти ответ, пишите нам в чате в Telegram.","blocks":[{"data":"Продолжаем изучать систему контроля версий git. Сегодня говорим про GitHub.&nbsp;На прошлом уроке мы создали локальный репозиторий для проекта. Но хранить данные только на компьютере опасно, если папка с репозиторием удалится или потеряется, весь проект пропадет. Поэтому важно дублировать все файлы и историю их изменений на сервере.&nbsp;Самая популярная платформа, на которой разработчики размещают репозитории — <a href=\"https://github.com/\" data-type=\"usual\" target=\"_blank\">GitHub</a>. Зарегистрируйтесь на нем. Это так же просто, как создать аккаунт в соцсетях.&nbsp;","type":"p","className":""},{"data":{"id":3989,"data":{"url":"https://www.youtube.com/embed/X3CcvoWfDZM","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=X3CcvoWfDZM&t=12s","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Настраиваем доступ по токену","type":"h2","className":""},{"data":"Когда вы зарегистрировались и зашли в аккаунт, стоит настроить доступ по токену. Это важная мера безопасности. Даже если ваш пароль кто-то украдет, зайти в аккаунт он не сможет. Токен — более продвинутый метод защиты, чем пароль. Аутентификация по токену генерирует входные данные отдельно для каждого устройства и сеанса. У токенов можно менять права доступа или отзывать их. Подобрать токен перебором невозможно.","type":"p","className":""},{"data":"Переходим в меню под фото профиля. Settings → Developer settings → Personal access tokens → Create new token. ","type":"p","className":""},{"data":{"id":3954,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/695633a0f4af4819968e3ae64a3ad5eb-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/695633a0f4af4819968e3ae64a3ad5eb-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":2948,"real_height_2x":5895},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/695633a0f4af4819968e3ae64a3ad5eb-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/695633a0f4af4819968e3ae64a3ad5eb-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":2948,"real_height_2x":5895}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Разные токены нужны для разных доступов, чтобы не запутаться, давайте дадим нашему токену название tutorial.&nbsp;В настройках для начала достаточно поставить галочку рядом с repo. Создаем токен. Получившийся токен нужно обязательно сохранить в какой-то надежный файл, а лучше в менеджер паролей.&nbsp;","type":"p","className":""},{"data":"Откроем терминал по адресу нашего проекта. На mac нужно выбрать «новый терминал по адресу папки». На Windows будет вариант «GitBush here».","type":"p","className":""},{"data":"Чтобы настроить доступ по токену, воспользуемся уже известной утилитой git config:<strong> git config --global user.name &lt;username, который задавали при регистрации&gt;</strong>","type":"p","className":""},{"data":"Теперь вводим токен: <strong>git config --global user.password &lt;ваш токен&gt;</strong>","type":"p","className":""},{"data":{"id":3957,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/53a824b3457e40e1a05a680d2c28bdb9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/53a824b3457e40e1a05a680d2c28bdb9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":213,"real_height_2x":426},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/53a824b3457e40e1a05a680d2c28bdb9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/53a824b3457e40e1a05a680d2c28bdb9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":213,"real_height_2x":426}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"&nbsp;","type":"p","className":""},{"data":"Устанавливаем двухфакторную аутентификацию","type":"h2","className":""},{"data":"Вторая важная настройка безопасности — двухфакторная аутентификация. Settings → Password and Autentication → Enable Two-Factor Authentication.&nbsp;","type":"p","className":""},{"data":"В качестве второго фактора лучше использовать не SMS, а приложение, например Google Аuthenticator.&nbsp;Его нужно скачать на телефон, нажать на плюс, чтобы добавить новый код, затем отсканировать qr-код, который появится на сайте, и ввести сгенерированный шестизначный код. После этого нужно скачать коды восстановления и сохранить их в надежное место.&nbsp;","type":"p","className":""},{"data":"&nbsp;","type":"p","className":""},{"data":"&nbsp;","type":"p","className":""},{"data":"Создаем репозиторий на GitHub","type":"h2","className":""},{"data":"Можем создать первый удаленный репозиторий. Нажимаем на + в правом верхнем углу, выбираем New repository. ","type":"p","className":""},{"data":{"id":3955,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/192792b36b104b2eb7efa1c24d04cc15-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/192792b36b104b2eb7efa1c24d04cc15-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":920,"real_height_2x":1840},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/192792b36b104b2eb7efa1c24d04cc15-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/192792b36b104b2eb7efa1c24d04cc15-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":920,"real_height_2x":1840}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Задаем имя репозитория, например, git_tutorial.&nbsp;","type":"p","className":""},{"data":"Можем добавить описание: «Учимся работать с удаленным репозиторием».","type":"p","className":""},{"data":"GitHub предлагает нам сразу создать два базовых файла README.md и&nbsp;.gitignore. Но у нас уже есть локальный репозиторий, с которым мы начали работать, добавим эти файлы в него.&nbsp;А на этом шаге просто нажимаем create repository.&nbsp;","type":"p","className":""},{"data":{"id":3956,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/85a5518e4bd64e8e8cd0349e5f05b57d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/85a5518e4bd64e8e8cd0349e5f05b57d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":898,"real_height_2x":1798},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/85a5518e4bd64e8e8cd0349e5f05b57d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/85a5518e4bd64e8e8cd0349e5f05b57d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":898,"real_height_2x":1798}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"&nbsp;","type":"p","className":""},{"data":"Файлы README и gitignore&nbsp;","type":"h2","className":""},{"data":"Файл README.md — это текстовый файл, в котором на языке markdown можно добавить описание проекта. Файл README необязателен, но помогает лучше ориентироваться в своих и чужих репозиториях. Давайте его добавим в нашу папку с проектом. Напишем заголовок «Тестовый репозиторий» и описание: «Это тестовый репозиторий, в котором я учусь работать с git».&nbsp;","type":"p","className":""},{"data":{"id":3958,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ebcaca0a5fc147dcac2bf0ef17051303-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ebcaca0a5fc147dcac2bf0ef17051303-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":440,"real_height_2x":880},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ebcaca0a5fc147dcac2bf0ef17051303-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ebcaca0a5fc147dcac2bf0ef17051303-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":440,"real_height_2x":880}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Описания могут быть и гораздо более подробными, содержать картинки, ссылки, вставки кода. Подробнее о языке markdown можно прочитать в <a href=\"https://www.markdownguide.org/basic-syntax/\" data-type=\"usual\" target=\"_blank\">официальном гайде</a>.&nbsp;","type":"p","className":""},{"data":"В проекте появился новый файл. Вернемся в терминал и добавим его в отслеживание: <strong>git add README.md</strong>","type":"p","className":""},{"data":"Закоммитим: <strong>git commit -m “Add README”</strong>","type":"p","className":""},{"data":"&nbsp;","type":"p","className":""},{"data":"Файл .gitignore нужен, чтобы прописать те файлы, которые мы не хотим отслеживать. Это могут быть конфигурационные или временные файлы, которые автоматически создаются по ходу работы. Учесть все ненужные файлы, которые могут появиться, и самостоятельно создать gitignore-документ сложно. Поэтому можно использовать шаблоны, а потом уже дополнять их самостоятельно по ходу работы. Мы программируем на python, поэтому для примера я нашла gitignore для python. Создадим файл .gitignore в нашей папке и скопируем в него названия файлов.&nbsp;","type":"p","className":""},{"data":{"id":3959,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/10a696582f2640309659fad840844ccb-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/10a696582f2640309659fad840844ccb-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":719,"real_height_2x":1438},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/10a696582f2640309659fad840844ccb-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/10a696582f2640309659fad840844ccb-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":719,"real_height_2x":1438}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Добавим новый файл в отслеживание и закоммитим изменения. ","type":"p","className":""},{"data":"<strong>git add .gitignore</strong>","type":"p","className":""},{"data":"<strong>git commit -m “Add gitignore”</strong>","type":"p","className":""},{"data":"Проверим git status. Все закоммичено.","type":"p","className":""},{"data":{"id":3960,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2c00f8f660fb4da78edde34e9da9a33d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2c00f8f660fb4da78edde34e9da9a33d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":586,"real_height_2x":1172},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2c00f8f660fb4da78edde34e9da9a33d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/2c00f8f660fb4da78edde34e9da9a33d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":586,"real_height_2x":1172}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь в репозитории есть все нужные файлы, можем добавить его на GitHub.&nbsp;GitHub можно использовать как обычное хранилище и загружать почти любые файлы.&nbsp;Для этого нужно нажать «загрузка нового файла» и выбрать, что мы хотим загрузить. ","type":"p","className":""},{"data":{"id":3964,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4c60be71d9204364a5e6d644f51155af-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4c60be71d9204364a5e6d644f51155af-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":456,"real_height_2x":911},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4c60be71d9204364a5e6d644f51155af-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4c60be71d9204364a5e6d644f51155af-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":456,"real_height_2x":911}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Можно таким путем добавить и наш репозиторий. Но так файлы просто скопируются из одного место в другое, а нам нужно привязать локальный репозиторий к серверу. ","type":"p","className":""},{"data":"&nbsp;","type":"p","className":""},{"data":"Просматриваем историю изменений","type":"h2","className":""},{"data":"Вернемся в терминал. Вспомним, какие изменения мы уже локально коммитили на прошлом уроке. Посмотреть все коммиты можно с помощью команды <strong>git log</strong>.&nbsp;Сейчас мы видим все коммиты.","type":"p","className":""},{"data":{"id":3961,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5ec05b91a09a491e9929a57e43eb6294-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5ec05b91a09a491e9929a57e43eb6294-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":780,"real_height_2x":1560},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5ec05b91a09a491e9929a57e43eb6294-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5ec05b91a09a491e9929a57e43eb6294-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":780,"real_height_2x":1560}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"У каждого коммита есть уникальный идентификатор — набор цифр и букв. Мы видим кто и когда сделал каждый коммит, какое сообщение он написал. Подробнее посмотреть информацию о конкретном коммите можно с помощью команды: <strong>git show &lt;5 первых символов идентификатора&gt;</strong>","type":"p","className":""},{"data":"В таком режиме мы видим, какие изменения были внесены.","type":"p","className":""},{"data":"Зеленые плюсы —&nbsp;какие строки добавились, красные минусы — какие удалились.&nbsp;","type":"p","className":""},{"data":{"id":3962,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/fbe6e34587e84394b60a0943015bf5d1-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/fbe6e34587e84394b60a0943015bf5d1-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":790,"real_height_2x":1582},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/fbe6e34587e84394b60a0943015bf5d1-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/fbe6e34587e84394b60a0943015bf5d1-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":790,"real_height_2x":1582}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы выйти из log, нужно нажать <strong>q</strong> в английской раскладке.","type":"p","className":""},{"data":"Еще раз посмотрим всю историю: <strong>git log. </strong>Наши изменения лежат в ветке master (на Windows будет ветка main), подробнее про ветки мы еще будем говорить на следующем занятии. Сейчас достаточно знать, что это основная ветка. Но на GitHub основная ветка называется main. ","type":"p","className":""},{"data":"Чтобы не возникало проблем при сохранении проекта на сервере, переименуем нашу локальную ветку: <strong>git branch -m master main</strong>. (Для Windows это делать не нужно)","type":"p","className":""},{"data":"Проверим историю: <strong>git log</strong>. Видим, что ветка переименовалась.","type":"p","className":""},{"data":"&nbsp;","type":"p","className":""},{"data":{"id":3963,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/420d2a5ea7a5497f96e549d671e4914c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/420d2a5ea7a5497f96e549d671e4914c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":894,"real_height_2x":1788},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/420d2a5ea7a5497f96e549d671e4914c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/420d2a5ea7a5497f96e549d671e4914c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":894,"real_height_2x":1788}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Передаем репозиторий на сервер","type":"h2","className":""},{"data":"Передадим наш репозиторий на сервер. Связаться с удаленным репозиторием можно по ссылке. Откроем репозиторий на GitHub и скопируем ссылку.&nbsp;","type":"p","className":""},{"data":{"id":3965,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bf21683a1cde48119e17823020239626-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bf21683a1cde48119e17823020239626-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":465,"real_height_2x":930},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bf21683a1cde48119e17823020239626-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/bf21683a1cde48119e17823020239626-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":465,"real_height_2x":930}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В открытом терминале пишем команду:","type":"p","className":""},{"data":"<strong>git remote add origin &lt;ссылка на репозиторий&gt;&nbsp;</strong>","type":"p","className":""},{"data":"(Чтобы вставить скопированную ссылку в терминал на Windows, нужно зажать ctrl и нажать левой кнопкой мыши или тачпада.)","type":"p","className":""},{"data":"Origin — это имя удаленного репозитория, которое мы будем дальше использовать вместо ссылки. Проверим, подключился ли репозиторий. Команда <strong>git remote -v </strong>показывает, какие удаленные репозитории присоединены.&nbsp;Мы видим присоединенный репозиторий. ","type":"p","className":""},{"data":{"id":3966,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4b99a29de36245f49e50b5f5e7aad64b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4b99a29de36245f49e50b5f5e7aad64b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":188,"real_height_2x":376},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4b99a29de36245f49e50b5f5e7aad64b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4b99a29de36245f49e50b5f5e7aad64b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":188,"real_height_2x":376}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь можем отправить на него наш локальный репозиторий: <strong>git push -u origin main&nbsp;</strong>","type":"p","className":""},{"data":{"id":3967,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/33546a6f0c0e4fbfb78727a75f3697ed-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/33546a6f0c0e4fbfb78727a75f3697ed-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":360,"real_height_2x":722},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/33546a6f0c0e4fbfb78727a75f3697ed-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/33546a6f0c0e4fbfb78727a75f3697ed-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":360,"real_height_2x":722}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Обновим страницу: наш репозиторий появился на сайте.","type":"p","className":""},{"data":{"id":3968,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/01642744308b428fad45092cfb7488ad-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/01642744308b428fad45092cfb7488ad-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":701,"real_height_2x":1402},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/01642744308b428fad45092cfb7488ad-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/01642744308b428fad45092cfb7488ad-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":701,"real_height_2x":1402}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В заголовке видим последний коммит. Если нажмем на часы — увидим историю коммитов. Такую же, как в git log.","type":"p","className":""},{"data":"Теперь пройдем весь путь от внесения изменений, до передачи их на сервер.","type":"p","className":""},{"data":"&nbsp;","type":"p","className":""},{"data":"Вносим изменения и исправляем ошибки","type":"h2","className":""},{"data":"Вносим изменения в наш файл test.py: <strong>print(“We learn GitHub”)&nbsp;&nbsp;</strong>","type":"p","className":""},{"data":"Добавляем изменение в отслеживание и закоммитим: <strong>git commit -a -m “Add third line”</strong>","type":"p","className":""},{"data":"В работе над реальным проектом, важно емко описывать изменения, которые вы внесли. Это поможет лучше ориентироваться в репозитории.&nbsp;","type":"p","className":""},{"data":"Теперь давайте представим, что мы закоммитили ошибочное изменение. Допишем в файл строку: <strong>print(“False line”)</strong>","type":"p","className":""},{"data":{"id":3969,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/10c6233884d347159ffb420cc5f0ca75-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/10c6233884d347159ffb420cc5f0ca75-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":338,"real_height_2x":675},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/10c6233884d347159ffb420cc5f0ca75-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/10c6233884d347159ffb420cc5f0ca75-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":338,"real_height_2x":675}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Добавим изменение в отслеживание и закоммитим:&nbsp;<strong>git commit -a -m “False commit”</strong>","type":"p","className":""},{"data":"Проверим историю: <strong>git log</strong>","type":"p","className":""},{"data":"Мы видим ошибочный коммит. ","type":"p","className":""},{"data":{"id":3971,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5a4f48d04b674058994bd57415c08b03-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5a4f48d04b674058994bd57415c08b03-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":613,"real_height_2x":1226},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5a4f48d04b674058994bd57415c08b03-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5a4f48d04b674058994bd57415c08b03-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":613,"real_height_2x":1226}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы отменить его, воспользуемся командой: <strong>git revert &lt;первые 5 символов идентификатора коммита&gt;</strong>","type":"p","className":""},{"data":"Мы попали в текстовый редактор, где уже есть сообщение об отмене коммита, можем написать другое сообщение или сохранить предложенное, чтобы выйти из текстового редактора нажмем<strong> cmd+X</strong>, затем <strong>y</strong> и <strong>enter</strong>.","type":"p","className":""},{"data":{"id":3970,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/918fa75e08d24b6687d0ca8fe9d8428b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/918fa75e08d24b6687d0ca8fe9d8428b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":738,"real_height_2x":1478},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/918fa75e08d24b6687d0ca8fe9d8428b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/918fa75e08d24b6687d0ca8fe9d8428b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":738,"real_height_2x":1478}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Проверим историю: <strong>git log. </strong>Мы видим, что git создал новое сохранение с отменой коммита, а в файле ненужная строка удалилась. ","type":"p","className":""},{"data":{"id":3975,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/944168a03f1944218f00cff274d148e6-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/944168a03f1944218f00cff274d148e6-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":818,"real_height_2x":1635},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/944168a03f1944218f00cff274d148e6-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/944168a03f1944218f00cff274d148e6-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":818,"real_height_2x":1635}]},{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/19a5cd6f534448c2a8d14eeda3e9dbff-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/19a5cd6f534448c2a8d14eeda3e9dbff-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":725,"real_height_2x":1450},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/19a5cd6f534448c2a8d14eeda3e9dbff-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/19a5cd6f534448c2a8d14eeda3e9dbff-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":725,"real_height_2x":1450}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"&nbsp;","type":"p","className":""},{"data":"Заливаем изменения на сервер","type":"h2","className":""},{"data":"Проверим <strong>git status. </strong>Дерево чистое, можем заливать коммиты на сервер: <strong>git push. </strong>Нам не нужно еще раз писать origin main, потому изменения из ветки main на ветку origin мы уже передавали в прошлый раз<strong>. </strong>Откроем наш репозиторий на сайте. Зайдем в файл test.py. Видим, что третья строка появилась, а четвертая ошибочная строка не закоммитилась, как нам и было нужно. ","type":"p","className":""},{"data":{"id":3974,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ddbb7773accf440e8917d462ca4b206b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ddbb7773accf440e8917d462ca4b206b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":312,"real_height_2x":624},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ddbb7773accf440e8917d462ca4b206b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ddbb7773accf440e8917d462ca4b206b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":312,"real_height_2x":624}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"&nbsp;","type":"p","className":""},{"data":"Копируем удаленные репозитории","type":"h2","className":""},{"data":"GitHub позволяет не только создавать свои репозитории, но и копировать чужие.&nbsp;Зайдем на GitHub <a href=\"https://github.com/iStoriesMedia\" data-type=\"usual\" target=\"_blank\">«Важных историй»</a>, выберем любой репозиторий. Скопируем ссылку.&nbsp;","type":"p","className":""},{"data":{"id":3972,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9b3dd953cbbb48de9f2a563bf350ff97-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9b3dd953cbbb48de9f2a563bf350ff97-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":525,"real_height_2x":1050},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9b3dd953cbbb48de9f2a563bf350ff97-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9b3dd953cbbb48de9f2a563bf350ff97-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":525,"real_height_2x":1050}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Создадим папку на компьютере для этого репозитория. Откроем терминал в этой папке.&nbsp;Введем команду <strong>git clone &lt;ссылка на репозиторий&gt;&nbsp;&nbsp;</strong>","type":"p","className":""},{"data":"Вы можете просто открыть папку и проверить, что в нее скопировались все файлы из репозитория.","type":"p","className":""},{"data":"Можно это сделать и в терминале, просмотрев все внутренние папки: <strong>ls</strong>","type":"p","className":""},{"data":"Перейдем в репозиторий: <strong>cd &lt;название клонированной папки с репозиторием&gt;</strong>","type":"p","className":""},{"data":{"id":3973,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/15fab3e5760a43838f415a4fd36e3203-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/15fab3e5760a43838f415a4fd36e3203-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":590,"real_height_2x":1181},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/15fab3e5760a43838f415a4fd36e3203-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/15fab3e5760a43838f415a4fd36e3203-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":590,"real_height_2x":1181}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь мы можем работать с этим репозиторием локально: вносить изменения, просматривать историю коммитов.","type":"p","className":""},{"data":"&nbsp;","type":"p","className":""},{"data":"Если у вас появятся вопросы, попробуйте найти ответ в интернете. Часто достаточно скопировать полученную ошибку и забить ее в поиск в браузере. Если все же не получается найти ответ, пишите нам в <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">чате</a> в Telegram.","type":"p","className":""}]},{"id":433,"header":"Система контроля версий Git. Урок 1","_path":"/workshops/2022/01/21/ustanavlivaem-i-nastraivaem-git/","lead":"Устанавливаем и настраиваем GIT","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7762730e1a2a4c948ba90dbe7a365828-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":" ","created_at_date":"2022-01-21","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":23,"first_name":"Полина","last_name":"Ужвак","first_name_en":"Polina","last_name_en":"Uzhvak","is_public":true,"_path":"polina-uzhvak","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_2x.webp","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_2x.jpg","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_2x.webp","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_2x.jpg","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_2x.webp","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_2x.jpg","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_2x.webp","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_2x.jpg","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Автор дата-отдела","lead_en":"","position":"Автор","position_en":null,"ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Мы начинаем курс по системе контроля версий Git. Она позволяет сохранять файлы, с которыми вы работаете, и все этапы их изменений. Если в вашем проекте что-то пошло не так, всегда можно вернуться к прошлой версии и начать работу с этапа, когда ошибок еще не было. Еще с Git вы сможете создавать отдельные ветки изменений ваших проектов, а потом сливать их в одну.\n\n\n\n\nУстанавливаем Git\nMac\nПерейдем на сайт.  Выберем Binary installer. На открывшейся странице нажимаем download. Открываем скачанный файл. Нажимаем на установочный образ правой кнопкой мыши и выбираем «открыть» (если не получается, зажмите control и нажмите правой кнопкой мыши на иконке еще раз). Устанавливаем Git, нажимая «продолжить» и затем «установить».\n\nWindows\nПереходим на сайт. Скачивание установочного файла начнется автоматически. Если нет, нажмите на ссылку «click here to download».\nОткрываем скачанный файл. Соглашаемся с условиями лицензии. Выбираем папку, куда стоит установить Git. \nНа следующих этапах можете выбрать те же опции, которые мы отметили на скриншотах.\n\n\n\n\n\n\nНастраиваем Git\n\nВсе возможности Git доступны из терминала. Откроем его. На Mac нужно ввести в поиске Terminal, на Windows на рабочем столе после установки должна появиться иконка Git Bash. Проверим, что git установлен. Для этого введем команду git --version. Мы видим версию git, которая установлена на компьютер. \n\nЗададим имя и адрес электронной почты. Они нужны, чтобы git понимал, кто именно вносит в файл изменения. \ngit config --global user.name \"Polina Uzhvak”\ngit config --global user.email uzhvak@istories.media\n\nЗададим текстовый редактор. По умолчанию стоит редактор Vim, но этот редактор довольно сложный (про это у программистов даже есть мемы). Мы его поменяем на более простой редактор nano: git config --global core.editor nano.\n\n\n\n\n\nЧтобы посмотреть все заданные настройки, наберем git config --list --show-origin. Вы увидите все настройки Git, среди которых будут и заданные нами. \n\n\n \nСоздаем репозиторий\nТеперь создадим локальное хранилище для наших файлов и их версий — репозиторий. Для примера проекта я создам на рабочем столе папку Git_Tutorial. \nОткрою папку в редакторе VSCode и создам файл с расширением .py с простой командой print(‘Hello!’). Не забываем сохранить файл в редакторе cmd (ctrl) + S. \n\n\nТеперь будем сохранять эту версию изменений в git.\nЧтобы открыть терминал сразу по адресу папки, нужно нажать на нее правой кнопкой мыши и выбрать «новый терминал по адресу папки» (на Windows нужно выбрать Git Bash Here).\n\n\n\nЕсли на Mac такой строки нет, это можно настроить. Для этого нужно перейти в «Системные настройки», затем пункт меню «Клавиатура», перейти на вкладку «Сочетание клавиш», в разделе «Службы» выбрать раздел «Файлы и папки» и поставить флажок напротив «Новый терминал по адресу папки».\n\nТеперь мы зашли в терминал сразу в нужной директории. Чтобы создать репозиторий, введем команду git init.\nЕсли команда сработала без ошибок, то вы увидите такой ответ: Initialized empty Git repository in Диск:/папка/.git/ В подкаталоге .git и будет храниться наш репозиторий. \n\n\nВ git есть три состояния файла:\nизменен, \nиндексирован, то есть отслеживается, \nзафиксирован, то есть сохранен.  \n\nЧтобы понять, в каком состоянии наш файл, воспользуемся командой git status\nФайл помечен красным, значит он изменен, но еще не отслеживается.\nДобавим его отслеживание с помощью команды git add test.py\nЕсли мы изменили сразу несколько файлов, стоит добавить в отслеживание их все. Чтобы не прописывать название каждого файла отдельно, можем воспользоваться командой git add *. Звездочка заменяет все символы. Если хотим добавить все файлы определенного расширения — git add *.(расширение). \n\nОпять проверим состояние файла git status. Зеленым подсвечен файл, который отслеживает git. \n\n\n\nЧтобы зафиксировать изменения, используем команду git commit.\n\nМы попали в текстовый редактор nano, который указывали при настройке. Здесь нам нужно прописать, что мы сделали на этом этапе. Например, начали проект, напишу start project.\nВнизу есть подсказки по редактору, чтобы выйти нажмем control+X, подтвердим выход нажав у и затем enter.  \n\n\nЕще раз проверим состояние файла git status. Git пишет, что сохранять нечего, мы все успешно сохранили или закоммитили.\n\n\n\nТеперь немного изменим файл. Добавим вторую строчку вывода в файле в редакторе VSCode print(“We learn git”).  Cохраним файл.\n\n\nПроверим git status. Git показывает, что у нас есть изменения, не сохраненные в систему контроля версий. Чтобы эту версию изменений тоже сохранить, мы должны опять добавить файл в отслеживание через git add и закоммитить через git commit, прописав название коммита в текстовом редакторе.  \nЧтобы каждый раз не писать две отдельные строки, их можно объединить: git commit -a -m “Add second output”.\nФлаг -a (сокращение от --all) говорит о том, что мы добавляем в отслеживание все удалённые или изменённые файлы, флаг -m позволяет писать, что мы сделали на новом этапе, не заходя в текстовый редактор. При этом если в проекте появляются новые файлы, их все равно нужно будет добавлять в отслеживание отдельно через команду git add.\n\n\n\n\nМы научились базовым принципам работы с git. В следующих уроках познакомимся с GitHub и научимся сохранять изменения на сервере. \nЕсли вам нравится наша работа, вы можете поддержать нас. А если у вас остались вопросы, пишите в чате в telegram.","blocks":[{"data":"Мы начинаем курс по системе контроля версий Git. Она позволяет сохранять файлы, с которыми вы работаете, и все этапы их изменений.&nbsp;Если в вашем проекте что-то пошло не так, всегда можно вернуться к прошлой версии и начать работу с этапа, когда ошибок еще не было. Еще с Git вы сможете создавать отдельные ветки изменений ваших проектов, а потом сливать их в одну.","type":"p","className":""},{"data":{"id":3878,"data":{"url":"https://www.youtube.com/embed/xWCKNekbXfM","text":"съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=xWCKNekbXfM","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Устанавливаем Git","type":"h2","className":""},{"data":"<strong>Mac</strong>","type":"p","className":""},{"data":"Перейдем на <a href=\"https://git-scm.com/download/mac\" data-type=\"usual\" target=\"_blank\">сайт</a>.  Выберем Binary installer. На открывшейся странице нажимаем download. Открываем скачанный файл. Нажимаем на установочный образ правой кнопкой мыши и выбираем «открыть» (если не получается, зажмите control и нажмите правой кнопкой мыши на иконке еще раз). Устанавливаем Git, нажимая «продолжить» и затем «установить».","type":"p","className":""},{"data":"<strong>Windows</strong>","type":"p","className":""},{"data":"Переходим на <a href=\"https://git-scm.com/download/win\" data-type=\"usual\" target=\"_blank\">сайт</a>. Скачивание установочного файла начнется автоматически. Если нет, нажмите на ссылку «click here to download».","type":"p","className":""},{"data":"Открываем скачанный файл. Соглашаемся с условиями лицензии. Выбираем папку, куда стоит установить Git. ","type":"p","className":""},{"data":"На следующих этапах можете выбрать те же опции, которые мы отметили на скриншотах.","type":"p","className":""},{"data":{"id":3872,"data":{"images":[{"caption":"Компоненты для установки","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4c8e8318424642c48c5aa6c3d038d98a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4c8e8318424642c48c5aa6c3d038d98a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":916,"real_height_2x":1832},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4c8e8318424642c48c5aa6c3d038d98a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4c8e8318424642c48c5aa6c3d038d98a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":916,"real_height_2x":1832}]},{"caption":"Выбор редактора","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5e21d2acce0647d0a4ad702f0155a420-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5e21d2acce0647d0a4ad702f0155a420-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":916,"real_height_2x":1832},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5e21d2acce0647d0a4ad702f0155a420-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5e21d2acce0647d0a4ad702f0155a420-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":916,"real_height_2x":1832}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":{"id":3873,"data":{"images":[{"caption":"Переменная окружения PATH","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2b810581d40345e0940264fab21b0490-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2b810581d40345e0940264fab21b0490-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":916,"real_height_2x":1832},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2b810581d40345e0940264fab21b0490-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/2b810581d40345e0940264fab21b0490-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":916,"real_height_2x":1832}]},{"caption":"Библиотека для HTTPS-соединений","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/71537cb9908746e58f6a98b86425f3e8-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/71537cb9908746e58f6a98b86425f3e8-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":919,"real_height_2x":1838},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/71537cb9908746e58f6a98b86425f3e8-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/71537cb9908746e58f6a98b86425f3e8-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":919,"real_height_2x":1838}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":{"id":3874,"data":{"images":[{"caption":"Символы окончания строки","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/337cc83b8cdf4e42903767e75e754dcf-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/337cc83b8cdf4e42903767e75e754dcf-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":919,"real_height_2x":1838},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/337cc83b8cdf4e42903767e75e754dcf-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/337cc83b8cdf4e42903767e75e754dcf-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":919,"real_height_2x":1838}]},{"caption":"Выбор терминала","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7f7804615ad740a1b1186b9e6f835eea-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7f7804615ad740a1b1186b9e6f835eea-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":917,"real_height_2x":1834},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7f7804615ad740a1b1186b9e6f835eea-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7f7804615ad740a1b1186b9e6f835eea-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":917,"real_height_2x":1834}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":{"id":3875,"data":{"images":[{"caption":"Поведение git pull","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ae5883b666b84823939b7496a0ead378-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ae5883b666b84823939b7496a0ead378-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":917,"real_height_2x":1834},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ae5883b666b84823939b7496a0ead378-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ae5883b666b84823939b7496a0ead378-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":917,"real_height_2x":1834}]},{"caption":"Credential Helper","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/08e1b7f55d834ecb880e8f175acddab8-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/08e1b7f55d834ecb880e8f175acddab8-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":917,"real_height_2x":1834},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/08e1b7f55d834ecb880e8f175acddab8-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/08e1b7f55d834ecb880e8f175acddab8-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":917,"real_height_2x":1834}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":{"id":3876,"data":{"images":[{"caption":"Дополнительные опции","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/da5c616b767042fc9827cc0b93d4654d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/da5c616b767042fc9827cc0b93d4654d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":917,"real_height_2x":1834},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/da5c616b767042fc9827cc0b93d4654d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/da5c616b767042fc9827cc0b93d4654d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":917,"real_height_2x":1834}]},{"caption":"Экспериментальные опции","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3719d4030cbe49999a65724914416004-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3719d4030cbe49999a65724914416004-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":916,"real_height_2x":1832},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3719d4030cbe49999a65724914416004-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3719d4030cbe49999a65724914416004-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":916,"real_height_2x":1832}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Настраиваем Git","type":"h2","className":""},{"data":"Все возможности Git доступны из терминала. Откроем его. На Mac нужно ввести в поиске Terminal, на Windows на рабочем столе после установки должна появиться иконка Git Bash. Проверим, что git установлен. Для этого введем команду <strong>git --version</strong>. Мы видим версию git, которая установлена на компьютер.&nbsp;","type":"p","className":""},{"data":"Зададим имя и адрес электронной почты. Они нужны, чтобы git понимал, кто именно вносит в файл изменения.&nbsp;","type":"p","className":""},{"data":"<strong>git config --global user.name \"Polina Uzhvak”</strong>","type":"p","className":""},{"data":"<strong>git config --global user.email uzhvak@istories.media</strong>","type":"p","className":""},{"data":"Зададим текстовый редактор. По умолчанию стоит редактор Vim, но этот редактор довольно сложный (про это у программистов даже есть <a href=\"https://meduza.io/shapito/2017/05/25/kak-vyyti-iz-vim-etot-tekstovyy-redaktor-takoy-slozhnyy-chto-v-nem-zastryal-million-chelovek\" data-type=\"usual\" target=\"_blank\">мемы</a>). Мы его поменяем на более простой редактор nano: <strong>git config --global core.editor nano.</strong>","type":"p","className":""},{"data":{"id":3879,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/10010eb33c6844e881a7d5d8aae68cd3-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/10010eb33c6844e881a7d5d8aae68cd3-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":275,"real_height_2x":550},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/10010eb33c6844e881a7d5d8aae68cd3-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/10010eb33c6844e881a7d5d8aae68cd3-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":275,"real_height_2x":550}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы посмотреть все заданные настройки, наберем <strong>git config --list --show-origin. </strong>Вы увидите все настройки Git, среди которых будут и заданные нами. ","type":"p","className":""},{"data":{"id":3880,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/969a56bcc69b49fb89597a0d52a06a8b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/969a56bcc69b49fb89597a0d52a06a8b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":512,"real_height_2x":1024},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/969a56bcc69b49fb89597a0d52a06a8b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/969a56bcc69b49fb89597a0d52a06a8b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":512,"real_height_2x":1024}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"&nbsp;","type":"p","className":""},{"data":"Создаем репозиторий","type":"h2","className":""},{"data":"Теперь создадим локальное хранилище для наших файлов и их версий — репозиторий. Для примера проекта я создам на рабочем столе папку Git_Tutorial.&nbsp;","type":"p","className":""},{"data":"Открою папку в редакторе VSCode и создам файл с расширением .py с простой командой <strong>print(‘Hello!’).</strong> Не забываем сохранить файл в редакторе cmd (ctrl) + S. ","type":"p","className":""},{"data":{"id":3881,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/94f3fd944a834c5197bd6b91249dbe4c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/94f3fd944a834c5197bd6b91249dbe4c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":468,"real_height_2x":936},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/94f3fd944a834c5197bd6b91249dbe4c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/94f3fd944a834c5197bd6b91249dbe4c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":468,"real_height_2x":936}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь будем сохранять эту версию изменений в git.","type":"p","className":""},{"data":"Чтобы открыть терминал сразу по адресу папки, нужно нажать на нее правой кнопкой мыши и выбрать «новый терминал по адресу папки» (на Windows нужно выбрать Git Bash Here).","type":"p","className":""},{"data":{"id":3882,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3d0612b5df0343718e9ce455c75d5ef4-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3d0612b5df0343718e9ce455c75d5ef4-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":863,"real_height_2x":1726},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3d0612b5df0343718e9ce455c75d5ef4-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3d0612b5df0343718e9ce455c75d5ef4-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":863,"real_height_2x":1726}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если на Mac такой строки нет, это можно настроить. Для этого нужно перейти в «Системные настройки», затем пункт меню «Клавиатура», перейти на вкладку «Сочетание клавиш», в разделе «Службы» выбрать раздел «Файлы и папки» и поставить флажок напротив «Новый терминал по адресу папки».","type":"p","className":""},{"data":"Теперь мы зашли в терминал сразу в нужной директории.&nbsp;Чтобы создать репозиторий, введем команду <strong>git init.</strong>","type":"p","className":""},{"data":"Если команда сработала без ошибок, то вы увидите такой ответ: <strong>Initialized empty Git repository in Диск:/папка/.git/ </strong>В подкаталоге .git и будет храниться наш репозиторий.&nbsp;","type":"p","className":""},{"data":{"id":3883,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8c2a2a74136a4909ab69eed7b8e214b9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8c2a2a74136a4909ab69eed7b8e214b9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":550,"real_height_2x":1100},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8c2a2a74136a4909ab69eed7b8e214b9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/8c2a2a74136a4909ab69eed7b8e214b9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":550,"real_height_2x":1100}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В git есть три состояния файла:","type":"p","className":""},{"data":"<li>изменен, </li><li>индексирован, то есть отслеживается, </li><li>зафиксирован, то есть сохранен.&nbsp;&nbsp;</li>","type":"ul","className":""},{"data":"Чтобы понять, в каком состоянии наш файл, воспользуемся командой <strong>git status</strong>","type":"p","className":""},{"data":"Файл помечен красным, значит он изменен, но еще не отслеживается.","type":"p","className":""},{"data":"Добавим его отслеживание с помощью команды <strong>git add test.py</strong>","type":"p","className":""},{"data":"Если мы изменили сразу несколько файлов, стоит добавить в отслеживание их все. Чтобы не прописывать название каждого файла отдельно, можем воспользоваться командой <strong>git add *</strong>. Звездочка заменяет все символы. Если хотим добавить все файлы определенного расширения — <strong>git add *.(расширение)</strong>.&nbsp;","type":"p","className":""},{"data":"Опять проверим состояние файла<strong> git status. </strong>Зеленым подсвечен файл, который отслеживает git.&nbsp;","type":"p","className":""},{"data":{"id":3884,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c91e51755dde43caba0f7524eef03407-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c91e51755dde43caba0f7524eef03407-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":784,"real_height_2x":1567},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/c91e51755dde43caba0f7524eef03407-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/c91e51755dde43caba0f7524eef03407-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":784,"real_height_2x":1567}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы зафиксировать изменения, используем команду <strong>git commit.</strong>","type":"p","className":""},{"data":"Мы попали в текстовый редактор nano, который указывали при настройке. Здесь нам нужно прописать, что мы сделали на этом этапе. Например, начали проект, напишу <strong>start project</strong>.","type":"p","className":""},{"data":"Внизу есть подсказки по редактору, чтобы выйти нажмем <strong>control+X</strong>, подтвердим выход нажав <strong>у </strong>и затем <strong>enter</strong>.&nbsp;&nbsp;","type":"p","className":""},{"data":{"id":3885,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/62f84a2bfb9045f7a8b6f7b8a106719d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/62f84a2bfb9045f7a8b6f7b8a106719d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":792,"real_height_2x":1583},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/62f84a2bfb9045f7a8b6f7b8a106719d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/62f84a2bfb9045f7a8b6f7b8a106719d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":792,"real_height_2x":1583}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Еще раз проверим состояние файла<strong> git status. </strong>Git пишет, что сохранять нечего, мы все успешно сохранили или закоммитили.","type":"p","className":""},{"data":{"id":3886,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3665016aa9d843e0a24691f105ceee9e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3665016aa9d843e0a24691f105ceee9e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":419,"real_height_2x":838},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3665016aa9d843e0a24691f105ceee9e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3665016aa9d843e0a24691f105ceee9e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":419,"real_height_2x":838}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь немного изменим файл. Добавим вторую строчку вывода в файле в редакторе VSCode <strong>print(“We learn git”).</strong>&nbsp;&nbsp;Cохраним файл.","type":"p","className":""},{"data":{"id":3887,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7e2f8112be0649be940eb535aeec7a06-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7e2f8112be0649be940eb535aeec7a06-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":444,"real_height_2x":888},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7e2f8112be0649be940eb535aeec7a06-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7e2f8112be0649be940eb535aeec7a06-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":444,"real_height_2x":888}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Проверим<strong> git status. </strong>Git показывает, что у нас есть изменения, не сохраненные в систему контроля версий. Чтобы эту версию изменений тоже сохранить, мы должны опять добавить файл в отслеживание через <strong>git add</strong> и закоммитить через<strong> git commit</strong>, прописав название коммита в текстовом редакторе.&nbsp;&nbsp;","type":"p","className":""},{"data":"Чтобы каждый раз не писать две отдельные строки, их можно объединить: <strong>git commit -a -m “Add second output”.</strong>","type":"p","className":""},{"data":"Флаг <strong>-a</strong> (сокращение от --all) говорит о том, что мы добавляем в отслеживание все удалённые или изменённые файлы, флаг<strong> -m</strong> позволяет писать, что мы сделали на новом этапе, не заходя в текстовый редактор. При этом если в проекте появляются новые файлы, их все равно нужно будет добавлять в отслеживание отдельно через команду <strong>git add.</strong>","type":"p","className":""},{"data":{"id":3888,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/700f2a95a6d048d18d435b9c0f9b4308-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/700f2a95a6d048d18d435b9c0f9b4308-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":776,"real_height_2x":1551},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/700f2a95a6d048d18d435b9c0f9b4308-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/700f2a95a6d048d18d435b9c0f9b4308-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":776,"real_height_2x":1551}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы научились базовым принципам работы с git. В следующих уроках познакомимся с GitHub и научимся сохранять изменения на сервере.&nbsp;","type":"p","className":""},{"data":"Если вам нравится наша работа, вы можете поддержать нас. А если у вас остались вопросы, пишите в чате в <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">telegram</a>.","type":"p","className":""}]},{"id":420,"header":"Геокодируем адреса","_path":"/workshops/2022/01/14/geokodiruem-adresa/","lead":"Присваиваем адресам геокоординаты с помощью плагина для Google Sheets","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/cf6bab7fe9c043b5bf7c0592a1553a68-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2022-01-14","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":true,"category":"workshops","locale":"ru","authors_list":[{"id":23,"first_name":"Полина","last_name":"Ужвак","first_name_en":"Polina","last_name_en":"Uzhvak","is_public":true,"_path":"polina-uzhvak","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_2x.webp","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_2x.jpg","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_2x.webp","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_2x.jpg","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_2x.webp","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_2x.jpg","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_2x.webp","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_2x.jpg","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Автор дата-отдела","lead_en":"","position":"Автор","position_en":null,"ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Сегодня узнаем, как превратить список адресов в список геокоординат с помощью плагина Geocode Awesome Table для Google Sheets, и научимся отображать их на карте. Для примера мы возьмем адреса свалок твердых бытовых отходов в Татарстане. Их можно найти в территориальной схеме обращения с отходами, которая выложена на сайте Минстроя республики. Я уже собрала адреса в таблицу, она доступна по ссылке. \n\n\n\n\nГотовим адреса\nВ столбце с адресом нет названия региона. Чтобы геокодер не ошибался и брал населенные пункты именно Татарстана, добавим колонку с регионом. Полный адрес получим с помощью функции join. В скобках пишем разделитель в кавычках — у нас это запятая с пробелом, потом ячейки, которые хотим объединить. \n\n\n\nРастягиваем функцию на всю страницу. Мы получили полные адреса.\n\nГеокодируем адреса\nТеперь нам нужно получить геокоординаты каждого адреса. Для начала установим нужный плагин. Находим вкладку «расширения» → «дополнения» → «установить дополнения». В строку поиска вбиваем Geocode by Awesome Table. Устанавливаем расширение. \n\nТеперь во вкладке расширений у нас появился геокодер, наводим на него и нажимаем start geocoding. Указываем, в каком столбце содержится адрес, геокоординаты которого нам нужно получить. В нашем случае это столбец «полный адрес». Нажимаем geocode и ждем. \n\n\n\n\nБуквально за минуту мы получили все координаты. У адресов полигонов ТБО есть особенности, например, указания «1000 м южнее д. Новые Бирюли», или «4230 м от д. Починок Шемордан по направлению на запад». Геокодер будет ориентироваться только на названные географические объекты, поэтому в некоторых строках геокоординаты будут приблизительные. В случае с конкретными адресами таких проблем быть не должно, но стоит все же проверять данные. Для этого можно просто скопировать полученные геокоординаты и посмотреть, какие адреса по ним выдаются в поиске онлайн-карт. \n\nСоздаем интерактивную карту\n\nКогда мы получили координаты и проверили, что они соответствуют действительности, можем создать интерактивную карту. Один из вариантов — сервис Google My Maps. \n\nНажимаем «создать карту». Добавлять объекты можно вручную. Например, наберем «татарстан полигоны тбо». Нашлись несколько полигонов, их можно добавить на карту, нажав «Добавить на карту». Но такой способ подходит, чтобы отмечать единичные объекты, например, составлять план путешествий. \n\n\n\nНам нужно добавить сразу все адреса из датасета, поэтому нажмем на кнопку импорт. \n\n\n\n\nМожно загрузить файл или подключиться к Googke Sheets. Выбираем наш файл, проверяем, что столбцы широты и долготы выбраны верно. Выбираем столбец, из которого возьмем подписи для точек. \n\n\n\n\nТеперь у нас отмечены все свалки в республике Татарстан. Сразу можно оценить, насколько их много. Сервис позволяет выбрать фон в разделе «Базовая карта» и изменить вид иконок. Возьмем более светлую карту для контраста, а иконки поменяем на значки и покрасим их в бордовый. \n\nЕще можно добавлять и другие слои с другими типами объектов. Для этого нужно нажать «добавить слой». Чтобы карта была доступна не только вам, к ней нужно открыть доступ во вкладке «поделиться». \n\n\n\nДадим название нашей карте — «мусорные полигоны в Татарстане». Теперь можно делиться картой по ссылке, распечатать ее или что самое полезное — добавить на сайт.\n\n\n\n\nЕсли вам нравится наша работа, вы можете поддержать нас. А если у вас остались вопросы, пишите в чате в Telegram.","blocks":[{"data":"Сегодня узнаем, как превратить список адресов в список геокоординат с помощью плагина Geocode Awesome Table для Google Sheets, и научимся отображать их на карте. Для примера мы возьмем адреса свалок твердых бытовых отходов в Татарстане. Их можно найти в территориальной схеме обращения с отходами, которая выложена на <a href=\"https://minstroy.tatarstan.ru/regionalnie-npa-2808717.htm \" data-type=\"usual\" target=\"_blank\">сайте</a> Минстроя республики. Я уже собрала адреса в таблицу, она доступна по <a href=\"https://docs.google.com/spreadsheets/d/1M1m8sMSIhHiuJF67TKY_kit8qZlRtY-qLLtWZ47ECnQ/edit#gid=0\" data-type=\"usual\" target=\"_blank\">ссылке</a>.&nbsp;","type":"p","className":""},{"data":{"id":3792,"data":{"url":"https://www.youtube.com/embed/st0sriECNr0","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=st0sriECNr0","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Готовим адреса","type":"h2","className":""},{"data":"В столбце с адресом нет названия региона. Чтобы геокодер не ошибался и брал населенные пункты именно Татарстана, добавим колонку с регионом. Полный адрес получим с помощью функции join. В скобках пишем разделитель в кавычках — у нас это запятая с пробелом, потом ячейки, которые хотим объединить. ","type":"p","className":""},{"data":{"id":3780,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/904fa36fd7794aae978fb9ceb3a5beca-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/904fa36fd7794aae978fb9ceb3a5beca-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":90,"real_height_2x":182},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/904fa36fd7794aae978fb9ceb3a5beca-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/904fa36fd7794aae978fb9ceb3a5beca-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":90,"real_height_2x":182}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Растягиваем функцию на всю страницу. Мы получили полные адреса.","type":"p","className":""},{"data":"Геокодируем адреса","type":"h2","className":""},{"data":"Теперь нам нужно получить геокоординаты каждого адреса.&nbsp;Для начала установим нужный плагин. Находим вкладку «расширения» → «дополнения» → «установить дополнения». В строку поиска вбиваем Geocode by Awesome Table. Устанавливаем расширение.&nbsp;","type":"p","className":""},{"data":"Теперь во вкладке расширений у нас появился геокодер, наводим на него и нажимаем start geocoding. Указываем, в каком столбце содержится адрес, геокоординаты которого нам нужно получить. В нашем случае это столбец «полный адрес». Нажимаем geocode и ждем.&nbsp;","type":"p","className":""},{"data":{"id":3781,"data":{"block":"<p><span style=\"background-color:#ffffff\">Geocode by awesome table позволяет геокодировать тысячу адресов в сутки. Если вам нужно геокодировать больше данных, придется искать более продвинутые варианты геокодинга или разбивать датасет на части и геокодировать за несколько дней. </span></p>","header":"Ограничения плагина","content":[{"insert":"Geocode by awesome table позволяет геокодировать тысячу адресов в сутки. Если вам нужно геокодировать больше данных, придется искать более продвинутые варианты геокодинга или разбивать датасет на части и геокодировать за несколько дней. ","attributes":{"color":"rgba(0, 0, 0, 0.85)","background":"#ffffff"}},{"insert":"\n"}]},"category":"drop-down-embed"},"type":"drop-down-embed"},{"data":"Буквально за минуту мы получили все координаты. У адресов полигонов ТБО есть особенности, например, указания «1000 м южнее д. Новые Бирюли», или «4230 м от д. Починок Шемордан по направлению на запад». Геокодер будет ориентироваться только на названные географические объекты, поэтому в некоторых строках геокоординаты будут приблизительные. В случае с конкретными адресами таких проблем быть не должно, но стоит все же проверять данные.&nbsp;Для этого можно просто скопировать полученные геокоординаты и посмотреть, какие адреса по ним выдаются в поиске онлайн-карт. ","type":"p","className":""},{"data":"Создаем интерактивную карту","type":"h2","className":""},{"data":"Когда мы получили координаты и проверили, что они соответствуют действительности, можем создать интерактивную карту. Один из вариантов — сервис <a href=\"https://www.google.com/maps/d/u/0/\" data-type=\"usual\" target=\"_blank\">Google My Maps</a>. ","type":"p","className":""},{"data":"Нажимаем «создать карту». Добавлять объекты можно вручную. Например, наберем «татарстан полигоны тбо». Нашлись несколько полигонов, их можно добавить на карту, нажав «Добавить на карту». Но такой способ подходит, чтобы отмечать единичные объекты, например, составлять план путешествий.&nbsp;","type":"p","className":""},{"data":{"id":3782,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/75c10be646494466b20f0e2fa25b2679-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/75c10be646494466b20f0e2fa25b2679-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":882,"real_height_2x":1763},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/75c10be646494466b20f0e2fa25b2679-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/75c10be646494466b20f0e2fa25b2679-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":882,"real_height_2x":1763}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Нам нужно добавить сразу все адреса из датасета, поэтому нажмем на кнопку импорт. ","type":"p","className":""},{"data":{"id":3784,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/57f7590beb0b40deb657de1fb066ddd9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/57f7590beb0b40deb657de1fb066ddd9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1288,"real_height_2x":2575},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/57f7590beb0b40deb657de1fb066ddd9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/57f7590beb0b40deb657de1fb066ddd9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1288,"real_height_2x":2575}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Можно загрузить файл или подключиться к Googke Sheets. Выбираем наш файл, проверяем, что столбцы широты и долготы выбраны верно. Выбираем столбец, из которого возьмем подписи для точек. ","type":"p","className":""},{"data":{"id":3785,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/22fce7f468324e6aaf2b15f220b76df2-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/22fce7f468324e6aaf2b15f220b76df2-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":838,"real_height_2x":1675},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/22fce7f468324e6aaf2b15f220b76df2-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/22fce7f468324e6aaf2b15f220b76df2-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":838,"real_height_2x":1675}]},{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/550c72e14635485082fc4d727595dc31-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/550c72e14635485082fc4d727595dc31-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":833,"real_height_2x":1666},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/550c72e14635485082fc4d727595dc31-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/550c72e14635485082fc4d727595dc31-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":833,"real_height_2x":1666}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Теперь у нас отмечены все свалки в республике Татарстан. Сразу можно оценить, насколько их много.&nbsp;Сервис позволяет выбрать фон в разделе «Базовая карта» и изменить вид иконок. Возьмем более светлую карту для контраста, а иконки поменяем на значки и покрасим их в бордовый. ","type":"p","className":""},{"data":"Еще можно добавлять и другие слои с другими типами объектов. Для этого нужно нажать «добавить слой». Чтобы карта была доступна не только вам, к ней нужно открыть доступ во вкладке «поделиться». ","type":"p","className":""},{"data":{"id":3789,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3c9ae16f04d048d8aebaacfec262cd13-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3c9ae16f04d048d8aebaacfec262cd13-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":604,"real_height_2x":1209},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3c9ae16f04d048d8aebaacfec262cd13-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3c9ae16f04d048d8aebaacfec262cd13-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":604,"real_height_2x":1209}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Дадим название нашей карте — «мусорные полигоны в Татарстане». Теперь можно делиться картой по ссылке, распечатать ее&nbsp;или что самое полезное — добавить на сайт.","type":"p","className":""},{"data":{"id":3791,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/583f36767ed5420c8336b6b219595d5e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/583f36767ed5420c8336b6b219595d5e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":502,"real_height_2x":1004},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/583f36767ed5420c8336b6b219595d5e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/583f36767ed5420c8336b6b219595d5e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":502,"real_height_2x":1004}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если вам нравится наша работа, вы можете поддержать нас. А если у вас остались вопросы, пишите в чате в <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">Telegram</a>.","type":"p","className":""},{"data":{"id":3788,"data":{"text":"Ваше пожертвования позволит нам записывать еще больше полезных уроков.","title":"Поддержите тех, кто делает уроки для дата-журналистов","buttonText":"Поддержать «Важные истории» "},"category":"donate-embed"},"type":"donate-embed"}]},{"id":399,"header":"Парсинг с помощью Python. Урок 5","_path":"/workshops/2021/12/30/parsing-s-pomoshchyu-python-urok-5/","lead":"Скрейпим сайты с помощью библиотек Selenium и BeautifulSoup","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/f1d58c9727254e9da907ebbdc3f11923-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-12-30","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Продолжаем рассказывать, как скрейпить сайты с помощью Python. Поэтому сегодня мы поговорим о том, как использовать библиотеки, которые мы уже с вами изучали в предыдущих уроках — Selenium и BeautifulSoup, и разберем один интересный случай, когда кажется, что все просто, но на самом деле нужно знать некоторые хитрости.  \nСегодня мы будет скрейпить сайт Мосгорсуда. В своей работе я очень часто прибегаю к данным этого сайта. В качестве примера мы возьмем карточку по моему административному делу: я выходила с пикетом против закона об иностранных агентах к Минюсту, потому что лично я признана иностранным агентом и сайт «Важных историй». Мы категорически не согласны с этим статусом и оспариваем его в суде. Так как меня за пикет задержали и составили протокол об административном правонарушении, то вот и появилась карточка на сайте Мосгорсуда. \nМы хотим собрать данные из этой таблички.\nА также получить данные об опубликованных документах по этому делу. \n\nДля начала мы должны импортировать нужные библиотеки. \nКак и в прошлом уроке мы с вами сначала запускаем драйвер, после чего мы копируем ссылку на дело в переменную url и передаем ее драйверу. После этого откроется браузер Chrome и ссылка на сайт. \nТеперь давайте разберемся как достать данные из первой странички. Поэтому давайте в обычном браузере, где мы работаем кликнем правой кнопкой мыши на табличку и выбираем Inspect. Если у вас другой браузер, то вам нужно кликнуть на «Посмотреть код элемента» или «Изучить элемент». После чего мы попадаем в Inspector. \nИ мы видим, что вся наша табличка лежит в теге с классом «cardsud_wrapper». Копируем название класса и в коде пишем следующее:  \n\nВ ответе лежит наша табличка, но не в очень удобном виде. Давайте посмотрим код еще раз. В каждой строчке есть по два элемента с классами «left» и «right». Давайте соберем данные отдельно из элементов из первого и второго класса. Так у нас получатся два списка: в одном будут лежать название данных, а во вторых сами данные. \n\nТеперь нам осталось только объединить эти два списка в словарь. Для этого используем функцию zip и dict. \nДавайте создадим словарь case, куда будем сохранять вообще все данные. И словарь case_info, куда положим только что собранную табличку. \n\nПервая задача решена. Для второй нам необходимо кликнуть на «Судебные акты» и собрать оттуда данные о документах. Давайте воспользуемся методом find_element_by_link_text. И сразу кликнем на элемент.\nИ как видите мы получили ошибку, потому что браузер не может почему-то кликнуть на эту кнопку, хотя она там есть. Поэтому давайте немного перепишем код и используем Keys. \nТеперь кнопка нажимается и мы видим нужную нам табличку с документами. Давайте извлечем оттуда данные с помощью библиотеки BeautifulSoup. Для начала снова посмотрим, как устроен код этой таблицы в Inspector. \nМы видим что наша табличка лежит в теге с классом «custom_table mainTable». А чтобы добраться до каждой строчки нужно спуститься в тег tbody и найти в нем все теги tr. \nПосле этого, можно уже доставать все данные попорядку и записывать их в словарь document, а каждый такой словарь сохранять сразу в нашу переменную case. \nВот таким способом можно получать данные с сайта Мосгорсуда. Остались вопросы? Задавайте их в нашем Telegram-чате, постараемся ответить.","blocks":[{"data":"Продолжаем рассказывать, как скрейпить сайты с помощью Python. Поэтому сегодня мы поговорим о том, как использовать библиотеки, которые мы уже с вами изучали в предыдущих уроках — Selenium и BeautifulSoup, и разберем один интересный случай, когда кажется, что все просто, но на самом деле нужно знать некоторые хитрости.&nbsp;&nbsp;","type":"p","className":""},{"data":{"id":3508,"data":{"url":"https://www.youtube.com/embed/WC3EGWmm7fQ","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=WC3EGWmm7fQ","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Сегодня мы будет скрейпить сайт Мосгорсуда. В своей работе я очень часто прибегаю к данным этого сайта. В качестве примера мы возьмем <a href=\"https://mos-gorsud.ru/rs/zamoskvoreckij/services/cases/admin/details/3c8b3810-123b-11ec-947c-932d91ed129a?respondent=%D0%9C%D0%B0%D1%80%D0%BE%D1%85%D0%BE%D0%B2%D1%81%D0%BA%D0%B0%D1%8F\" data-type=\"usual\" target=\"_blank\">карточку</a> по моему административному делу: я выходила с пикетом против закона об иностранных агентах к Минюсту, потому что лично я признана иностранным агентом и сайт «Важных историй». Мы категорически не согласны с этим статусом и оспариваем его в суде. Так как меня за пикет задержали и составили протокол об административном правонарушении, то вот и появилась карточка на сайте Мосгорсуда.&nbsp;","type":"p","className":""},{"data":{"id":3494,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a047e20563674c24a5e4d2ae4176d66e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a047e20563674c24a5e4d2ae4176d66e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":715,"real_height_2x":1430},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a047e20563674c24a5e4d2ae4176d66e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a047e20563674c24a5e4d2ae4176d66e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":715,"real_height_2x":1430}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы хотим собрать данные из этой таблички.","type":"p","className":""},{"data":{"id":3495,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/87527ffdd1db4f6e875684fc1db56645-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/87527ffdd1db4f6e875684fc1db56645-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":624,"real_height_2x":1248},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/87527ffdd1db4f6e875684fc1db56645-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/87527ffdd1db4f6e875684fc1db56645-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":624,"real_height_2x":1248}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"А также получить данные об опубликованных документах по этому делу.&nbsp;","type":"p","className":""},{"data":"Для начала мы должны импортировать нужные библиотеки.&nbsp;","type":"p","className":""},{"data":{"id":3496,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1bc517d620bf47f89343999b09545878-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1bc517d620bf47f89343999b09545878-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":120,"real_height_2x":242},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1bc517d620bf47f89343999b09545878-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1bc517d620bf47f89343999b09545878-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":120,"real_height_2x":242}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Как и в прошлом уроке мы с вами сначала запускаем драйвер, после чего мы копируем ссылку на дело в переменную url и передаем ее драйверу. После этого откроется браузер Chrome и ссылка на сайт.&nbsp;","type":"p","className":""},{"data":{"id":3497,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/90173337b0a94a34bf4e2db07794173b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/90173337b0a94a34bf4e2db07794173b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":166,"real_height_2x":332},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/90173337b0a94a34bf4e2db07794173b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/90173337b0a94a34bf4e2db07794173b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":166,"real_height_2x":332}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь давайте разберемся как достать данные из первой странички. Поэтому давайте в обычном браузере, где мы работаем кликнем правой кнопкой мыши на табличку и выбираем Inspect. Если у вас другой браузер, то вам нужно кликнуть на «Посмотреть код элемента» или «Изучить элемент». После чего мы попадаем в Inspector.&nbsp;","type":"p","className":""},{"data":{"id":3498,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/25774434702a44c0b6ec62aa98db86d4-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/25774434702a44c0b6ec62aa98db86d4-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":632,"real_height_2x":1266},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/25774434702a44c0b6ec62aa98db86d4-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/25774434702a44c0b6ec62aa98db86d4-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":632,"real_height_2x":1266}]},{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3ed0fdf69db547f99102cb1011762453-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3ed0fdf69db547f99102cb1011762453-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":812,"real_height_2x":1624},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3ed0fdf69db547f99102cb1011762453-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3ed0fdf69db547f99102cb1011762453-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":812,"real_height_2x":1624}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"И мы видим, что вся наша табличка лежит в теге с классом «cardsud_wrapper». Копируем название класса и в коде пишем следующее:&nbsp;&nbsp;","type":"p","className":""},{"data":{"id":3499,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/0f4635d771154cf7bd6ef0c7f3cf7421-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/0f4635d771154cf7bd6ef0c7f3cf7421-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":113,"real_height_2x":226},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/0f4635d771154cf7bd6ef0c7f3cf7421-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/0f4635d771154cf7bd6ef0c7f3cf7421-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":113,"real_height_2x":226}]}]},"category":"image-embed"},"type":"image-embed"},{"data":{"id":3509,"data":{"text":"Поддержите нас небольшим пожертвованием, а мы продолжим рассказывать о самых интересных иструментах для дата-журналистов","title":"Нравятся наши уроки?","buttonText":"Поддержать Мастерскую"},"category":"donate-embed"},"type":"donate-embed"},{"data":"В ответе лежит наша табличка, но не в очень удобном виде. Давайте посмотрим код еще раз. В каждой строчке есть по два элемента с классами «left» и «right».&nbsp;Давайте соберем данные отдельно из элементов из первого и второго класса. Так у нас получатся два списка: в одном будут лежать название данных, а во вторых сами данные.&nbsp;","type":"p","className":""},{"data":{"id":3500,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9f5b246c9ad64a47968bcfd546ff1a73-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9f5b246c9ad64a47968bcfd546ff1a73-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":534,"real_height_2x":1070},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9f5b246c9ad64a47968bcfd546ff1a73-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9f5b246c9ad64a47968bcfd546ff1a73-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":534,"real_height_2x":1070}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь нам осталось только объединить эти два списка в словарь. Для этого используем функцию zip и dict.&nbsp;","type":"p","className":""},{"data":{"id":3501,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1f2f32bf926243c8bf011b2c3e2adf2d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1f2f32bf926243c8bf011b2c3e2adf2d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":250,"real_height_2x":499},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1f2f32bf926243c8bf011b2c3e2adf2d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1f2f32bf926243c8bf011b2c3e2adf2d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":250,"real_height_2x":499}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Давайте создадим словарь case, куда будем сохранять вообще все данные. И словарь case_info, куда положим только что собранную табличку.&nbsp;","type":"p","className":""},{"data":{"id":3502,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3ad9ceb015d7422f9c2126d6963ac53e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3ad9ceb015d7422f9c2126d6963ac53e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":264,"real_height_2x":529},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3ad9ceb015d7422f9c2126d6963ac53e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3ad9ceb015d7422f9c2126d6963ac53e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":264,"real_height_2x":529}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Первая задача решена. Для второй нам необходимо кликнуть на «Судебные акты» и собрать оттуда данные о документах. Давайте воспользуемся методом find_element_by_link_text. И сразу кликнем на элемент.","type":"p","className":""},{"data":{"id":3503,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/fb4a58a130574b41b81b9f32198ae472-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/fb4a58a130574b41b81b9f32198ae472-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":726,"real_height_2x":1452},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/fb4a58a130574b41b81b9f32198ae472-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/fb4a58a130574b41b81b9f32198ae472-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":726,"real_height_2x":1452}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"И как видите мы получили ошибку, потому что браузер не может почему-то кликнуть на эту кнопку, хотя она там есть. Поэтому давайте немного перепишем код и используем Keys.&nbsp;","type":"p","className":""},{"data":{"id":3504,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b6c83118a62343b9b1dce2be075d5d41-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b6c83118a62343b9b1dce2be075d5d41-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":101,"real_height_2x":202},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b6c83118a62343b9b1dce2be075d5d41-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b6c83118a62343b9b1dce2be075d5d41-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":101,"real_height_2x":202}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь кнопка нажимается и мы видим нужную нам табличку с документами. Давайте извлечем оттуда данные с помощью библиотеки BeautifulSoup. Для начала снова посмотрим, как устроен код этой таблицы в Inspector. ","type":"p","className":""},{"data":{"id":3505,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8af8b3de17f14cde83fedd1916e72eac-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8af8b3de17f14cde83fedd1916e72eac-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":602,"real_height_2x":1205},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8af8b3de17f14cde83fedd1916e72eac-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/8af8b3de17f14cde83fedd1916e72eac-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":602,"real_height_2x":1205}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы видим что наша табличка лежит в теге с классом «custom_table mainTable». А чтобы добраться до каждой строчки нужно спуститься в тег tbody и найти в нем все теги tr.&nbsp;","type":"p","className":""},{"data":{"id":3506,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ba84c737f92a4b2cae32e3dfef0be913-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ba84c737f92a4b2cae32e3dfef0be913-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":514,"real_height_2x":1029},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ba84c737f92a4b2cae32e3dfef0be913-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ba84c737f92a4b2cae32e3dfef0be913-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":514,"real_height_2x":1029}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"После этого, можно уже доставать все данные попорядку и записывать их в словарь document, а каждый такой словарь сохранять сразу в нашу переменную case.&nbsp;","type":"p","className":""},{"data":{"id":3507,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d683051b3dd341fea07bd7995516dfc1-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d683051b3dd341fea07bd7995516dfc1-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":786,"real_height_2x":1573},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/d683051b3dd341fea07bd7995516dfc1-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/d683051b3dd341fea07bd7995516dfc1-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":786,"real_height_2x":1573}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Вот таким способом можно получать данные с сайта Мосгорсуда. Остались вопросы? Задавайте их в нашем<a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\"> Telegram-чате</a>, постараемся ответить. ","type":"p","className":""}]},{"id":385,"header":"Семантический анализ в Python","_path":"/workshops/2021/12/07/semanticheskii-analiz-v-python/","lead":"Рассчитываем контекстную близость слов с помощью библиотеки Word2vec","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/3dc6777a234d40eb97dc7697bfc4f177-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-12-07","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"В одном из недавних материалов вместе с дата-отделом «Новой газеты» мы разбирались, как разные Telegram-каналы пишут о мигрантах, то есть, какой образ мигранта они создают в своих публикациях. Для этого мы выгрузили все посты из отобранных каналов и изучили их с помощью библиотеки для Python — Word2vec. О работе с ней и пойдет речь.\n\n\nWord2vec была разработана в 2013 году исследователями из Google. Она основана на методе дистрибутивной семантики, ее задача — вычислять семантическую близость между лексическими единицами (словами или словосочетаниями), чтобы помочь понять, какой образ создается у конкретного явления.\n\nЧтобы использовать Word2vec, понадобится Python версии 3.5. Создадим виртуальное окружение, где будем использовать именно эту версию. Открываем Anaconda, заходим во вкладку «Enviroments», нажимаем на кнопку «Create». Ставим галочку у «Python», выбираем в выпадающем меню нужную версию. В поле «Name» введите имя виртуального окружения и нажмите «Create».\n\n\n\nКогда окружение будет создано, заходите в Visual Studio Code. Создадим папку для нового проекта и перейдем внутрь нее.\n\n\nОткроем папку и создадим в ней новый файл, в котором начнем работать. Но сперва активируем виртуальное окружение. Для этого в терминале выбираем «bash» в выпадающем меню и пишем conda activate <название виртуального окружения>.\n\n\nПроверим, какой интерпретатор используется. Заходим в него и выбираем нашу версию Python.\n\n\nУстановим нужные библиотеки: Word2vec, Gensim, pymystem3 и Pandas. Команда в терминале — pip install <название библиотеки>. Далее импортируем библиотеки в проект.\n\n\nДля примера возьмем посты из Telegram-канала «Караульный». Скачать уже собранные посты можно на нашей странице в GitHub. В первой колонке у нас дата поста, во второй — сам пост. Перенесем csv-файл в папку проекта.\n\n\nПрочитаем файл с помощью команды pd.read_csv. Укажем точку с запятой как разделитель и удалим лишние строчки (на случай, когда в постах не было текста, а были только картинки).\n\n \nИз файла мы будем доставать все посты. Создадим для очищенных новый файл (Karaulny.txt), введем команду, приводящую все слова к единому регистру. Импортируем библиотеку re, чтобы оставить в файле только слова и убирать численные значения.\n\nПоложим re.findall в переменную res, каждое найденное значение в списке запишем в файл. Каждое слово будем отделять пробелом, а каждый файл — точкой. В конце закроем файл.\n\n\nКогда этот код отработает, у нас появится нужный txt-файл.\n\n\nЗакомментируем выполненный код с помощью \"\"\"\" — он нам больше не понадобится. Откроем новый файл на чтение и создаем список постов, разделяя их с помощью точки. \n\n\nТеперь нужно привести каждое слово к его начальной форме. Например, из «ходил» сделаем «ходить». Здесь пригодится библиотека pymystem3 — положим ее в переменную m, откроем на запись новый файл (Karaulny_lemma.txt) и применим метод lemmatize для каждого поста. \n\n\nСнова закомментируем предыдущую часть кода. Следующий этап — научить библиотеку отделять слова от фраз, например, чтобы она воспринимала слова «Российская Федерация» как единое словосочетание.\n\nДля этого используем метод word2phrase, который получает на вход наш последний файл со словами в начальной форме (Karaulny_lemma.txt), а на выход отдает файл с распознанными выражениями (Karaulny_lemma.txt-phrases) — они будут написаны через нижнее подчеркивание.\n\n\nПосле этого необходимо превратить файл в бинарный (метод word2vec), чтобы передать его библиотеке, которая с помощью нейросети рассчитает расстояние между словами и словосочетаниями.\n\n\nУ нас появился бинарный файл (Karaulny_lemma.txt.bin). Закомментируем предыдущий код, передадим бинарный файл нашей модели (переменная model) и, используя метод KeyedVectors, загрузим этот файл в модель.\n\nТеперь мы можем применить метод most_similar, который будет высчитывать контекстную близость к слову «мигрант». Попросим метод найти 200 самых близких по контексту слов. Итог запишем в новый txt-файл (Karaulny_migrant.txt).\n\n\nВ новом файле мы увидим, какие слова чаще всего встречались в Telegram-канале «Караульный» рядом со словом «мигрант». Например, у словосочетания «массовый_драка» коэффициент близости к слову «мигрант» довольно высокий — больше 0,97. Cудя по нашим данным, канал часто пишет именно о преступлениях мигрантов.\n\n\nЕсли у вас остались вопросы по уроку — не стесняйтесь задавать их в нашем чате.","blocks":[{"data":"В одном из недавних материалов вместе с дата-отделом «Новой газеты» мы <a href=\"https://istories.media/reportages/2021/11/23/kak-propagandisti-nagnetayut-nenavist-k-migrantam-a-mvd-obvinyaet-v-etom-inoagentov/\" data-type=\"usual\" target=\"_blank\">разбирались</a>, как разные Telegram-каналы пишут о мигрантах, то есть, какой образ мигранта они создают в своих публикациях. Для этого мы выгрузили все посты из отобранных каналов и изучили их с помощью библиотеки для Python — <strong>Word2vec</strong>. О работе с ней и пойдет речь.","type":"p","className":""},{"data":{"id":3315,"data":{"url":"https://www.youtube.com/embed/__B4kino_9g","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=__B4kino_9g","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"<strong>Word2vec</strong> была разработана в 2013 году исследователями из Google. Она основана на методе дистрибутивной семантики, ее задача —&nbsp;вычислять семантическую близость между лексическими единицами (словами или словосочетаниями), чтобы помочь понять, какой образ создается у конкретного явления.","type":"p","className":""},{"data":"Чтобы использовать <strong>Word2vec</strong>, понадобится Python версии <strong>3.5</strong>. Создадим виртуальное окружение, где будем использовать именно эту версию. Открываем <strong>Anaconda</strong>, заходим во вкладку «<strong>Enviroments</strong>», нажимаем на кнопку «<strong>Create</strong>». Ставим галочку у «<strong>Python</strong>», выбираем в выпадающем меню нужную версию.&nbsp;В поле «<strong>Name</strong>» введите имя виртуального окружения и нажмите «<strong>Create</strong>».","type":"p","className":""},{"data":{"id":3298,"data":{"images":[{"credit":"Anaconda → «Enviroments» → «Create»","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f5d217a155e2470cada01ae1cb3bb01d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f5d217a155e2470cada01ae1cb3bb01d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1084,"real_height_2x":2169},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f5d217a155e2470cada01ae1cb3bb01d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f5d217a155e2470cada01ae1cb3bb01d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1084,"real_height_2x":2169}]},{"credit":"Если версии 3.5 здесь не окажется, зайдите на официальный сайт Python и загрузите ее оттуда: https://www.python.org/downloads/","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4215ec98f7364b0bb6ee048a97fba141-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4215ec98f7364b0bb6ee048a97fba141-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":708,"real_height_2x":1416},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4215ec98f7364b0bb6ee048a97fba141-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4215ec98f7364b0bb6ee048a97fba141-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":708,"real_height_2x":1416}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Когда окружение будет создано, заходите в <strong>Visual Studio Code</strong>. Создадим папку для нового проекта и перейдем внутрь нее.","type":"p","className":""},{"data":{"id":3299,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e1cb021e74f144e68cb95c3fd61c187f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e1cb021e74f144e68cb95c3fd61c187f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":282,"real_height_2x":566},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e1cb021e74f144e68cb95c3fd61c187f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e1cb021e74f144e68cb95c3fd61c187f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":282,"real_height_2x":566}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Откроем папку и создадим в ней новый файл, в котором начнем работать.&nbsp;Но сперва активируем виртуальное окружение. Для этого в терминале выбираем «<strong>bash</strong>» в выпадающем меню и пишем <strong>conda activate &lt;название виртуального окружения&gt;</strong>.","type":"p","className":""},{"data":{"id":3301,"data":{"images":[{"credit":"«+» → «bash»","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b8897e3c438b42dda47d2c22ea926d6b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b8897e3c438b42dda47d2c22ea926d6b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":259,"real_height_2x":518},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b8897e3c438b42dda47d2c22ea926d6b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b8897e3c438b42dda47d2c22ea926d6b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":259,"real_height_2x":518}]},{"credit":"Активируем виртуальное окружение","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1b79f7cea8774b319fe9a2c4013f7105-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1b79f7cea8774b319fe9a2c4013f7105-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":390,"real_height_2x":781},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1b79f7cea8774b319fe9a2c4013f7105-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1b79f7cea8774b319fe9a2c4013f7105-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":390,"real_height_2x":781}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Проверим, какой интерпретатор используется. Заходим в него и выбираем нашу версию Python.","type":"p","className":""},{"data":{"id":3300,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/91a03cb3b92b438795a16a3c7596be2d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/91a03cb3b92b438795a16a3c7596be2d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":446,"real_height_2x":892},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/91a03cb3b92b438795a16a3c7596be2d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/91a03cb3b92b438795a16a3c7596be2d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":446,"real_height_2x":892}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Установим нужные библиотеки: <strong>Word2vec</strong>, <strong>Gensim</strong>, <strong>pymystem3</strong> и <strong>Pandas</strong>. Команда в терминале — <strong>pip install &lt;название библиотеки&gt;</strong>. Далее импортируем библиотеки в проект.","type":"p","className":""},{"data":{"id":3302,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9ebd96615dd740a780f5cf4519776e12-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9ebd96615dd740a780f5cf4519776e12-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":416,"real_height_2x":832},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9ebd96615dd740a780f5cf4519776e12-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9ebd96615dd740a780f5cf4519776e12-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":416,"real_height_2x":832}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Для примера возьмем посты из Telegram-канала «Караульный». Скачать уже собранные посты можно на <a href=\"https://github.com/iStoriesMedia/word2vec\" data-type=\"usual\" target=\"_blank\">нашей странице в GitHub</a>. В первой колонке у нас дата поста, во второй — сам пост. Перенесем csv-файл в папку проекта.","type":"p","className":""},{"data":{"id":3305,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9643a9fe6cfe48238a4cf548188d0f21-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9643a9fe6cfe48238a4cf548188d0f21-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":589,"real_height_2x":1178},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9643a9fe6cfe48238a4cf548188d0f21-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9643a9fe6cfe48238a4cf548188d0f21-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":589,"real_height_2x":1178}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Прочитаем файл с помощью команды <strong>pd.read_csv</strong>. Укажем точку с запятой как разделитель и удалим лишние строчки (на случай, когда в постах не было текста, а были только картинки).","type":"p","className":""},{"data":{"id":3306,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d1c6c395a2384505a3245468d1eeebb2-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d1c6c395a2384505a3245468d1eeebb2-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":143,"real_height_2x":286},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/d1c6c395a2384505a3245468d1eeebb2-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/d1c6c395a2384505a3245468d1eeebb2-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":143,"real_height_2x":286}]}]},"category":"image-embed"},"type":"image-embed"},{"data":" ","type":"p","className":""},{"data":"Из файла мы будем доставать все посты. Создадим для очищенных новый файл (<strong>Karaulny.txt</strong>), введем команду, приводящую все слова к единому регистру. Импортируем библиотеку <strong>re</strong>, чтобы оставить в файле только слова и убирать численные значения.","type":"p","className":""},{"data":"Положим <strong>re.findall</strong> в переменную <strong>res</strong>, каждое найденное значение в списке запишем в файл. Каждое слово будем отделять пробелом, а каждый файл — точкой. В конце закроем файл.","type":"p","className":""},{"data":{"id":3307,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1101d22cb5494897b9b8a0febc3f56bc-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1101d22cb5494897b9b8a0febc3f56bc-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":670,"real_height_2x":1340},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1101d22cb5494897b9b8a0febc3f56bc-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1101d22cb5494897b9b8a0febc3f56bc-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":670,"real_height_2x":1340}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Когда этот код отработает, у нас появится нужный txt-файл.","type":"p","className":""},{"data":{"id":3314,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ce8971ca0a4749f98ef3501ca72b6848-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ce8971ca0a4749f98ef3501ca72b6848-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":384,"real_height_2x":769},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ce8971ca0a4749f98ef3501ca72b6848-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ce8971ca0a4749f98ef3501ca72b6848-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":384,"real_height_2x":769}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Закомментируем выполненный код с помощью <strong>\"\"\"\"</strong> —&nbsp;он нам больше не понадобится. Откроем новый файл на чтение и создаем список постов, разделяя их с помощью точки.&nbsp;","type":"p","className":""},{"data":{"id":3313,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bc7026c939454f06a99bd3b80e6e20c5-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bc7026c939454f06a99bd3b80e6e20c5-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":536,"real_height_2x":1072},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bc7026c939454f06a99bd3b80e6e20c5-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/bc7026c939454f06a99bd3b80e6e20c5-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":536,"real_height_2x":1072}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь нужно привести каждое слово к его начальной форме. Например, из «ходил» сделаем «ходить». Здесь пригодится библиотека <strong>pymystem3</strong> —&nbsp;положим ее в переменную <strong>m</strong>, откроем на запись новый файл (<strong>Karaulny_lemma.txt</strong>) и применим метод <strong>lemmatize</strong> для каждого поста.&nbsp;","type":"p","className":""},{"data":{"id":3312,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c41da6499adf4db5be48bfd4034ea3c5-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c41da6499adf4db5be48bfd4034ea3c5-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":507,"real_height_2x":1014},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/c41da6499adf4db5be48bfd4034ea3c5-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/c41da6499adf4db5be48bfd4034ea3c5-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":507,"real_height_2x":1014}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Снова закомментируем предыдущую часть кода. Следующий этап — научить библиотеку отделять слова от фраз, например, чтобы она воспринимала слова «Российская Федерация» как единое словосочетание.","type":"p","className":""},{"data":"Для этого используем метод <strong>word2phrase</strong>, который получает на вход наш последний файл со словами в начальной форме (<strong>Karaulny_lemma.txt</strong>), а на выход отдает файл с распознанными выражениями (<strong>Karaulny_lemma.txt-phrases</strong>) — они будут написаны через нижнее подчеркивание.","type":"p","className":""},{"data":{"id":3311,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/635caed9282d46698d36be0d32fe0188-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/635caed9282d46698d36be0d32fe0188-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":380,"real_height_2x":759},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/635caed9282d46698d36be0d32fe0188-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/635caed9282d46698d36be0d32fe0188-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":380,"real_height_2x":759}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"После этого необходимо превратить файл в бинарный (метод <strong>word2vec</strong>), чтобы передать его библиотеке, которая с помощью нейросети рассчитает расстояние между словами и словосочетаниями.","type":"p","className":""},{"data":{"id":3310,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b400850b5ec240f78676924ea0813eee-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b400850b5ec240f78676924ea0813eee-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":506,"real_height_2x":1013},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b400850b5ec240f78676924ea0813eee-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b400850b5ec240f78676924ea0813eee-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":506,"real_height_2x":1013}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"У нас появился бинарный файл (<strong>Karaulny_lemma.txt.bin</strong>). Закомментируем предыдущий код, передадим бинарный файл нашей модели (переменная <strong>model</strong>) и, используя метод <strong>KeyedVectors</strong>, загрузим этот файл в модель.","type":"p","className":""},{"data":"Теперь мы можем применить метод <strong>most_similar</strong>, который будет высчитывать контекстную близость к слову «мигрант». Попросим метод найти 200 самых близких по контексту слов. Итог запишем в новый txt-файл (<strong>Karaulny_migrant.txt</strong>).","type":"p","className":""},{"data":{"id":3309,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/031509d512eb4c4ca1a702d379af8fce-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/031509d512eb4c4ca1a702d379af8fce-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":530,"real_height_2x":1061},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/031509d512eb4c4ca1a702d379af8fce-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/031509d512eb4c4ca1a702d379af8fce-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":530,"real_height_2x":1061}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В новом файле мы увидим, какие слова чаще всего встречались в Telegram-канале «Караульный» рядом со словом «мигрант». Например, у словосочетания «массовый_драка» коэффициент близости к слову «мигрант» довольно высокий — больше 0,97. Cудя по <a href=\"https://istories.media/reportages/2021/11/23/kak-propagandisti-nagnetayut-nenavist-k-migrantam-a-mvd-obvinyaet-v-etom-inoagentov/\" data-type=\"usual\" target=\"_blank\">нашим данным</a>, канал часто пишет именно о преступлениях мигрантов.","type":"p","className":""},{"data":{"id":3308,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2b235e864d8b447a9ac4743a8477751b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2b235e864d8b447a9ac4743a8477751b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":734,"real_height_2x":1469},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2b235e864d8b447a9ac4743a8477751b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/2b235e864d8b447a9ac4743a8477751b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":734,"real_height_2x":1469}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если у вас остались вопросы по уроку —&nbsp;не стесняйтесь задавать их в <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">нашем чате</a>.","type":"p","className":""}]},{"id":381,"header":"Парсинг с помощью Python. Урок 4","_path":"/workshops/2021/11/26/parsing-s-pomoshchyu-python-urok-4/","lead":"Учимся оптимизированно переходить по ссылкам и скрейпить сайт с помощью библиотеки Scrapy","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/e71540f098cc4fb8a53dc261b7d60e36-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-11-26","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":23,"first_name":"Полина","last_name":"Ужвак","first_name_en":"Polina","last_name_en":"Uzhvak","is_public":true,"_path":"polina-uzhvak","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_2x.webp","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_2x.jpg","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_2x.webp","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_2x.jpg","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_2x.webp","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_2x.jpg","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_2x.webp","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_2x.jpg","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Автор дата-отдела","lead_en":"","position":"Автор","position_en":null,"ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Продолжаем изучать парсинг на Python. В прошлом уроке мы познакомились с библиотекой Scrapy и попробовали с ее помощью собрать информацию о книгах из одного раздела онлайн-магазина. А сегодня мы соберем информацию обо всех книгах. Сделаем это с помощью специального класса — crawlspider. Он позволяет легко и быстро искать ссылки на странице и переходить по ним. \n\n\n\nОткроем проект, с которым работали на прошлом уроке и создадим еще одного паука. Для этого переходим в папку spiders и создаем новый файл с расширением «py». Назовем его «all_books_spider.py».\n\n\n\n\nИмпорт библиотек\nКак и в прошлый раз, мы начинаем наш проект с импорта библиотеки.\n\nПишем: import scrapy\n\nКроме этого, нам нужно импортировать библиотеки, которые будут собирать ссылки со страницы. \n\nПишем:\nfrom scrapy.spiders import CrawlSpider, Rule\nfrom scrapy.linkextractors import LinkExtractor\n\n\n\n\nСоздаем класс\nКак и в прошлом уроке, создаем класс, в который запишем правила скрейпинга. Только на этот раз в скобках вместо scrapy.Spider мы напишем CrawlSpider: class BookSpider(CrawlSpider). \n\nДаем пауку имя: name = 'all_books'. Задаем начальную ссылку — это будет стартовая страница онлайн-магазина: start_urls = ['https://book24.ru/'].\n\n\n\n\nСбор ссылок\nТеперь нужно написать правило сбора ссылок. \n\nПишем: rules =. Cоздаем кортеж. Кортеж похож на список, отличие в том, что список — изменяемый тип данных, а кортеж нет. \n\n\n\n\nЧтобы понять, какое правило задать, откроем сайт. Мы видим несколько категорий с книгами. Можно переходить по ним поэтапно, собирая информацию о каждой книжке на каждой странице каждого раздела. И так пройтись по всем разделам. Ссылку для каждого перехода нам бы пришлось задавать с помощью css-селектора, как мы это делали в прошлый раз. Класс Crawl spider позволяет выполнить задачу проще и быстрее.\n\nДавайте посмотрим на ссылку одного из разделов. Например, художественная литература. \n\n\n\nСкопируем ссылку и посмотрим на нее. Чтобы эта строка не влияла на код, закомментируем ее, для этого нужно написать в начало решетку: #https://book24.ru/catalog/fiction-1592/.\n\nМы видим, что после основного названия сайта (https://book24.ru) есть слово «catalog», а затем конкретный раздел каталога: fiction. Если мы зайдем в любой другой раздел, в ссылке тоже будет слово «catalog». Значит, нам нужно создать правило, чтобы паук проходился по всем ссылкам, в которых есть «catalog». Так мы соберем все разделы. \n\nТеперь зайдем на страницу с книгой. Скопируем ссылку и посмотрим на нее. #https://book24.ru/product/portret-doriana-greya-1597309/.\n\nПосле основного названия сайта, есть слово «product». Такое слово есть на странице с каждой книгой. Значит, чтобы собрать все книги в разделе, нужно пройтись по всем ссылкам со словом «product».\n\nЗапишем наше правило: Rule(LinkExtractor(allow='catalog')). Команда allow говорит, чтобы паук перешел по всем ссылкам, в которых есть слово «catalog». С помощью deny мы могли бы задать, по ссылкам с каким словом переходить не нужно. \n\nВторым правилом зададим переход по страницам книг, то есть ссылкам со словом «product»: Rule(LinkExtractor(allow='product').\nЗа то, что паук делает на странице, отвечает callback. Ему мы передадим функцию parse_items, в которой будет лежать информация, что именно нужно собрать со страницы: Rule(LinkExtractor(allow='product'), callback='parse_items')\n\nМы получили два правила. Первое говорит пауку, что нужно пройти по всем ссылкам со словом «catalog», после этого включается второе правило, которое говорит переходить по ссылкам со словом «product» и собирать нужную информацию. \n\n\n\nФункция\nВ прошлом уроке первую созданную функцию мы называли parse. Работая с классом CrawlSpider, нельзя использовать это название. Иначе код будет работать некорректно. Это важно помнить. Поэтому мы назвали нашу функцию parse_items. Как собирать информацию со страницы книги, мы подробно разбирали на прошлом уроке. \n\nНапишем ключевое слово yield и создадим словарь. Собирать необходимые нам элементы будем с помощью css-селекторов. \n\nПуть к названию и количеству покупок скопируем из предыдущего паука.\n'name': response.css('h1.product-detail-page__title::text').get().strip(),\n'buy': response.css('p.product-detail-page__purchased-text::text').get().split()[1], \n\n\nЧтобы полученный датасет был хорошо структурирован, соберем информацию обо всех разделах, которым принадлежит книга. Они как матрешка вкладываются друг в друга. Для примера перейдем в раздел «художественная литература» → «проза» → «историческая проза» и откроем страницу с книгой. \n\n\n\nScrapy Shell\n\nЧтобы собрать информацию об этих разделах, перейдем в scrapy shell. Для этого наберем в терминале команду scrapy shell.\nПосле этого передадим команде fetch страницу книги: fetch('https://book24.ru/product/odin-den-v-drevnem-mire-zapiski-puteshestvennika-vo-vremeni-6024803/').\n\nМы увидели ответ 200, значит, с сайтом можно работать. \n\n\n\n\nПосмотрим, где лежат названия разделов. Нажмем правой кнопкой мыши, выберем «просмотреть код». Мы видим, что название раздела лежит в теге span, который вложен в тег a. \n\n\nОбратимся к нему с помощью уже известной команды response.css. Если какой-то тег вложен в другой, мы можем дописать его через пробел. Мы дописываем тег span. Слово text поможет увидеть, что именно находится в css-селекторе, к которому мы обращаемся: response.css('a.breadcrumbs__link.smartLink span::text') \n\nМы получили на выход список css-selector, в которых видим нужные слова: \nГлавная\nХудожественная литература\nПроза\nКлассическая зарубежная литература\n\n\nНам нужно достать каждый раздел по отдельности. Так как это список, обратимся по номеру элемента. Художественная литература на втором месте после раздела главная. Так как в программировании отсчет идет с нуля, обратимся к первому элементу.\n\nНапишем: response.css('a.breadcrumbs__link.smartLink span::text')[1]. На выход мы получим нужный css-селектор. \n\nЧтобы выбрать содержание селектора, допишем get(): response.css('a.breadcrumbs__link.smartLink span::text')[1].get().\n\nПробелы в строке по бокам уберем с помощью известного метода strip(): response.css('a.breadcrumbs__link.smartLink span::text')[1].get().strip().\n\n\nМы получили нужный элемент, добавим его в словарь. Ключ назовем «first_type».\n\n\nЧтобы получить следующий раздел, к которому относится книга, обратимся ко второму элементу списка: response.css('a.breadcrumbs__link.smartLink span::text')[2].get().strip()\n\nНазовем ключ «second_type»: 'second_type': response.css('a.breadcrumbs__link.smartLink span::text')[2].get().strip(). И так же достанем третий последний раздел. \n\n\nМы указали все элементы, которые нам нужно достать. Выходим из ScrapyShell — control+D\n\nЗапись в файл\n\nНам даже не нужно прописывать переход по страницам, потому что паук сам соберет все ссылки на сайте, которые соответствуют нашему правилу. Сохраняем файл и можем запускать паука. Результат запишем в csv-файл all_books.csv. Напишем команду в терминале: scrapy crawl all_books -O all_books.csv\n\nПаук начал собирать информацию обо всех книгах на сайте. Это займет около 10 минут. В папке с проектом мы видим новый документ. В нем есть информация о каждой из 16 тысяч книг. \n\n\n\n\nЭто уже полноценный датасет, который можно анализировать. Например, посмотреть, какую книгу покупали чаще всего. Попробуйте выделить пятерку самых популярных книг, результат получится неожиданный.","blocks":[{"data":"Продолжаем изучать парсинг на Python. В прошлом уроке мы познакомились с библиотекой Scrapy и попробовали с ее помощью собрать информацию о книгах из одного раздела онлайн-магазина. А сегодня мы соберем информацию обо всех книгах. Сделаем это с помощью специального класса — crawlspider. Он позволяет легко и быстро искать ссылки на странице и переходить по ним. ","type":"p","className":""},{"data":{"id":3274,"data":{"url":"https://www.youtube.com/embed/Dqp7H49T13o","text":"Съемка и монтаж: Глеб Лиманский","caption":"","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=Dqp7H49T13o","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Откроем проект, с которым работали на прошлом уроке и создадим еще одного паука. Для этого переходим в папку spiders и создаем новый файл с расширением «py». Назовем его «all_books_spider.py».","type":"p","className":""},{"data":{"id":3257,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e162b7d179284323b21ab124a981f74c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e162b7d179284323b21ab124a981f74c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":746,"real_height_2x":1492},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e162b7d179284323b21ab124a981f74c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e162b7d179284323b21ab124a981f74c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":746,"real_height_2x":1492}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Импорт библиотек","type":"h2","className":""},{"data":"Как и в прошлый раз, мы начинаем наш проект с импорта библиотеки.","type":"p","className":""},{"data":"Пишем: import scrapy","type":"p","className":""},{"data":"Кроме этого, нам нужно импортировать библиотеки, которые будут собирать ссылки со страницы.&nbsp;","type":"p","className":""},{"data":"Пишем:","type":"p","className":""},{"data":"from scrapy.spiders import CrawlSpider, Rule","type":"p","className":""},{"data":"from scrapy.linkextractors import LinkExtractor","type":"p","className":""},{"data":{"id":3258,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/78215730f2524cd1a695638d1d594ea6-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/78215730f2524cd1a695638d1d594ea6-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":556,"real_height_2x":1112},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/78215730f2524cd1a695638d1d594ea6-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/78215730f2524cd1a695638d1d594ea6-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":556,"real_height_2x":1112}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Создаем класс","type":"h2","className":""},{"data":"Как и в прошлом уроке, создаем класс, в который запишем правила скрейпинга. Только на этот раз в скобках вместо scrapy.Spider мы напишем CrawlSpider:&nbsp;class BookSpider(CrawlSpider). ","type":"p","className":""},{"data":"Даем пауку имя: name = 'all_books'. Задаем начальную ссылку — это будет стартовая страница онлайн-магазина:&nbsp;start_urls = ['<a href=\"https://book24.ru/\" data-type=\"usual\" target=\"_blank\">https://book24.ru/</a>'].","type":"p","className":""},{"data":{"id":3259,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/524217cfd0d0491bb1155334ecb3d25d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/524217cfd0d0491bb1155334ecb3d25d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":617,"real_height_2x":1234},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/524217cfd0d0491bb1155334ecb3d25d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/524217cfd0d0491bb1155334ecb3d25d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":617,"real_height_2x":1234}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Сбор ссылок","type":"h2","className":""},{"data":"Теперь нужно написать правило сбора ссылок.&nbsp;","type":"p","className":""},{"data":"Пишем: rules =. Cоздаем кортеж. Кортеж похож на список, отличие в том, что список — изменяемый тип данных, а кортеж нет.&nbsp;","type":"p","className":""},{"data":{"id":3260,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4afa5177e0254757b52295c3d4dce3b9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4afa5177e0254757b52295c3d4dce3b9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":667,"real_height_2x":1334},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4afa5177e0254757b52295c3d4dce3b9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4afa5177e0254757b52295c3d4dce3b9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":667,"real_height_2x":1334}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы понять, какое правило задать, откроем сайт.&nbsp;Мы видим несколько категорий с книгами. Можно переходить по ним поэтапно, собирая информацию о каждой книжке на каждой странице каждого раздела. И так пройтись по всем разделам. Ссылку для каждого перехода нам бы пришлось задавать с помощью css-селектора, как мы это делали в прошлый раз. Класс Crawl spider позволяет выполнить задачу проще и быстрее.","type":"p","className":""},{"data":"Давайте посмотрим на ссылку одного из разделов. Например, художественная литература.&nbsp;","type":"p","className":""},{"data":{"id":3261,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/579c91c299df47b5bb0101383a1ded6a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/579c91c299df47b5bb0101383a1ded6a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":624,"real_height_2x":1247},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/579c91c299df47b5bb0101383a1ded6a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/579c91c299df47b5bb0101383a1ded6a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":624,"real_height_2x":1247}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Скопируем ссылку и посмотрим на нее. Чтобы эта строка не влияла на код, закомментируем ее, для этого нужно написать в начало решетку: #<a href=\"https://book24.ru/catalog/fiction-1592/\" data-type=\"usual\" target=\"_blank\">https://book24.ru/catalog/fiction-1592/</a>.","type":"p","className":""},{"data":"Мы видим, что после основного названия сайта (https://book24.ru) есть слово «catalog», а затем конкретный раздел каталога: fiction. Если мы зайдем в любой другой раздел, в ссылке тоже будет слово «catalog». Значит, нам нужно создать правило, чтобы паук проходился по всем ссылкам, в которых есть «catalog». Так мы соберем все разделы.&nbsp;","type":"p","className":""},{"data":"Теперь зайдем на страницу с книгой. Скопируем ссылку и посмотрим на нее. #https://book24.ru/product/portret-doriana-greya-1597309/.","type":"p","className":""},{"data":"После основного названия сайта, есть слово «product». Такое слово есть на странице с каждой книгой. Значит, чтобы собрать все книги в разделе, нужно пройтись по всем ссылкам со словом «product».","type":"p","className":""},{"data":"Запишем наше правило: Rule(LinkExtractor(allow='catalog')). Команда allow говорит, чтобы паук перешел по всем ссылкам, в которых есть слово «catalog». С помощью deny мы могли бы задать, по ссылкам с каким словом переходить не нужно.&nbsp;","type":"p","className":""},{"data":"Вторым правилом зададим переход по страницам книг, то есть ссылкам со словом «product»: Rule(LinkExtractor(allow='product').","type":"p","className":""},{"data":"За то, что паук делает на странице, отвечает callback. Ему мы передадим функцию parse_items, в которой будет лежать информация, что именно нужно собрать со страницы: Rule(LinkExtractor(allow='product'), callback='parse_items')","type":"p","className":""},{"data":"Мы получили два правила. Первое говорит пауку, что нужно пройти по всем ссылкам со словом «catalog», после этого включается второе правило, которое говорит переходить по ссылкам со словом&nbsp;«product» и собирать нужную информацию.&nbsp;","type":"p","className":""},{"data":{"id":3262,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/de5f75efba0e42f7935b9f02427786ff-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/de5f75efba0e42f7935b9f02427786ff-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":664,"real_height_2x":1330},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/de5f75efba0e42f7935b9f02427786ff-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/de5f75efba0e42f7935b9f02427786ff-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":664,"real_height_2x":1330}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Функция","type":"h2","className":""},{"data":"В прошлом уроке первую созданную функцию мы называли parse. Работая с классом CrawlSpider, нельзя использовать это название. Иначе код будет работать некорректно. Это важно помнить. Поэтому мы назвали нашу функцию parse_items. Как собирать информацию со страницы книги, мы подробно разбирали на прошлом уроке.&nbsp;","type":"p","className":""},{"data":"Напишем ключевое слово yield и создадим словарь. Собирать необходимые нам элементы будем с помощью css-селекторов.&nbsp;","type":"p","className":""},{"data":"Путь к названию и количеству покупок скопируем из предыдущего паука.","type":"p","className":""},{"data":"'name': response.css('h1.product-detail-page__title::text').get().strip(),","type":"p","className":""},{"data":"'buy': response.css('p.product-detail-page__purchased-text::text').get().split()[1],&nbsp;","type":"p","className":""},{"data":{"id":3272,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/44034c72db1842b3b28da9f73425bd59-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/44034c72db1842b3b28da9f73425bd59-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":220,"real_height_2x":442},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/44034c72db1842b3b28da9f73425bd59-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/44034c72db1842b3b28da9f73425bd59-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":220,"real_height_2x":442}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы полученный датасет был хорошо структурирован, соберем информацию обо всех разделах, которым принадлежит книга. Они как матрешка вкладываются друг в друга. Для примера перейдем в раздел <strong>«</strong>художественная литература<strong>»</strong> <strong>→ «</strong>проза<strong>»</strong> <strong>→ «</strong>историческая проза<strong>»</strong> и откроем страницу с книгой. ","type":"p","className":""},{"data":{"id":3263,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/be4ac3efa8ab46ed996148c829027392-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/be4ac3efa8ab46ed996148c829027392-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":560,"real_height_2x":1121},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/be4ac3efa8ab46ed996148c829027392-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/be4ac3efa8ab46ed996148c829027392-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":560,"real_height_2x":1121}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Scrapy Shell","type":"h2","className":""},{"data":"Чтобы собрать информацию об этих разделах, перейдем в scrapy shell. Для этого наберем в терминале команду scrapy shell.","type":"p","className":""},{"data":"После этого передадим команде fetch страницу книги: fetch('<a href=\"https://book24.ru/product/odin-den-v-drevnem-mire-zapiski-puteshestvennika-vo-vremeni-6024803/\" data-type=\"usual\" target=\"_blank\">https://book24.ru/product/odin-den-v-drevnem-mire-zapiski-puteshestvennika-vo-vremeni-6024803/</a>').","type":"p","className":""},{"data":"Мы увидели ответ 200, значит, с сайтом можно работать.&nbsp;","type":"p","className":""},{"data":{"id":3265,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7c6d529ca4074055bce7ca87d8440bc7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7c6d529ca4074055bce7ca87d8440bc7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":306,"real_height_2x":614},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7c6d529ca4074055bce7ca87d8440bc7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7c6d529ca4074055bce7ca87d8440bc7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":306,"real_height_2x":614}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Посмотрим, где лежат названия разделов. Нажмем правой кнопкой мыши, выберем «просмотреть код».&nbsp;Мы видим, что название раздела лежит в теге span, который вложен в тег a.&nbsp;","type":"p","className":""},{"data":{"id":3266,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7353708e523a4220aba8ede532de8e0b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7353708e523a4220aba8ede532de8e0b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":662,"real_height_2x":1325},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7353708e523a4220aba8ede532de8e0b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7353708e523a4220aba8ede532de8e0b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":662,"real_height_2x":1325}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Обратимся к нему с помощью уже известной команды response.css. Если какой-то тег вложен в другой, мы можем дописать его через пробел. Мы дописываем тег span. Слово text поможет увидеть, что именно находится в css-селекторе, к которому мы обращаемся: response.css('a.breadcrumbs__link.smartLink span::text')&nbsp;","type":"p","className":""},{"data":"Мы получили на выход список css-selector, в которых видим нужные слова:&nbsp;","type":"p","className":""},{"data":"<li>Главная</li><li>Художественная литература</li><li>Проза</li><li>Классическая зарубежная литература</li>","type":"ul","className":""},{"data":{"id":3267,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/52300f7fcb8844b2bcac6b0a82e1e42d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/52300f7fcb8844b2bcac6b0a82e1e42d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":349,"real_height_2x":698},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/52300f7fcb8844b2bcac6b0a82e1e42d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/52300f7fcb8844b2bcac6b0a82e1e42d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":349,"real_height_2x":698}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Нам нужно достать каждый раздел по отдельности. Так как это список, обратимся по номеру элемента. Художественная литература на втором месте после раздела главная. Так как в программировании отсчет идет с нуля, обратимся к первому элементу.","type":"p","className":""},{"data":"Напишем: response.css('a.breadcrumbs__link.smartLink span::text')[1]. На выход мы получим нужный css-селектор.&nbsp;","type":"p","className":""},{"data":"Чтобы выбрать содержание селектора, допишем get(): response.css('a.breadcrumbs__link.smartLink span::text')[1].get().","type":"p","className":""},{"data":"Пробелы в строке по бокам уберем с помощью известного метода strip(): response.css('a.breadcrumbs__link.smartLink span::text')[1].get().strip().","type":"p","className":""},{"data":{"id":3268,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/df6a03f394b74d0f92a8490b632be410-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/df6a03f394b74d0f92a8490b632be410-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":151,"real_height_2x":302},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/df6a03f394b74d0f92a8490b632be410-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/df6a03f394b74d0f92a8490b632be410-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":151,"real_height_2x":302}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы получили нужный элемент, добавим его в словарь. Ключ назовем «first_type».","type":"p","className":""},{"data":{"id":3269,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7022f140efff49178f38458a8ea5bbc4-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7022f140efff49178f38458a8ea5bbc4-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":220,"real_height_2x":439},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7022f140efff49178f38458a8ea5bbc4-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7022f140efff49178f38458a8ea5bbc4-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":220,"real_height_2x":439}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы получить следующий раздел, к которому относится книга, обратимся ко второму элементу списка: response.css('a.breadcrumbs__link.smartLink span::text')[2].get().strip()","type":"p","className":""},{"data":"Назовем ключ «second_type»: 'second_type': response.css('a.breadcrumbs__link.smartLink span::text')[2].get().strip(). И так же достанем третий последний раздел. ","type":"p","className":""},{"data":{"id":3271,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/50d7555b363045b8942f3b3a8040c09c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/50d7555b363045b8942f3b3a8040c09c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":235,"real_height_2x":470},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/50d7555b363045b8942f3b3a8040c09c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/50d7555b363045b8942f3b3a8040c09c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":235,"real_height_2x":470}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы указали все элементы, которые нам нужно достать. Выходим из ScrapyShell — control+D","type":"p","className":""},{"data":"Запись в файл","type":"h2","className":""},{"data":"Нам даже не нужно прописывать переход по страницам, потому что паук сам соберет все ссылки на сайте, которые соответствуют нашему правилу.&nbsp;Сохраняем файл и можем запускать паука. Результат запишем в csv-файл all_books.csv. Напишем команду в терминале: scrapy crawl all_books -O all_books.csv","type":"p","className":""},{"data":"Паук начал собирать информацию обо всех книгах на сайте. Это займет около 10 минут.&nbsp;В папке с проектом мы видим новый документ. В нем есть информация о каждой из 16 тысяч книг.&nbsp;","type":"p","className":""},{"data":{"id":3273,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2eb53461df21428ab4fe91bde0378c49-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2eb53461df21428ab4fe91bde0378c49-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":612,"real_height_2x":1226},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2eb53461df21428ab4fe91bde0378c49-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/2eb53461df21428ab4fe91bde0378c49-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":612,"real_height_2x":1226}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Это уже полноценный датасет, который можно анализировать. Например, посмотреть, какую книгу покупали чаще всего.&nbsp;Попробуйте выделить пятерку самых популярных книг, результат получится неожиданный.&nbsp;","type":"p","className":""}]},{"id":378,"header":"Журналистика данных, часть 2. Особенности дата-журналистики в России и ее будущее; где и как учиться дата-журналистике, где работать","_path":"/workshops/2021/11/19/zhurnalistika-dannikh-chast-2-osobennosti-data-zhurnalistiki-v-rossii-i-yee-budushchee-gde-i-kak-uchitsya-data-zhurnalistike-gde-rabotat/","lead":"О журналистике данных в России из первых рук","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpeg","url_1x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-1920x960px_1x.jpeg","url_2x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-1920x960px_2x.jpeg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpeg","url_1x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-1272x636px_1x.jpeg","url_2x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-1272x636px_2x.jpeg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpeg","url_1x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-912x456px_1x.jpeg","url_2x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-912x456px_2x.jpeg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpeg","url_1x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-600x400px_1x.jpeg","url_2x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-600x400px_2x.jpeg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpeg","url_1x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-360x360px_1x.jpeg","url_2x":"https://static.istories.media/uploaded/images/19e921f7266f4c5d919ae6e3abd3c962-360x360px_2x.jpeg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"Фото: Shahadat Rahman / Unsplash","created_at_date":"2021-11-19","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":2517,"last_name":"","first_name":"Редакция","last_name_en":"","first_name_en":"Editors","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Дата-журналистика — это метод, с помощью которого журналисты находят данные, анализируют и рассказывают на их основе истории. В первой части мы рассказали об истории журналистики данных: как и зачем она появилась, какие СМИ в мире и в России активно применяют дата-журналистские методы в своей работе. На этот раз обсудим более практические вещи: в чем особенности дата-журналистики на русском языке, что ее ждет в будущем, какие навыки нужны для работы, где их получить и где работать.\nЧем дата-журналистика в России отличается от зарубежной\nМы опросили дата-журналистов, и они выделили два главных отличия российской дата-журналистики:\n\nИндустрия только начала развиваться и «догоняет» зарубежную.\nРасследования — главная тема журналистики данных в России.\n\nВо-первых, изначально истории на данных начали делать журналисты в США и Британии, и сейчас англоязычные издания публикуют большинство дата-материалов в мире и задают стандарты работы (подробнее об этом мы писали здесь). Журналистика данных на русском языке только формируется и «догоняет» англоязычную. \n\n«Это нормально: у них дата-журналистика развивается десятки лет, у нас совсем недолго, — объясняет дата-журналист, специалист по визуализации данных Александр Богачев. — У них гораздо больше дата-журналистов в топовых медиа умеют всё: и кодить, и писать, и понимают в анализе и визуализации данных».\n\n«Мы отстаем, наверное, в визуальной подаче, потому что мировые англоязычные издания делают какие-то потрясающие интерактивные графики чуть ли не еженедельно, у них это стоит на потоке, — добавляет редакторка дата-отдела „Важных историй“ Алеся Мароховская (Минюст включил Алесю в список СМИ-иноагентов). — У нас на это тратится больше времени и ресурсов». Аудитория, по ее словам, пока тоже не привыкла к такому формату: у российских читателей дата-материалы менее востребованы, чем у зарубежных. \n\nОсобенности российской дата-журналистики в первую очередь продиктованы тем, что сами медиа сильно отличаются, считает дата-журналист «Тинькофф-журнала»Алексей Смагин: «В России СМИ бедные и заклеймованы разными нежелательными статусами, лишь единицы могут нанять себе человека, который умеет кодить. Среди зарубежных команд же есть много заметных изданий, которые способны содержать большие дата-отделы». \n\nВо-вторых, в России журналистика данных освещает в основном политические и социальные темы, меньше — познавательные или развлекательные.\n«На конференции по дата-журналистике Lampa в мае 2021-го я попыталась подвести итоги развития индустрии, — рассказывает соосновательница „Школы данных в Кыргызстане“ Анастасия Валеева. — Тогда еще не началась волна по признанию всех иноагентами, но были обыски и аресты журналистов. Их преследовали за расследования, но тем не менее это и были дата-журналисты. Мы обсуждали это с Александром Богачевым и пришли к выводу, что, возможно, в этом и есть особенность, что дата-журналистика в России основывается на расследовательской журналистике, она из нее вышла. То есть она использует фокус расследований и методы журналистики данных. Это определяет природу дата-материалов: часто это расследования, они изобличают коррупцию, говорят о социальных проблемах».\n\nНа Западе нередко дата-отделы делают развлекательные и познавательные вещи: например, на них специализируется целое издание The Pudding. В России дата-истории, не связанные с политикой и социальными проблемами, публикует, например, «Тинькофф-журнал».\nТренды в журналистике данных. Что будет дальше\nНесмотря на то что российская дата-журналистика пока догоняет зарубежную, в этом есть свои плюсы: есть возможность проявить себя, экспериментировать, развивать индустрию. «Нам еще есть чем удивлять читателя», — заключает журналистка «Важных историй» Соня Савина. Опрошенные нами дата-журналисты выделили еще несколько важных трендов.\n\nДата-журналистика начинает развиваться в региональных медиа.\nРаботать с данными становится проще, все больше журналистов получают такие навыки.\nПовышается дата-грамотность читателей, они привыкают к графикам и цифрам.\nДата-журналистские материалы выходят из узкого круга ценителей, попадают в общеполитическую новостную повестку.\nДата-активисты — математики, аналитики — тоже начинают публиковать расследования на данных в медиа.\nИз-за политического давления становится меньше независимых СМИ, где можно работать дата-журналисту.\n\nГлавный тренд, конечно, в том, что навыки работы с данными получают все больше журналистов. Инструменты работы с данными упрощаются, каждый может их освоить. Еще несколько лет назад всё было сложнее, почти все материалы о журналистике данных были на английском языке. Из-за этого она была сконцентрирована в Москве и Санкт-Петербурге. Сейчас все больше дата-публикаций появляется в региональных СМИ. \n\nЖурналистика данных развивается и в постсоветских странах. «Сейчас разные страны подтягиваются к этому процессу, — говорит соосновательница „Школы данных в Кыргызстане“ Анастасия Валеева. — Условно Кыргызстан, маленькая страна, а за четыре года развилась так, что делает проекты по дата-журналистике мирового уровня (подробнее о дата-проектах из Кыргызстана здесь. — Прим. ред.). Это классно, это пример для регионов: сейчас уже во всем регионе Центральной Азии спонсируются программы по дата-журналистике. В России недавно был хакатон на Урале. Идет развитие. Было бы классно, если бы дата-журналистика использовалась не только для создания каких-то важных очень больших статей, но и чтобы она стала частью ежедневного инструментария чуть ли не любого журналиста наряду с телефоном или базой владельцев компаний».\nСпециалист по визуализации данных и дата-журналистике Александр Богачев заметил, что дата-журналистикой все больше занимаются не только журналисты, но гражданские активисты. Математик Сергей Шпилькин открыл для россиян графики, которые показывают, сколько голосов было украдено из-за фальсификаций на выборах — уже знаменитую «пилу Чурова» и «комету Панфиловой». «Сейчас это кажется чем-то обыденным, а тогда это было настоящей бомбой, которая в том числе привела к протестным митингам в 2011 году. То есть митинги в каком-то смысле были результатом дата-журналистики», — говорит Александр Богачев.\n\nВ 2021-м программист Петр Жижин расследовал вбросы за «Единую России» на электронном голосовании в Москве, о его выводах писали все независимые СМИ.\n\nДругой пример гражданской дата-журналистики — расследования про коронавирус демографа Алексея Ракши и аналитиков Александра Драгана и Бориса Овчинникова. С помощью анализа поисковых запросов и других показателей они доказывали, что, скорее всего, реальная заболеваемость и смертность россиян от коронавируса намного выше официальной статистики. \n\nНесмотря на множество позитивных изменений в дата-журналистике, есть и противоположный тренд — это политическое давление. Почти все издания, которые публикуют расследования, в том числе на данных, объявлены иностранными агентами («Важные истории», «Медиазона», The Insider, VTimes, телеканал «Дождь»), «Проект» стал нежелательной организацией и закрыт под угрозой уголовного преследования сотрудников. Минюст признал десятки журналистов физлицами-иноагентами, им угрожают штрафы и уголовное преследование.\n\n«Я вижу тенденцию, что журналистика в России, к сожалению, умирает, — отмечает Андрей Дорожный. — Здесь немного вариантов: либо применять свои навыки в каких-то безопасных темах — социалке, градостроительстве и подобных, либо оставаться в этой опасной журналистике с рисками».\nНо все равно дата-журналистика никуда не исчезнет, уверен Александр Богачев: «Дата-журналистика будет развиваться дальше, будет появляться больше специалистов. Чем более закрытым становится российское государство в плане данных, чем оно больше врет и скрывает, тем меньше к нему доверия — и тем больше возможностей для дата-журналистики создавать более сильные и резонансные материалы».\n\nГде работать\nВ СМИ — где уже есть дата-отделы или, наоборот, где можно стать первым дата-журналистом.\nВ государственном секторе, НКО, бизнесе. \n\nНесмотря на перечисленные сложности, дата-журналистика входит топ-100 профессий, которые будут востребованы в ближайшие 30 лет по версии РБК.\n\nВо-первых, остаются независимые СМИ, в которых можно заниматься дата-журналистикой, в том числе расследовательской. \n\nВо-вторых, в России есть еще много медиа без дата-отделов и дата-журналистов. Это открытая ниша, и можно придумывать и предлагать разным СМИ разные темы на данных. «Важнее всего уметь себя продать, а потом — занять. Важно уметь придумать, что ты будешь делать. Так как в медиа особо не понимают, что должен делать дата-журналист, то и внятных заданий ждать не стоит», — предупреждает Алексей Смагин. \n\nВ-третьих, навыки дата-журналистов востребованы в крупных компаниях — в продуктовых отделах, в PR и маркетинге, в бренд-медиа. «Сейчас все крупные компании вроде Mail, Сбера, Ozon имеют команду райтеров, редакторов. Внутри них можно писать, — подтверждает Андрей Дорожный. — Большинству компаний, в которых есть много данных, нужны люди, которые умеют эти данные интерпретировать и превращать в понятные истории. Этот навык на рынке очень востребован». По его опыту, можно просто предлагать свои умения тем брендам и организациям, которые нравятся: «Иногда нужно приходить и говорить: „привет, я умею делать вот так, давайте я буду у вас этим заниматься“, то есть проактивно искать работу».\n\nЭто тренд подтверждает «Нетология», где есть курс по дата-журналистике. Согласно их внутренним данным, абсолютное большинство студентов — гуманитарии, которые с нуля осваивают технические навыки на курсе. Половина из них — журналисты федеральных и региональных медиа. У остальных профессиональный бэкграунд в маркетинге, коммуникациях, аналитике. Они сталкиваются с тем, что внутри компании накапливается много данных, которые можно исследовать, но для этого им не хватает умений в визуализации и дата-сторителлинге. \nКакие навыки нужны дата-журналисту\nВ последние годы становится больше профессий на стыке разных дисциплин, и среди них дата-журналистика. Здесь нужны как традиционные журналистские, так и технические навыки. \n\nЖурналистские: любопытство, критическое мышление, умение увидеть интересную тему, обрабатывать большие объемы информации, привычка все перепроверять и писать простым языком.\nТехнические: знание основ математики и статистики, программирования на уровне сбора и анализа данных, навык визуализации данных, знание принципов дизайна. \n\nПо словам Андрея Дорожного, в работе очень помогает любопытство и привычка везде искать темы: «Надо во всём искать темы, в обычных вещах. Например, я вчера слушал подкаст на абстрактную тему и внезапно придумал тему для дата-материала». В работе с информацией также важно все ставить под сомнение, перепроверять, не бояться обращаться к экспертам.\nАлеся Мароховская уверена, что самое главное — это увидеть интересную тему, и любым способом найти под нее данные: в виде готового датасета, спарсить, запросить у кого-то. «Дальше уже без разницы, какими инструментами ты это будешь анализировать. Единственное, на чем я стою и буду стоять дальше: если ты не знаешь программирование, ты очень сильно ограничен в своих возможностях, тебе нужно просить кого-то, поэтому в моем понимании идеальный дата-журналист может найти тему, найти под нее данные, собрать их и обработать». \n\nВ большинстве англоязычных редакций умение программировать — обязательное требование для дата-журналиста.\n\nНо можно обойтись и без него, считает Андрей Дорожный: «Многое можно сделать и без [языка программирования] Python, тем более что во многих крупных компаниях есть отдел аналитиков, которые тебе выгрузят любые данные. Вопрос только в том, что они не могут это интерпретировать и хорошо упаковать. То есть я считаю, что навык рассказать гораздо важнее, чем навык собрать. Визуализация очень важна, большинство людей не любят цифры, но любят красивые картинки. Мы 90% информации получаем визуально. То есть сбор, анализ, обработка, интерпретация, сторителлинг, визуализация — основные вещи». \n\nГде учиться журналистике данных \nДата-журналисты в России и в мире приходят в профессию разными путями: учатся самостоятельно, оканчивают магистратуру по журналистике данных, проходят онлайн-курсы. Коротко перечислим, где можно получить нужные навыки.\n\nЕсть множество курсов, на которых можно научиться каким-то отдельным навыкам — программированию, анализу данных, визуализации, сторителлингу. Непосредственно магистерских программ по дата-журналистике на английском языке в университетах в мире не больше десяти. Например:\n\nData Journalism, Columbia University (США);\nData Journalism, University of Missouri (США);\nComputational and Data Journalism, Cardiff University (Великобритания);\nData Journalism, Birmingham City University (Великобритания);\nJournalism in Data and Investigative Journalism, University of King's College (Канада).\n\nМодули и курсы по дата-журналистике есть и в других ведущих университетах мира, начиная со Стэнфордского в США. \n\nС каждым годом становится больше онлайн-курсов на английском языке, вот несколько базовых бесплатных:\n\nКороткий вводный курс по дата-журналистике от ведущих дата-журналистов мира.\n6-недельный курс Data Journalism and Visualization with Free Tools.\nВводный курс от Google News Initiative (обучает работе в Google Sheets, Google Data Studio и других инструментах компании).\n\nНа русском языке в последние годы тоже появилось несколько программ и курсов, которые обучают дата-журналистике:\n\nМагистратура по журналистике данных в НИУ ВШЭ.\nЕдинственная магистерская программа по дата-журналистике на русском языке. Появилась в 2016 году, ее выпускники работают во многих редакциях, которые занимаются дата-журналистикой в России.\nВводный курс по дата-журналистике из 20 уроков от Андрея Дорожного на Stepik.\nЗнакомит с форматами дата-материалов и основными инструментами. \nКурс института «Стрелка» «Как стать дата-журналистом».\nПроходит с 2019 года весной, обучает журналистов, блогеров, аналитиков и медиаменеджеров работать с данными и создавать продукты для медиа.\nМастерская «Важных историй»\nЗаписываем обучающие видео по программированию, анализу и визуализации данных.\nКурс онлайн-платформы «Нетология» «Дата-журналист: истории основанные на данных».\nБольшой курс, рассчитанный 7 месяцев. Обучает всем этапам создания дата-материала, включая программирование на Python. К новому курсу можно присоединиться до конца года (промокод ISTORIES2021 дает дополнительную скидку 5% к уже действующей на сайте скидке до 45%).\n\nБольше узнать о дата-журналистике на русском можно на мероприятиях — конференции Lampa, Дне открытых данных «Инфокультуры», на хакатонах. Много интересного появляется на сайте Глобальной сети журналистов-расследователей, в соцсетях дата-журналистов и изданий с дата-отделами: Telegram-каналах Мастерской «Важных историй», «Как мы считали» «Новой газеты», Data.csv Алексея Смагина и Алеси Мароховской, «Дата-сторителлинг» Андрея Дорожного . Часто новости про дата-журналистику появляются в Telegram-чатах Open Russia Data Chat, «Курсы для журналистов», Lampa, DDJ Russian.","blocks":[{"data":"Дата-журналистика — это метод, с помощью которого журналисты находят данные, анализируют и рассказывают на их основе истории. В <a href=\"https://istories.media/workshops/2021/11/05/zhurnalistika-dannikh-chast-1-istoriya/\" data-type=\"usual\" target=\"_blank\">первой</a> части мы рассказали об истории журналистики данных: как и зачем она появилась, какие СМИ в мире и в России активно применяют дата-журналистские методы в своей работе. На этот раз обсудим более практические вещи: в чем особенности дата-журналистики на русском языке, что ее ждет в будущем, какие навыки нужны для работы, где их получить и где работать.","type":"p","className":""},{"data":"<strong>Чем дата-журналистика в России отличается от зарубежной</strong>","type":"h2","className":""},{"data":"Мы опросили дата-журналистов, и они выделили два главных отличия российской дата-журналистики:","type":"p","className":""},{"data":"<li>Индустрия только начала развиваться и «догоняет» зарубежную.</li><li>Расследования — главная тема журналистики данных в России.</li>","type":"ul","className":""},{"data":"Во-первых, изначально истории на данных начали делать журналисты в США и Британии, и сейчас англоязычные издания публикуют большинство дата-материалов в мире и задают стандарты работы (подробнее об этом мы писали <a href=\"https://istories.media/workshops/2021/11/05/zhurnalistika-dannikh-chast-1-istoriya/\" data-type=\"usual\" target=\"_blank\">здесь</a>). Журналистика данных на русском языке только формируется и «догоняет» англоязычную.&nbsp;","type":"p","className":""},{"data":"«Это нормально: у них дата-журналистика развивается десятки лет, у нас совсем недолго, — объясняет дата-журналист, специалист по визуализации данных Александр Богачев. — У них гораздо больше дата-журналистов в топовых медиа умеют всё: и кодить, и писать, и понимают в анализе и визуализации данных».","type":"p","className":""},{"data":"«Мы отстаем, наверное, в визуальной подаче, потому что мировые англоязычные издания делают какие-то потрясающие интерактивные графики чуть ли не еженедельно, у них это стоит на потоке, — добавляет редакторка дата-отдела „Важных историй“ Алеся Мароховская (Минюст включил Алесю в список СМИ-иноагентов). — У нас на это тратится больше времени и ресурсов». Аудитория, по ее словам, пока тоже не привыкла к такому формату: у российских читателей дата-материалы менее востребованы, чем у зарубежных.&nbsp;","type":"p","className":""},{"data":"Особенности российской дата-журналистики в первую очередь продиктованы тем, что сами медиа сильно отличаются, считает дата-журналист «Тинькофф-журнала»Алексей Смагин: «В России СМИ бедные и заклеймованы разными нежелательными статусами, лишь единицы могут нанять себе человека, который умеет кодить. Среди зарубежных команд же есть много заметных изданий, которые способны содержать большие дата-отделы».&nbsp;","type":"p","className":""},{"data":"Во-вторых, в России журналистика данных освещает в основном политические и социальные темы, меньше — познавательные или развлекательные.","type":"p","className":""},{"data":{"id":3237,"data":{"text":"Соосновательница «Школы данных в Кыргызстане»","author":"Анастасия Валеева","header":"Часто дата-материалы — это расследования, они изобличают коррупцию, говорят о социальных проблемах"},"category":"quotation-embed"},"type":"quotation-embed"},{"data":"«На конференции по дата-журналистике <a href=\"http://lampa2021.tilda.ws/\" data-type=\"usual\" target=\"_blank\">Lampa</a> в мае 2021-го я попыталась подвести итоги развития индустрии, —&nbsp;рассказывает соосновательница „Школы данных в Кыргызстане“ Анастасия Валеева. — Тогда еще не началась волна по признанию всех иноагентами, но были обыски и аресты журналистов. Их преследовали за расследования, но тем не менее это и были дата-журналисты. Мы обсуждали это с Александром Богачевым и пришли к выводу, что, возможно, в этом и есть особенность, что дата-журналистика в России основывается на расследовательской журналистике, она из нее вышла. То есть она использует фокус расследований и методы журналистики данных. Это определяет природу дата-материалов: часто это расследования, они изобличают коррупцию, говорят о социальных проблемах».","type":"p","className":""},{"data":"На Западе нередко дата-отделы делают развлекательные и познавательные вещи: например, на них специализируется целое издание <a href=\"https://pudding.cool/\" data-type=\"usual\" target=\"_blank\">The Pudding</a>. В России дата-истории, не связанные с политикой и социальными проблемами, публикует, например, <a href=\"https://journal.tinkoff.ru/\" data-type=\"usual\" target=\"_blank\">«Тинькофф-журнал»</a>.","type":"p","className":""},{"data":"<strong>Тренды в журналистике данных. Что будет дальше</strong>","type":"h2","className":""},{"data":"Несмотря на то что российская дата-журналистика пока догоняет зарубежную, в этом есть свои плюсы: есть возможность проявить себя, экспериментировать, развивать индустрию. «Нам еще есть чем удивлять читателя», — заключает журналистка «Важных историй» Соня Савина. Опрошенные нами дата-журналисты выделили еще несколько важных трендов.","type":"p","className":""},{"data":"<li>Дата-журналистика начинает развиваться в региональных медиа.</li><li>Работать с данными становится проще, все больше журналистов получают такие навыки.</li><li>Повышается дата-грамотность читателей, они привыкают к графикам и цифрам.</li><li>Дата-журналистские материалы выходят из узкого круга ценителей, попадают в общеполитическую новостную повестку.</li><li>Дата-активисты — математики, аналитики — тоже начинают публиковать расследования на данных в медиа.</li><li>Из-за политического давления становится меньше независимых СМИ, где можно работать дата-журналисту.</li>","type":"ul","className":""},{"data":"Главный тренд, конечно, в том, что навыки работы с данными получают все больше журналистов. Инструменты работы с данными упрощаются, каждый может их освоить. Еще несколько лет назад всё было сложнее, почти все материалы о журналистике данных были на английском языке. Из-за этого она была сконцентрирована в Москве и Санкт-Петербурге. Сейчас все больше дата-публикаций появляется в региональных СМИ.&nbsp;","type":"p","className":""},{"data":"Журналистика данных развивается и в постсоветских странах. «Сейчас разные страны подтягиваются к этому процессу, — говорит соосновательница „Школы данных в Кыргызстане“ Анастасия Валеева. — Условно Кыргызстан, маленькая страна, а за четыре года развилась так, что делает проекты по дата-журналистике мирового уровня (подробнее о дата-проектах из Кыргызстана <a href=\"https://istories.media/workshops/2021/11/05/zhurnalistika-dannikh-chast-1-istoriya/\" data-type=\"usual\" target=\"_blank\">здесь</a>. — Прим. ред.). Это классно, это пример для регионов: сейчас уже во всем регионе Центральной Азии спонсируются программы по дата-журналистике. В России недавно был хакатон на Урале. Идет развитие. Было бы классно, если бы дата-журналистика использовалась не только для создания каких-то важных очень больших статей, но и чтобы она стала частью ежедневного инструментария чуть ли не любого журналиста наряду с телефоном или базой владельцев компаний».","type":"p","className":""},{"data":{"id":3240,"data":{"text":"И первыми получайте новые расследования на данных и не только, репортажи и интервью","title":"Подпишитесь на рассылку «Важных историй»"},"category":"mailing-embed"},"type":"mailing-embed"},{"data":"Специалист по визуализации данных и дата-журналистике Александр Богачев заметил, что дата-журналистикой все больше занимаются не только журналисты, но гражданские активисты. Математик Сергей Шпилькин открыл для россиян <a href=\"https://istories.media/reportages/2021/09/21/elektronnoe-golosovanie-pamfilovoi-zaostrilo-pilu-churova/\" data-type=\"usual\" target=\"_blank\">графики</a>, которые показывают, сколько голосов было украдено из-за фальсификаций на выборах — уже знаменитую «пилу Чурова» и «комету Панфиловой». «Сейчас это кажется чем-то обыденным, а тогда это было настоящей бомбой, которая в том числе привела к протестным митингам в 2011 году. То есть митинги в каком-то смысле были результатом дата-журналистики», — говорит Александр Богачев.","type":"p","className":""},{"data":"В 2021-м программист Петр Жижин <a href=\"https://istories.media/investigations/2021/09/28/neobyasnimii-rost-chto-ne-tak-s-elektronnim-golosovaniem/\" data-type=\"usual\" target=\"_blank\">расследовал</a> вбросы за «Единую России» на электронном голосовании в Москве, о его выводах писали все независимые СМИ.","type":"p","className":""},{"data":"Другой пример гражданской дата-журналистики — расследования про коронавирус демографа <a href=\"https://discours.io/articles/social/stop-dying\" data-type=\"usual\" target=\"_blank\">Алексея Ракши</a> и аналитиков <a href=\"https://theins.ru/obshestvo/236248\" data-type=\"usual\" target=\"_blank\">Александра Драгана</a> и <a href=\"https://www.vtimes.io/2020/10/30/zapros-na-koronavirus-a1218\" data-type=\"usual\" target=\"_blank\">Бориса Овчинникова</a>. С помощью анализа поисковых запросов и других показателей они доказывали, что, скорее всего, реальная заболеваемость и смертность россиян от коронавируса намного выше официальной статистики.&nbsp;","type":"p","className":""},{"data":"Несмотря на множество позитивных изменений в дата-журналистике, есть и противоположный тренд — это политическое давление. Почти все издания, которые публикуют расследования, в том числе на данных, объявлены иностранными агентами («Важные истории», «Медиазона», The Insider, VTimes, телеканал «Дождь»), «Проект» стал нежелательной организацией и закрыт под угрозой уголовного преследования сотрудников. Минюст признал десятки журналистов физлицами-иноагентами, им угрожают штрафы и уголовное преследование.","type":"p","className":""},{"data":"«Я вижу тенденцию, что журналистика в России, к сожалению, умирает, — отмечает Андрей Дорожный. — Здесь немного вариантов: либо применять свои навыки в каких-то безопасных темах — социалке, градостроительстве и подобных, либо оставаться в этой опасной журналистике с рисками».","type":"p","className":""},{"data":{"id":3236,"data":{"text":"Специалист по визуализации данных и дата-журналистике","author":"Александр Богачев","header":"«Дата-журналистика будет развиваться дальше, будет появляться больше специалистов. Чем более закрытым становится российское государство в плане данных, чем оно больше врет и скрывает, тем меньше к нему доверия — и тем больше возможностей для дата-журналистики создавать более сильные и резонансные материалы»."},"category":"quotation-embed"},"type":"quotation-embed"},{"data":"Но все равно дата-журналистика никуда не исчезнет, уверен Александр Богачев: «Дата-журналистика будет развиваться дальше, будет появляться больше специалистов. Чем более закрытым становится российское государство в плане данных, чем оно больше врет и скрывает, тем меньше к нему доверия — и тем больше возможностей для дата-журналистики создавать более сильные и резонансные материалы».","type":"p","className":""},{"data":"<strong>Где работать</strong>","type":"p","className":""},{"data":"<li>В СМИ — где уже есть дата-отделы или, наоборот, где можно стать первым дата-журналистом.</li><li>В государственном секторе, НКО, бизнесе.&nbsp;</li>","type":"ul","className":""},{"data":"Несмотря на перечисленные сложности, дата-журналистика <a href=\"https://trends.rbc.ru/trends/education/5d6e48529a7947777002717b\" data-type=\"usual\" target=\"_blank\">входит</a> топ-100 профессий, которые будут востребованы в ближайшие 30 лет по версии РБК.","type":"p","className":""},{"data":"Во-первых, остаются независимые СМИ, в которых можно заниматься дата-журналистикой, в том числе расследовательской.&nbsp;","type":"p","className":""},{"data":"Во-вторых, в России есть еще много медиа без дата-отделов и дата-журналистов. Это открытая ниша, и можно придумывать и предлагать разным СМИ разные темы на данных. «Важнее всего уметь себя продать, а потом — занять. Важно уметь придумать, что ты будешь делать. Так как в медиа особо не понимают, что должен делать дата-журналист, то и внятных заданий ждать не стоит», — предупреждает Алексей Смагин.&nbsp;","type":"p","className":""},{"data":"В-третьих, навыки дата-журналистов востребованы в крупных компаниях — в продуктовых отделах, в PR и маркетинге, в бренд-медиа. «Сейчас все крупные компании вроде Mail, Сбера, Ozon имеют команду райтеров, редакторов. Внутри них можно писать, — подтверждает Андрей Дорожный. — Большинству компаний, в которых есть много данных, нужны люди, которые умеют эти данные интерпретировать и превращать в понятные истории. Этот навык на рынке очень востребован». По его опыту, можно просто предлагать свои умения тем брендам и организациям, которые нравятся: «Иногда нужно приходить и говорить: „привет, я умею делать вот так, давайте я буду у вас этим заниматься“, то есть проактивно искать работу».","type":"p","className":""},{"data":"Это тренд подтверждает «Нетология», где есть курс по <a href=\"http://netolo.gy/hgB\" data-type=\"usual\" target=\"_blank\">дата-журналистике</a>. Согласно их внутренним данным, абсолютное большинство студентов — гуманитарии, которые с нуля осваивают технические навыки на курсе. Половина из них — журналисты федеральных и региональных медиа. У остальных профессиональный бэкграунд в маркетинге, коммуникациях, аналитике. Они сталкиваются с тем, что внутри компании накапливается много данных, которые можно исследовать, но для этого им не хватает умений в визуализации и дата-сторителлинге.&nbsp;","type":"p","className":""},{"data":"<strong>Какие навыки нужны дата-журналисту</strong>","type":"h2","className":""},{"data":"В последние годы становится больше профессий на стыке разных дисциплин, и среди них дата-журналистика. Здесь нужны как традиционные журналистские, так и технические навыки.&nbsp;","type":"p","className":""},{"data":"<li>Журналистские: любопытство, критическое мышление, умение увидеть интересную тему, обрабатывать большие объемы информации, привычка все перепроверять и писать простым языком.</li><li>Технические: знание основ математики и статистики, программирования на уровне сбора и анализа данных, навык визуализации данных, знание принципов дизайна.&nbsp;</li>","type":"ul","className":""},{"data":"По словам Андрея Дорожного, в работе очень помогает любопытство и привычка везде искать темы: «Надо во всём искать темы, в обычных вещах. Например, я вчера слушал подкаст на абстрактную тему и внезапно придумал тему для дата-материала». В работе с информацией также важно все ставить под сомнение, перепроверять, не бояться обращаться к экспертам.","type":"p","className":""},{"data":{"id":3239,"data":{"text":"Редакторка дата-отдела «Важных историй»","author":"Алеся Мароховская","header":"На чем я стою и буду стоять дальше: если ты не знаешь программирование, ты очень сильно ограничен в своих возможностях, тебе нужно просить кого-то, ждать»."},"category":"quotation-embed"},"type":"quotation-embed"},{"data":"Алеся Мароховская уверена, что самое главное — это увидеть интересную тему, и любым способом найти под нее данные: в виде готового датасета, спарсить, запросить у кого-то. «Дальше уже без разницы, какими инструментами ты это будешь анализировать. Единственное, на чем я стою и буду стоять дальше: если ты не знаешь программирование, ты очень сильно ограничен в своих возможностях, тебе нужно просить кого-то, поэтому в моем понимании идеальный дата-журналист может найти тему, найти под нее данные, собрать их и обработать».&nbsp;","type":"p","className":""},{"data":"В большинстве англоязычных редакций умение программировать — обязательное требование для дата-журналиста.","type":"p","className":""},{"data":"Но можно обойтись и без него, считает Андрей Дорожный: «Многое можно сделать и без [языка программирования] Python, тем более что во многих крупных компаниях есть отдел аналитиков, которые тебе выгрузят любые данные. Вопрос только в том, что они не могут это интерпретировать и хорошо упаковать. То есть я считаю, что навык рассказать гораздо важнее, чем навык собрать. Визуализация очень важна, большинство людей не любят цифры, но любят красивые картинки. Мы 90% информации получаем визуально. То есть сбор, анализ, обработка, интерпретация, сторителлинг, визуализация — основные вещи».&nbsp;","type":"p","className":""},{"data":"<strong>Где учиться журналистике данных&nbsp;</strong>","type":"h2","className":""},{"data":"Дата-журналисты в России и в <a href=\"https://datajournalism.com/read/blog/learning-paths-into-data-journalism\" data-type=\"usual\" target=\"_blank\">мире</a> приходят в профессию разными путями: учатся самостоятельно, оканчивают магистратуру по журналистике данных, проходят онлайн-курсы. Коротко перечислим, где можно получить нужные навыки.","type":"p","className":""},{"data":"Есть множество курсов, на которых можно научиться каким-то отдельным навыкам — программированию, анализу данных, визуализации, сторителлингу. Непосредственно магистерских программ по дата-журналистике на английском языке в университетах в мире не больше <a href=\"https://github.com/jwyg/data-journalism-courses/blob/master/data-journalism-university-courses.csv\" data-type=\"usual\" target=\"_blank\">десяти</a>. Например:","type":"p","className":""},{"data":"<li>Data Journalism, <a href=\"https://journalism.columbia.edu/ms-data-journalism\" data-type=\"usual\" target=\"_blank\">Columbia University</a> (США);</li><li>Data Journalism, <a href=\"https://journalism.missouri.edu/programs/undergraduate/general/independent-study/data-journalism-interdisciplinary/\" data-type=\"usual\" target=\"_blank\">University of Missouri</a> (США);</li><li>Computational and Data Journalism, <a href=\"https://www.cardiff.ac.uk/study/postgraduate/taught/courses/course/computational-and-data-journalism-msc\" data-type=\"usual\" target=\"_blank\">Cardiff University</a> (Великобритания);</li><li>Data Journalism, <a href=\"http://www.bcu.ac.uk/media/courses/data-journalism-ma-2018-19\" data-type=\"usual\" target=\"_blank\">Birmingham City University</a> (Великобритания);</li><li>Journalism in Data and Investigative Journalism, <a href=\"https://ukings.ca/area-of-study/master-of-journalism-data-investigative/\" data-type=\"usual\" target=\"_blank\">University of King's College</a> (Канада).</li>","type":"ul","className":""},{"data":"Модули и курсы по дата-журналистике есть и в <a href=\"https://medium.com/ucd-ischool/where-in-the-world-can-i-study-data-journalism-44c006e55ea5\" data-type=\"usual\" target=\"_blank\">других</a> ведущих университетах мира, начиная со Стэнфордского в США.&nbsp;","type":"p","className":""},{"data":"С каждым годом становится больше онлайн-курсов на английском языке, вот несколько базовых бесплатных:","type":"p","className":""},{"data":"<li>Короткий <a href=\"https://datajournalism.com/watch/doing-journalism-with-data-first-steps-skills-and-tools\" data-type=\"usual\" target=\"_blank\">вводный курс</a> по дата-журналистике от ведущих дата-журналистов мира.</li><li>6-недельный курс <a href=\"https://journalismcourses.org/course/dataviz/\" data-type=\"usual\" target=\"_blank\">Data Journalism and Visualization with Free Tools</a>.</li><li>Вводный курс от <a href=\"https://newsinitiative.withgoogle.com/training/course/data-journalism\" data-type=\"usual\" target=\"_blank\">Google News Initiative</a> (обучает работе в Google Sheets, Google Data Studio и других инструментах компании).</li>","type":"ul","className":""},{"data":"На русском языке в последние годы тоже появилось несколько программ и курсов, которые обучают дата-журналистике:","type":"p","className":""},{"data":"<li><a href=\"https://www.hse.ru/ma/datajourn/\" data-type=\"usual\" target=\"_blank\">Магистратура</a> по журналистике данных в НИУ ВШЭ.</li>","type":"ul","className":""},{"data":"Единственная магистерская программа по дата-журналистике на русском языке. Появилась в 2016 году, ее выпускники работают во многих редакциях, которые занимаются дата-журналистикой в России.","type":"p","className":""},{"data":"<li><a href=\"https://stepik.org/course/70303/promo\" data-type=\"usual\" target=\"_blank\">Вводный курс</a> по дата-журналистике из 20 уроков от Андрея Дорожного на Stepik.</li>","type":"ul","className":""},{"data":"Знакомит с форматами дата-материалов и основными инструментами.&nbsp;","type":"p","className":""},{"data":"<li>Курс института «Стрелка» <a href=\"https://data-journalism.strelka.com\" data-type=\"usual\" target=\"_blank\">«Как стать дата-журналистом»</a>.</li>","type":"ul","className":""},{"data":"Проходит с 2019 года весной, обучает журналистов, блогеров, аналитиков и медиаменеджеров работать с данными и создавать продукты для медиа.","type":"p","className":""},{"data":"<li><a href=\"https://www.youtube.com/c/%D0%9C%D0%B0%D1%81%D1%82%D0%B5%D1%80%D1%81%D0%BA%D0%B0%D1%8F%D0%92%D0%B0%D0%B6%D0%BD%D1%8B%D1%85%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D0%B9/videos\" data-type=\"usual\" target=\"_blank\">Мастерская «Важных историй»</a></li>","type":"ul","className":""},{"data":"Записываем обучающие видео по программированию, анализу и визуализации данных.","type":"p","className":""},{"data":"<li>Курс онлайн-платформы «Нетология» <a href=\"http://netolo.gy/hgB\" data-type=\"usual\" target=\"_blank\">«Дата-журналист: истории основанные на данных»</a>.</li>","type":"ul","className":""},{"data":"Большой курс, рассчитанный 7 месяцев. Обучает всем этапам создания дата-материала, включая программирование на Python. К новому курсу можно присоединиться до конца года (<strong>промокод ISTORIES2021</strong> дает дополнительную скидку 5% к уже действующей на сайте скидке до 45%).","type":"p","className":""},{"data":"Больше узнать о дата-журналистике на русском можно на мероприятиях — конференции <a href=\"http://lampa2021.tilda.ws/\" data-type=\"usual\" target=\"_blank\">Lampa</a>, Дне открытых данных <a href=\"https://t.me/infoculture\" data-type=\"usual\" target=\"_blank\">«Инфокультуры»</a>, на хакатонах. Много интересного появляется на <a href=\"https://gijn.org/%d1%80%d0%b5%d1%81%d1%83%d1%80%d1%81%d0%bd%d1%8b%d0%b9-%d1%86%d0%b5%d0%bd%d1%82%d1%80-gijn-%d0%b3%d0%bb%d0%be%d0%b1%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d0%b9-%d1%81%d0%b5%d1%82%d0%b8-%d0%b6%d1%83%d1%80/\" data-type=\"usual\" target=\"_blank\">сайте</a> Глобальной сети журналистов-расследователей, в соцсетях дата-журналистов и изданий с дата-отделами: Telegram-каналах <a href=\"https://t.me/istories_workshop\" data-type=\"usual\" target=\"_blank\">Мастерской</a> «Важных историй», <a href=\"https://t.me/new_data\" data-type=\"usual\" target=\"_blank\">«Как мы считали»</a> «Новой газеты», <a href=\"https://t.me/data_csv\" data-type=\"usual\" target=\"_blank\">Data.csv</a> Алексея Смагина и Алеси Мароховской, <a href=\"https://t.me/data_publication\" data-type=\"usual\" target=\"_blank\">«Дата-сторителлинг»</a> Андрея Дорожного . Часто новости про дата-журналистику появляются в Telegram-чатах <a href=\"https://t.me/opendatarussiachat\" data-type=\"usual\" target=\"_blank\">Open Russia Data Chat</a>, <a href=\"https://t.me/JourElements2020\" data-type=\"usual\" target=\"_blank\">«Курсы для журналистов»</a>, <a href=\"https://t.me/lampa_2021\" data-type=\"usual\" target=\"_blank\">Lampa,</a> <a href=\"https://t.me/ddjrus\" data-type=\"usual\" target=\"_blank\">DDJ Russian</a>. ","type":"p","className":""}]},{"id":374,"header":"Парсинг с помощью Python. Урок 3","_path":"/workshops/2021/11/12/parsing-s-pomoshchyu-python-urok-3/","lead":"Учимся скрейпить сайты с помощью библиотеки Scrapy\n","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/bfb35898f44e4364b60d8d533f65fe8a-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-11-12","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":23,"first_name":"Полина","last_name":"Ужвак","first_name_en":"Polina","last_name_en":"Uzhvak","is_public":true,"_path":"polina-uzhvak","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_2x.webp","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-896x504px_2x.jpg","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_2x.webp","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-688x387px_2x.jpg","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_2x.webp","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-416x234px_2x.jpg","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_2x.webp","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a2c3a2eaa4af438c94e0f73b51cc6e26-336x189px_2x.jpg","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Автор дата-отдела","lead_en":"","position":"Автор","position_en":null,"ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Продолжаем изучать парсинг с Python. В прошлый раз мы использовали библиотеки Requests, Beautifulsoup и Selenium. Сегодня поговорим о библиотеке Scrapy. Она позволяет быстро собирать информацию с сайтов, работать с динамическими сайтами, когда информация подгружается автоматически, работать с api. На примере книжного магазина мы попробуем  разобраться, как работает эта библиотека.\n\n\n\n\nРаботать со Scrapy удобнее в редакторе Visual Studio Code. Если вы еще не знаете, как работать в VStudio и устанавливать виртуальное окружение, посмотрите уроки, где мы показывал, как написать робота для анализа госконтрактов. В них мы подробно рассказывали, как установить редактор, разбирали базовые команды в терминале, учились устанавливать и запускать виртуальное окружение. \n\nЭтот урок мы начнем с момента, когда VStudio и виртуальное окружение установлено. \n\nСоздаем проект\n\nВ редакторе мы открываем терминал. Через терминал создадим папку, где будет лежать наш проект, назовем его our_spider. Команда: mk dir our_spider. \n\nПерейдем в эту папку: cd our_spider.\n\nИ запустим виртуальное окружение: pipenv shell\n\n\n\n\nТеперь установим библиотеку: pip install scrapy\n\n\n\n\nЧтобы было легче смотреть на команды, которые мы вводим, можно иногда очищать терминал. Для этого на Mac есть горячие клавиши: control+L.\n\nСоздадим наш первый проект, назовем его bestsellers. Для этого вводим команду: scrapy startproject bestsellers. \n\nПерейдем в папку: cd bestsellers. \n\n\n\n\nОткроем эту папку и в редакторе: open folder → our_spider.\n\n\n\n\nМы видим, что в папке с проектом появилось несколько папок и файлов. Это файлы конфигурации, настройки нашего скрейпера. Подробнее о том, что содержится в каждом файле, написано в официальной документации Scrapy. Но сейчас нас эти файлы не интересуют. Мы заходим в папку spiders. В ней будут лежать пауки — это файлы, в которых мы прописываем, что именно нужно собирать на сайте. Создадим первого паука. Для этого нужно нажать на значок папки рядом с названием основной папки — bestsellers. Назовем нашего паука book_spider.py. Не забываем указывать расширение .py для питона. \n\n\n\n\nИзучаем сайт\n\nПосмотрим на сайт, с которым мы будем работать. Это онлайн-магазин Book24. Мы будем собирать информацию о книгах из раздела «бестселлеры». Для этого нужно зайти на страницу каждой книги, собрать нужную информацию, выйти и зайти на страницу уже следующей книги. И так пройти по всем книгам раздела. \n\nПрежде чем начинать писать код, посмотрим, какие команды будут доставать нужные нам элементы. Для этого перейдем в scrapy shell. Scrapy shell — это оболочка, что-то вроде отдельной комнаты, в которой можно пробовать обращаться к сайту с помощью отдельных команд и смотреть, какие ответы возвращаются. При этом не нужно писать целый код.\n\nЧтобы перейти в scrapy shell, набираем в терминале команду scrapy shell и нажимаем enter.\n\n\n\n\nТеперь обратимся к сайту, с которым будем работать. Для этого воспользуемся командой fetch. В скобках и кавычках передадим ссылку на страницу книги. В ответе мы увидели число 200. Это значит, сайт работает и готов отдавать нам информацию. \n\n\n\n\nЧтобы обратиться к сайту, воспользуемся командой response. Обращаться к элементам мы можем через css-элемент или xpath. Об этом мы уже рассказывали в прошлых уроках. Попробуем обратиться по css-элементу. \n\nНазвание книги\n\nПосмотрим, где лежит название нашей книги. Для этого нажмем правой кнопкой мыши на название и выберем «посмотреть код». Откроются элементы разработчика. Заголовок книги лежит в теге h1 c классом product-detail-page__title. Копируем его. \n\n\n\n\nВ терминале набираем response.css('h1.product-detail-page__title'). Нажимаем enter. Мы получили весь css-селектор. \n\n\n\n\nВ этой записи сложно что-то разобрать. Чтобы было легче понять, что мы достали, после названия класса напишем два двоеточия и слово text: response.css('h1.product-detail-page__title::text'). Чтобы каждый раз не переписывать команду в терминале с нуля, можно вызывать последнюю команду с помощью горячих клавиш: на Mac это стрелка вверх. \n\n\n\n\nМы получили строку, в которой есть нужный нам заголовок. Чтобы достать его, допишем в конец команды get, он выводит первый элемент из списка css-селекторов: response.css('h1.product-detail-page__title::text').get(). Мы получили нужный нам заголовок. \n\n\n\n\nЧтобы избавиться от пробелов по бокам, воспользуемся уже известным нам методом strip: response.css('h1.product-detail-page__title::text').get().strip()\n\n\n\n\nЭту команду можно скопировать в какой-нибудь текстовый документ. Она нам еще понадобится. \n\nКоличество покупок\n\nТеперь попробуем собрать информацию о количестве покупок. Она находится в теге p с классом product-detail-page__purchased-text. \n\n\n\n\nВозвращаемся в терминал. Опять пишем команду response.css, только теперь вставляем тег p и нужный класс, сразу допишем text и get: response.css('p.product-detail-page__purchased-text::text').get()\n\nМы получили строку: « Купили 939 раз ». Но мы хотим извлечь только число, для этого будем использовать уже известный нам метод split. Он разбивает строку по пробелам и возвращает список слов. \n\nНам нужен первый элемент в списке. Не забываем, что в программировании отсчет начинается с нуля: response.css('p.product-detail-page__purchased-text::text').get().split()[1]\n\n\n\n\nМы получили нужное нам число. Скопируйте или запомните эту команду, она нам понадобится. \n\nНазвание раздела\n\nТретий элемент, который мы будем собирать на странице книги — информация о разделе. Опять нажимаем на название раздела правой кнопкой мыши и выбираем «просмотреть код». \n\n\n\nМы видим, что название раздела находится в атрибуте title тега a, который вложен в тег div. Скопируем класс тега div и вернемся в терминал. \n\nНабираем команду response. Так как заголовок был вложен в атрибут тега а, после названия класса напишем тег a и через два двоеточия слово attr и в скобках название атрибута: response.css('div.product-characteristic__value a::attr(title)'). \n\n\n\nПолучили на выход список элементов. Если мы посмотрим на сайт, поймем, что это разные характеристики книги, просто они находятся в одном и том же теге. \n\n\n\n\nНужная нам характеристика лежит в третьем теге. Так как в программировании отсчет начинается с нуля, обратимся ко второму элементу списка: response.css('div.product-characteristic__value a::attr(title)')[2].get().\n\n\n\n \nМы получили название раздела, которое нам нужно. Скопируйте эту команду, она нам еще понадобится. \n\nПишем Spider\nТеперь, когда мы понимаем, как доставать нужные элементы, можем написать нашего первого паука. Для начала импортируем scrapy: import scrapy. \nВ библиотеке scrapy каждый паук, который собирает информацию, — это класс. Нам нужно создать его.\n\n\n\n\nДадим пауку имя — book24. И начальную ссылку, с которой нужно начать поиск. В нашем случае это раздел бестселлеров.\n\nПравила скрейпинга мы задаем, используя метод parse. Cтандартная запись для всех методов Scrapy: def parse(self, response):\n\n\n\n\nМы посмотрели как брать информацию со страницы книги, но сначала до этой страницы нужно добраться. А для этого нужно собрать ссылки на каждую книгу. Посмотрим, где они находятся. Для этого вернемся в терминал и передадим команде fetch ссылку на раздел бестселлеров. \n\n\n\nПосмотрим, где лежит ссылка на страницу книжек. Ссылка — это атрибут href в теге а, который вложен в тег div. \n\n\n\n\nМы можем вызвать ее так же, как вызывали название раздела, только укажем правильное название класса, а вместо атрибута title напишем href: response.css('div.product-card__image-holder a::attr(href)').get(). \n\nПишем цикл для перехода по книгам\n\nНам нужно, чтобы паук проходился по каждой ссылке и заходил в нее. Для этого напишем цикл. Скажем, что нужно проходиться по каждой ссылке из нашего списка. Здесь мы уже не дописываем get к команде response.css, потому что get выводит первый элемент из списка css-селекторов, а нам нужны ссылки на все книги. \n\n\n\n\nДля перехода по ссылке воспользуемся этого методом follow. Пишем yield, это ключевое слово в Scrapy, которое позволяет выполнить разные действия. Затем пишем response.follow и в качестве атрибута передадим нашу ссылку. А еще напишем callback — правило, по которому паук поймет, что именно нужно сделать на странице, на которую он перейдет. Если не напишем callback, паук просто перейдет по ссылке и ничего не сделает. В callback передадим новый метод parse_book.\n\n\n\n\nСобираем информацию о каждой книге\n\n\nМетод parse.book мы пишем так же, как до этого писали метод parse. В нем мы зададим, что именно нужно собирать на странице каждой книги. Для этого опять напишем ключевое слово yield и создадим словарь. Ключами в нашем словаре будут слова: name, buy и type (название книги, количество покупок, название раздела). А в качестве значений передадим команды, которые мы вызывали в scrapy shell (помните, мы советовали их скопировать).\n\n\n\nПереход по страницам\n\nНам осталось сделать добавить переход по страницам. Так как переходить на новую страницу нужно, когда собрана вся информация на первой странице, код с переходом добавим внизу метода parse. Переходить мы будем с помощью уже известного слова yield и команды response.follow. Только на этот раз переходить будем не по ссылке внутрь книги, а по сслыке на новую страницу. \n\nКак получить ссылку на следующую страницу с помощью f-строк мы рассказывали в первом уроке по скрейпингу. \n\nВ callback прописываем, что нужно сделать после перехода: зайти внутрь каждой книги. Эту задачу мы прописывали в методе parse, поэтому пишем callback=self.parse\n\n\n\nЗапускаем паука и записываем результат парсинга в файл\n\nТеперь наш паук полностью готов, осталось его запустить. Для начала нужно выйти из scrapy shell. На Mac для этого есть горячие клавиши control+d. Если мы уверены, что хотим выйти — нажимаем y на клавиатуре. Не забываем сохранить нашего паука.\n\nНабираем в терминале последнюю команду scrapy crawl, передаем название нашего парсера — book24.\nЧтобы записать данные в файл, допишем: -O book.csv. Паук соберет все данные в файл с названием book и расширением csv. \n\n\n\n\nПосле этой команды паук начал ходить по всем страницам и на каждой странице собирать информацию по каждой книжке. Мы видим, что в папке с нашим проектом появился файл book.сsv. Проверяем: если в файле лежим вся информация, которую мы хотели собрать, значит наш паук сработал правильно.\n\n\n \nЕсли у вас что-то не получилось — пишите в наш Telegram-чат, постараемся подсказать.","blocks":[{"data":"Продолжаем изучать парсинг с Python. В прошлый раз мы использовали библиотеки <a href=\"https://istories.media/workshops/2021/09/10/parsing-s-pomoshchyu-python-urok-1/\" data-type=\"usual\" target=\"_blank\">Requests</a>, <a href=\"https://istories.media/workshops/2021/09/10/parsing-s-pomoshchyu-python-urok-1/\" data-type=\"usual\" target=\"_blank\">Beautifulsoup</a> и <a href=\"https://istories.media/workshops/2021/09/20/parsing-s-pomoshchyu-python-urok-2/\" data-type=\"usual\" target=\"_blank\">Selenium</a>. Сегодня поговорим о библиотеке Scrapy. Она позволяет быстро собирать информацию с сайтов, работать с динамическими сайтами, когда информация подгружается автоматически, работать с api.&nbsp;На примере книжного магазина мы попробуем  разобраться, как работает эта библиотека.","type":"p","className":""},{"data":{"id":3173,"data":{"url":"https://www.youtube.com/embed/n6pq0RjfpEM","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=n6pq0RjfpEM","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Работать со Scrapy удобнее в редакторе Visual Studio Code. Если вы еще не знаете, как работать в VStudio и устанавливать виртуальное окружение, посмотрите уроки, где мы показывал, как написать робота для анализа госконтрактов. В них мы подробно рассказывали,&nbsp;как <a href=\"https://istories.media/workshops/2021/04/16/pishem-svoego-robota-na-python-urok-1/\" data-type=\"usual\" target=\"_blank\">установить</a> редактор, разбирали базовые команды в терминале, учились <a href=\"https://istories.media/workshops/2021/04/16/pishem-svoego-robota-na-python-urok-2/\" data-type=\"usual\" target=\"_blank\">устанавливать</a> и запускать виртуальное окружение.&nbsp;","type":"p","className":""},{"data":"Этот урок мы начнем с момента, когда VStudio и виртуальное окружение установлено.&nbsp;","type":"p","className":""},{"data":"Создаем проект","type":"h2","className":""},{"data":"В редакторе мы открываем терминал. Через терминал создадим папку, где будет лежать наш проект, назовем его our_spider. Команда: mk dir our_spider.&nbsp;","type":"p","className":""},{"data":"Перейдем в эту папку: cd our_spider.","type":"p","className":""},{"data":"И запустим виртуальное окружение: pipenv shell","type":"p","className":""},{"data":{"id":3174,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/6cfa33fc470047ffbcbd637a3072fac9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/6cfa33fc470047ffbcbd637a3072fac9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":468,"real_height_2x":936},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/6cfa33fc470047ffbcbd637a3072fac9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/6cfa33fc470047ffbcbd637a3072fac9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":468,"real_height_2x":936}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь установим библиотеку: pip install scrapy","type":"p","className":""},{"data":{"id":3175,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7566c31852424b91931c8eed128fe4d7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7566c31852424b91931c8eed128fe4d7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":352,"real_height_2x":705},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7566c31852424b91931c8eed128fe4d7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7566c31852424b91931c8eed128fe4d7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":352,"real_height_2x":705}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы было легче смотреть на команды, которые мы вводим, можно иногда очищать терминал. Для этого на Mac есть горячие клавиши: control+L.","type":"p","className":""},{"data":"Создадим наш первый проект, назовем его bestsellers. Для этого вводим команду: scrapy startproject bestsellers.&nbsp;","type":"p","className":""},{"data":"Перейдем в папку: cd bestsellers.&nbsp;","type":"p","className":""},{"data":{"id":3177,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ec8ba8713b9a4786a05f42700003e06b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ec8ba8713b9a4786a05f42700003e06b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":347,"real_height_2x":694},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ec8ba8713b9a4786a05f42700003e06b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ec8ba8713b9a4786a05f42700003e06b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":347,"real_height_2x":694}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Откроем эту папку и в редакторе: open folder → our_spider.","type":"p","className":""},{"data":{"id":3179,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b8a7d6b7ed8443c5965192e529afc615-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b8a7d6b7ed8443c5965192e529afc615-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":702,"real_height_2x":1406},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b8a7d6b7ed8443c5965192e529afc615-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b8a7d6b7ed8443c5965192e529afc615-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":702,"real_height_2x":1406}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы видим, что в папке с проектом появилось несколько папок и файлов. Это файлы конфигурации, настройки нашего скрейпера. Подробнее о том, что содержится в каждом файле, написано в официальной <a href=\"https://docs.scrapy.org/en/latest/index.html\" data-type=\"usual\" target=\"_blank\">документации</a> Scrapy. Но сейчас нас эти файлы не интересуют. Мы заходим в папку spiders. В ней будут лежать пауки <strong>— </strong>это файлы, в которых мы прописываем, что именно нужно собирать на сайте.&nbsp;Создадим первого паука. Для этого нужно нажать на значок папки рядом с названием основной папки — bestsellers.&nbsp;Назовем нашего паука book_spider.py. Не забываем указывать расширение .py для питона.&nbsp;","type":"p","className":""},{"data":{"id":3181,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c223fb09a78c4b4faad82a3f1686a891-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c223fb09a78c4b4faad82a3f1686a891-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":762,"real_height_2x":1526},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/c223fb09a78c4b4faad82a3f1686a891-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/c223fb09a78c4b4faad82a3f1686a891-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":762,"real_height_2x":1526}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Изучаем сайт","type":"h2","className":""},{"data":"Посмотрим на сайт, с которым мы будем работать. Это онлайн-магазин <a href=\"https://book24.ru/\" data-type=\"usual\" target=\"_blank\">Book24</a>. Мы будем собирать информацию о книгах из раздела «бестселлеры». Для этого нужно зайти на страницу каждой книги, собрать нужную информацию, выйти и зайти на страницу уже следующей книги. И так пройти по всем книгам раздела.&nbsp;","type":"p","className":""},{"data":"Прежде чем начинать писать код, посмотрим, какие команды будут доставать нужные нам элементы. Для этого перейдем в scrapy shell. Scrapy shell — это оболочка, что-то вроде отдельной комнаты, в которой можно пробовать обращаться к сайту с помощью отдельных команд и смотреть, какие ответы возвращаются. При этом не нужно писать целый код.","type":"p","className":""},{"data":"Чтобы перейти в scrapy shell, набираем в терминале команду scrapy shell&nbsp;и нажимаем enter.","type":"p","className":""},{"data":{"id":3185,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b3558a213a604cffa27b9f52f7858c79-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b3558a213a604cffa27b9f52f7858c79-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":452,"real_height_2x":904},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b3558a213a604cffa27b9f52f7858c79-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b3558a213a604cffa27b9f52f7858c79-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":452,"real_height_2x":904}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь обратимся к сайту, с которым будем работать. Для этого воспользуемся командой fetch. В скобках и кавычках передадим ссылку на <a href=\"https://book24.ru/product/transhumanism-inc-6015821/\" data-type=\"usual\" target=\"_blank\">страницу</a> книги.&nbsp;В ответе мы увидели число 200. Это значит,&nbsp;сайт работает и готов отдавать нам информацию.&nbsp;","type":"p","className":""},{"data":{"id":3187,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/015c7afe2b27456b8d7c9eddf9bd2a7f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/015c7afe2b27456b8d7c9eddf9bd2a7f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":380,"real_height_2x":759},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/015c7afe2b27456b8d7c9eddf9bd2a7f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/015c7afe2b27456b8d7c9eddf9bd2a7f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":380,"real_height_2x":759}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы обратиться к сайту, воспользуемся командой response. Обращаться к элементам мы можем через css-элемент или xpath. Об этом мы уже <a href=\"https://istories.media/workshops/2021/09/20/parsing-s-pomoshchyu-python-urok-2/\" data-type=\"usual\" target=\"_blank\">рассказывали</a> в прошлых уроках. Попробуем обратиться по css-элементу.&nbsp;","type":"p","className":""},{"data":"<strong>Название книги</strong>","type":"p","className":""},{"data":"Посмотрим, где лежит название нашей книги. Для этого нажмем правой кнопкой мыши на название и выберем «посмотреть код». Откроются элементы разработчика. Заголовок книги лежит в теге h1 c классом product-detail-page__title. Копируем его.&nbsp;","type":"p","className":""},{"data":{"id":3188,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/6186e0a7e1ef4935b058a5ab1e8e989d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/6186e0a7e1ef4935b058a5ab1e8e989d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":675,"real_height_2x":1350},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/6186e0a7e1ef4935b058a5ab1e8e989d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/6186e0a7e1ef4935b058a5ab1e8e989d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":675,"real_height_2x":1350}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В терминале набираем response.css('h1.product-detail-page__title'). Нажимаем enter. Мы получили весь css-селектор. ","type":"p","className":""},{"data":{"id":3189,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/aad0cf45de284d4992cc5bbab7d66ae5-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/aad0cf45de284d4992cc5bbab7d66ae5-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":112,"real_height_2x":224},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/aad0cf45de284d4992cc5bbab7d66ae5-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/aad0cf45de284d4992cc5bbab7d66ae5-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":112,"real_height_2x":224}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В этой записи сложно что-то разобрать.&nbsp;Чтобы было легче понять, что мы достали, после названия класса напишем два двоеточия и слово text: response.css('h1.product-detail-page__title::text'). Чтобы каждый раз не переписывать команду в терминале с нуля, можно вызывать последнюю команду с помощью горячих клавиш: на Mac это стрелка вверх.&nbsp;","type":"p","className":""},{"data":{"id":3190,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/00aeb49b631a43868d023694ea1d32b9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/00aeb49b631a43868d023694ea1d32b9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":178,"real_height_2x":357},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/00aeb49b631a43868d023694ea1d32b9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/00aeb49b631a43868d023694ea1d32b9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":178,"real_height_2x":357}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы получили строку, в которой есть нужный нам заголовок. Чтобы достать его, допишем в конец команды get, он выводит первый элемент из списка css-селекторов: response.css('h1.product-detail-page__title::text').get(). Мы получили нужный нам заголовок.&nbsp;","type":"p","className":""},{"data":{"id":3191,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/25cc55c4b293494d93653e3034ea826a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/25cc55c4b293494d93653e3034ea826a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":236,"real_height_2x":472},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/25cc55c4b293494d93653e3034ea826a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/25cc55c4b293494d93653e3034ea826a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":236,"real_height_2x":472}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы избавиться от пробелов по бокам, воспользуемся уже известным нам методом strip: response.css('h1.product-detail-page__title::text').get().strip()","type":"p","className":""},{"data":{"id":3192,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/159dcb6c1376446f97d6401f9c1de755-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/159dcb6c1376446f97d6401f9c1de755-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":287,"real_height_2x":574},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/159dcb6c1376446f97d6401f9c1de755-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/159dcb6c1376446f97d6401f9c1de755-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":287,"real_height_2x":574}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Эту команду можно скопировать в какой-нибудь текстовый документ. Она нам еще понадобится.&nbsp;","type":"p","className":""},{"data":"<strong>Количество покупок</strong>","type":"p","className":""},{"data":"Теперь попробуем собрать информацию о количестве покупок. Она находится в теге p с классом product-detail-page__purchased-text.&nbsp;","type":"p","className":""},{"data":{"id":3193,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8cd2500874f6433a98faf3f3b1872781-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8cd2500874f6433a98faf3f3b1872781-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":676,"real_height_2x":1351},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8cd2500874f6433a98faf3f3b1872781-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/8cd2500874f6433a98faf3f3b1872781-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":676,"real_height_2x":1351}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Возвращаемся в терминал. Опять пишем команду response.css, только теперь вставляем тег p и нужный класс, сразу допишем text и get: response.css('p.product-detail-page__purchased-text::text').get()","type":"p","className":""},{"data":"Мы получили строку: « Купили 939 раз ». Но мы хотим извлечь только число, для этого будем использовать уже известный нам метод split. Он разбивает строку по пробелам и возвращает список слов.&nbsp;","type":"p","className":""},{"data":"Нам нужен первый элемент в списке. Не забываем, что в программировании отсчет начинается с нуля: response.css('p.product-detail-page__purchased-text::text').get().split()[1]","type":"p","className":""},{"data":{"id":3195,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/00dd6f12ea7647bc8e4706b339286747-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/00dd6f12ea7647bc8e4706b339286747-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":225,"real_height_2x":450},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/00dd6f12ea7647bc8e4706b339286747-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/00dd6f12ea7647bc8e4706b339286747-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":225,"real_height_2x":450}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы получили нужное нам число. Скопируйте или запомните эту команду, она нам понадобится.&nbsp;","type":"p","className":""},{"data":"<strong>Название раздела</strong>","type":"p","className":""},{"data":"Третий элемент, который мы будем собирать на странице книги — информация о разделе. Опять нажимаем на название раздела правой кнопкой мыши и выбираем «просмотреть код».&nbsp;","type":"p","className":""},{"data":{"id":3196,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/eace2739a5ac4e8fa1572593a1c01149-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/eace2739a5ac4e8fa1572593a1c01149-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":678,"real_height_2x":1358},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/eace2739a5ac4e8fa1572593a1c01149-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/eace2739a5ac4e8fa1572593a1c01149-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":678,"real_height_2x":1358}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы видим, что название раздела находится в атрибуте title тега a, который вложен в тег div. Скопируем класс тега div и вернемся в терминал.&nbsp;","type":"p","className":""},{"data":"Набираем команду response. Так как заголовок был вложен в атрибут тега а, после названия класса напишем тег a и через два двоеточия слово attr и в скобках название атрибута:&nbsp;response.css('div.product-characteristic__value a::attr(title)').&nbsp;","type":"p","className":""},{"data":{"id":3197,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e1e3cd6f9f55444fa5274c1248bcf60e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e1e3cd6f9f55444fa5274c1248bcf60e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":236,"real_height_2x":472},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e1e3cd6f9f55444fa5274c1248bcf60e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e1e3cd6f9f55444fa5274c1248bcf60e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":236,"real_height_2x":472}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Получили на выход список элементов. Если мы посмотрим на сайт, поймем, что это разные характеристики книги, просто они находятся в одном и том же теге. ","type":"p","className":""},{"data":{"id":3198,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f526c534b8f441ed98f4488f831217bc-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f526c534b8f441ed98f4488f831217bc-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":810,"real_height_2x":1622},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f526c534b8f441ed98f4488f831217bc-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f526c534b8f441ed98f4488f831217bc-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":810,"real_height_2x":1622}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Нужная нам характеристика лежит в третьем теге. Так как в программировании отсчет начинается с нуля, обратимся ко второму элементу списка: response.css('div.product-characteristic__value a::attr(title)')[2].get().","type":"p","className":""},{"data":{"id":3199,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/aa02ebc2a4d848a590e26dd713afe73c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/aa02ebc2a4d848a590e26dd713afe73c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":296,"real_height_2x":592},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/aa02ebc2a4d848a590e26dd713afe73c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/aa02ebc2a4d848a590e26dd713afe73c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":296,"real_height_2x":592}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"&nbsp;","type":"p","className":""},{"data":"Мы получили название раздела, которое нам нужно. Скопируйте эту команду, она нам еще понадобится.&nbsp;","type":"p","className":""},{"data":"Пишем Spider","type":"h2","className":""},{"data":"Теперь, когда мы понимаем, как доставать нужные элементы, можем написать нашего первого паука.&nbsp;Для начала импортируем scrapy: import scrapy.&nbsp;","type":"p","className":""},{"data":"В библиотеке scrapy каждый паук, который собирает информацию, — это класс. Нам нужно создать его.","type":"p","className":""},{"data":{"id":3201,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/eb125572b6e9493181ec7e5012b5628f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/eb125572b6e9493181ec7e5012b5628f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":758,"real_height_2x":1515},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/eb125572b6e9493181ec7e5012b5628f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/eb125572b6e9493181ec7e5012b5628f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":758,"real_height_2x":1515}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Дадим пауку имя — book24. И начальную ссылку, с которой нужно начать поиск. В нашем случае это раздел <a href=\"https://book24.ru/knigi-bestsellery/\" data-type=\"usual\" target=\"_blank\">бестселлеров</a>.","type":"p","className":""},{"data":{"id":3200,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/70bdb5a2dcfd4928867683aa395cf53f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/70bdb5a2dcfd4928867683aa395cf53f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":643,"real_height_2x":1286},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/70bdb5a2dcfd4928867683aa395cf53f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/70bdb5a2dcfd4928867683aa395cf53f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":643,"real_height_2x":1286}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Правила скрейпинга мы задаем, используя метод parse. Cтандартная запись для всех методов Scrapy: def parse(self, response):","type":"p","className":""},{"data":{"id":3202,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e8311b0be277484db7787a7ed3d2dd55-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e8311b0be277484db7787a7ed3d2dd55-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":612,"real_height_2x":1223},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e8311b0be277484db7787a7ed3d2dd55-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e8311b0be277484db7787a7ed3d2dd55-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":612,"real_height_2x":1223}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы посмотрели как брать информацию со страницы книги, но сначала до этой страницы нужно добраться. А для этого нужно собрать ссылки на каждую книгу. Посмотрим, где они находятся.&nbsp;Для этого вернемся в терминал и передадим команде fetch ссылку на раздел бестселлеров.&nbsp;","type":"p","className":""},{"data":{"id":3204,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4fb07759b2a84b4a9de3aabea3eb99c6-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4fb07759b2a84b4a9de3aabea3eb99c6-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":116,"real_height_2x":232},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4fb07759b2a84b4a9de3aabea3eb99c6-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4fb07759b2a84b4a9de3aabea3eb99c6-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":116,"real_height_2x":232}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Посмотрим, где лежит ссылка на страницу книжек. Ссылка <strong>— </strong>это атрибут href в теге а, который вложен в тег div. ","type":"p","className":""},{"data":{"id":3205,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/0f6add3ee3a04dddb5d0944c9d782926-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/0f6add3ee3a04dddb5d0944c9d782926-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":440,"real_height_2x":880},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/0f6add3ee3a04dddb5d0944c9d782926-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/0f6add3ee3a04dddb5d0944c9d782926-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":440,"real_height_2x":880}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы можем вызвать ее так же, как вызывали название раздела, только укажем правильное название класса, а вместо атрибута title напишем href:&nbsp;response.css('div.product-card__image-holder a::attr(href)').get().&nbsp;","type":"p","className":""},{"data":{"id":3203,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1e7a4d42cadc4c2685a0093070b942f0-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1e7a4d42cadc4c2685a0093070b942f0-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":115,"real_height_2x":230},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1e7a4d42cadc4c2685a0093070b942f0-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1e7a4d42cadc4c2685a0093070b942f0-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":115,"real_height_2x":230}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Пишем цикл&nbsp;для перехода по книгам","type":"h2","className":""},{"data":"Нам нужно, чтобы паук проходился по каждой ссылке и заходил в нее. Для этого напишем цикл. Скажем, что нужно проходиться по каждой ссылке из нашего списка.&nbsp;Здесь мы уже не дописываем get к команде response.css, потому что get выводит первый элемент из списка css-селекторов, а нам нужны ссылки на все книги. ","type":"p","className":""},{"data":{"id":3207,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/fb3e3be80c594bb1a1bc2f0886ce6a17-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/fb3e3be80c594bb1a1bc2f0886ce6a17-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":348,"real_height_2x":696},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/fb3e3be80c594bb1a1bc2f0886ce6a17-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/fb3e3be80c594bb1a1bc2f0886ce6a17-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":348,"real_height_2x":696}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Для перехода по ссылке воспользуемся этого методом follow.&nbsp;Пишем&nbsp;yield, это ключевое слово в Scrapy, которое позволяет выполнить разные действия. Затем пишем response.follow и в качестве атрибута передадим нашу ссылку. А еще напишем callback — правило, по которому паук поймет, что именно нужно сделать на странице, на которую он перейдет. Если не напишем callback, паук просто перейдет по ссылке и ничего не сделает.&nbsp;В callback передадим новый метод parse_book.","type":"p","className":""},{"data":{"id":3208,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b6ab3417da064cdeb7c729296f307e41-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b6ab3417da064cdeb7c729296f307e41-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":468,"real_height_2x":936},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b6ab3417da064cdeb7c729296f307e41-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b6ab3417da064cdeb7c729296f307e41-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":468,"real_height_2x":936}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Собираем информацию о каждой книге","type":"h2","className":""},{"data":"Метод parse.book мы пишем так же, как до этого писали метод parse. В нем мы зададим, что именно нужно собирать на странице каждой книги. Для этого опять напишем ключевое слово yield и создадим словарь. Ключами в нашем словаре будут слова: name, buy и type (название книги, количество покупок, название раздела). А в качестве значений передадим команды, которые мы вызывали в scrapy shell (помните, мы советовали их скопировать).","type":"p","className":""},{"data":{"id":3209,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/6397612850204f2ab4d9e147cf97b226-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/6397612850204f2ab4d9e147cf97b226-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":606,"real_height_2x":1212},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/6397612850204f2ab4d9e147cf97b226-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/6397612850204f2ab4d9e147cf97b226-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":606,"real_height_2x":1212}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Переход по страницам","type":"h2","className":""},{"data":"Нам осталось сделать добавить переход по страницам. Так как переходить на новую страницу нужно, когда собрана вся информация на первой странице, код с переходом добавим внизу метода parse. Переходить мы будем с помощью уже известного слова yield и команды response.follow. Только на этот раз переходить будем не по ссылке внутрь книги, а по сслыке на новую страницу.&nbsp;","type":"p","className":""},{"data":"Как получить ссылку на следующую страницу с помощью f-строк мы <a href=\"https://istories.media/workshops/2021/09/10/parsing-s-pomoshchyu-python-urok-1/\" data-type=\"usual\" target=\"_blank\">рассказывали</a> в первом уроке по скрейпингу.&nbsp;","type":"p","className":""},{"data":"В callback прописываем, что нужно сделать после перехода: зайти внутрь каждой книги. Эту задачу мы прописывали в методе parse, поэтому пишем callback=self.parse","type":"p","className":""},{"data":{"id":3211,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e8e245ba371a4ebd9b2cee9a0aab800e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e8e245ba371a4ebd9b2cee9a0aab800e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":648,"real_height_2x":1296},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e8e245ba371a4ebd9b2cee9a0aab800e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e8e245ba371a4ebd9b2cee9a0aab800e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":648,"real_height_2x":1296}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Запускаем паука и записываем результат парсинга в файл","type":"h2","className":""},{"data":"Теперь наш паук полностью готов, осталось его запустить. Для начала нужно выйти из scrapy shell. На Mac для этого есть горячие клавиши control+d. Если мы уверены, что хотим выйти — нажимаем y на клавиатуре. Не забываем сохранить нашего паука.","type":"p","className":""},{"data":"Набираем в терминале последнюю команду scrapy crawl, передаем название нашего парсера —&nbsp;book24.","type":"p","className":""},{"data":"Чтобы записать данные в файл, допишем:&nbsp;-O book.csv. Паук соберет все данные в файл с названием book и расширением csv.&nbsp;","type":"p","className":""},{"data":{"id":3214,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ea49a7dca27e438faaa1dac6cdcd502c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ea49a7dca27e438faaa1dac6cdcd502c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":78,"real_height_2x":156},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ea49a7dca27e438faaa1dac6cdcd502c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ea49a7dca27e438faaa1dac6cdcd502c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":78,"real_height_2x":156}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"После этой команды паук начал ходить по всем страницам и на каждой странице собирать информацию по каждой книжке. Мы видим, что в папке с нашим проектом появился файл book.сsv. Проверяем: если в файле лежим вся информация, которую мы хотели собрать, значит наш паук сработал правильно.","type":"p","className":""},{"data":{"id":3215,"data":{"images":[{"isNarrow":false,"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/cd0200a4dca040f38d921d9a45fb66d9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/cd0200a4dca040f38d921d9a45fb66d9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":730,"real_height_2x":1460},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/cd0200a4dca040f38d921d9a45fb66d9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/cd0200a4dca040f38d921d9a45fb66d9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":730,"real_height_2x":1460}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"&nbsp;","type":"p","className":""},{"data":"Если у вас что-то не получилось — пишите в наш <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">Telegram-чат</a>, постараемся подсказать.","type":"p","className":""}]},{"id":372,"header":"Журналистика данных, часть 1. История","_path":"/workshops/2021/11/05/zhurnalistika-dannikh-chast-1-istoriya/","lead":"Обзор основных этапов в истории дата-журналистики в мире и России","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/bd24d592c67842e5968040839533b35f-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"«Атлас диаграмм по экономическим вопросам» И.Озерова, 1909","created_at_date":"2021-11-05","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":2517,"last_name":"","first_name":"Редакция","last_name_en":"","first_name_en":"Editors","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Дата-журналистика на русском языке — относительно новое явление, и по-прежнему даже в медиа не все знают, что это такое. Чтобы восполнить этот пробел, мы решили посвятить пару мастерских обсуждению журналистики данных.\n\nКакие медиа первыми начали делать дата-материалы? Кто и за что получил первые международные премии? Растет ли спрос на дата-журналистов? Чем дата-журналистика на русском языке принципиально отличается от англоязычной?\n\nМы подготовили этот обзор вместе с образовательной компанией «Нетология», где есть курс по журналистике данных. В первой части расскажем о зарождении этого направления в мире и России, а во второй — поговорим о трендах, о будущем дата-журналистики и о том, где и чему учиться и где работать.\nПочему журналистику данных называют профессией будущего \nДата-журналистами называют тех, кто в дополнение к традиционным журналистским навыкам умеет работать с данными: знает основы статистики, анализа данных и программирования и использует все это в своей работе. \n\nВ 2020 году издание РБК включило журналистику данных в список 100 профессий будущего, которые находятся на стыке разных дисциплин и будут востребованы в ближайшие 30 лет. \n\nСвязано это с тем, что объем информации в мире постоянно растет, данные накапливаются — и нужны люди, которые могут делать выводы на основе данных и представлять их аудитории в понятном и удобном виде. Умение рассказать историю на основе данных — главный навык дата-журналистов. \n\nВ более широком понимании эту сферу называют дата-сторителлинг. Дата-сторителлеров и дата-журналистов отличает от аналитиков данных именно умение найти интересную тему в данных, проанализировать их, написать текст или спродюсировать видео. Такие специалисты могут работать не только в медиа, но и в бизнесе, в некоммерческих и государственных организациях, потому что в них тоже все чаще требуются люди, которые умеют извлекать из данных смыслы и истории. \nЗачем нужна журналистика данных \nНовости сыплются на нас каждый день, и за ними трудно понять, какие процессы на самом деле происходят в обществе. С помощью журналистики данных можно взглянуть на социальные проблемы системно, а не с точки зрения разрозненных фактов и отдельных историй. \n\nВ зарубежной практике много примеров, когда дата-журналистика и расследования приводила к большим изменениям. В силу политических причин в России дата-журналистика редко напрямую приводит к каким-то действиям со стороны государства, но она подсвечивает системные проблемы, вызывает резонанс и делает незаметное очевидным. \n\nНапример, в 2019 году благодаря расследованию «Новой газеты» и «Медиазоны» (Минюст признал «Медиазону» иностранным агентом) «Я тебя сейчас, сука, убивать буду» мы узнали о колоссальном масштабе домашнего насилия в России. Авторы выяснили, что большинство осужденных за убийство женщин защищались от мужей или сожителей. Тогда директор центра помощи жертвам домашнего насилия «Насилию.нет» (признан Минюстом иностранным агентом) Анна Ривина отметила, что несмотря на то, что правозащитники и раньше знали о такой проблеме, у них не было цифр и фактов, чтобы предъявить это органам власти и показать реальные масштабы домашнего насилия. Теперь эти цифры есть. \n\nРасследование «Важных историй» о том, как полицейские с помощью «штатных» понятых фальсифицируют уголовные дела, впервые доказало массовость этой практики, о которой многие догадывались. Расследования о том, как власти скрывают число заболевших и погибших от коронавируса (например «Медиазоны», «Холода» и «Медузы» (признана Минюстом иноагентом), «Новой газеты»), напоминают людям, что пандемия еще не закончилась и нужно быть осторожными. \n\nНесмотря на отсутствие прямой обратной связи, журналистика данных помогает лучше понять, как устроено наше общество и что с ним происходит. А понимание — это уже шаг к изменениям.\nРазвитие дата-журналистики на английском языке\nДата-журналистика в России и других странах опирается в первую очередь на опыт изданий из США и Великобритании, поскольку они стали пионерами в этой области и до сих пор задают стандарты работы. Поэтому начнем рассказ с англоязычной дата-журналистики.\n\nОговоримся, что наш обзор не претендует на полное изложение истории журналистики данных. О мировом опыте уже написаны целые книги (например, вот или вот), а о русскоязычной дата-журналистике кому-то еще предстоит написать. Мы же остановимся только на некоторых этапах.\n\nДокомпьютерная эпоха. Первые графики и публикации\n\nВ поисках истоков журналистики данных можно зайти очень далеко в прошлое. Дата-журналистика ассоциируется в первую очередь с инфографикой и визуализацией данных, а они существовали еще до нашей эры. Авторы проекта Milestones предлагают считать первым образцом графического представления информации карту города Конья (сейчас это Турция) шестого тысячелетия до нашей эры. \nОднако графики в том виде, в каком мы привыкли их видеть, начали появляться в 19-м веке, когда стала накапливаться демографическая, медицинская и экономическая статистика.\n\nВ конце 18-го века шотландский экономист и инженер Уильям Плейфэр изобрел самые популярные сейчас виды визуализации данных — столбчатую диаграмму, линейный график и пайчарт (круговую диаграмму). Их можно встретить почти в каждом дата-материале. \nВ 18-м веке были опубликованы две очень важные визуализации, которые буквально спасли жизни людей. \n\nПервая — карта распространения холеры врача Джона Сноу. В 1854 году в Лондоне вспыхнула холера. Тогда считалось, что она передается воздушным путем. Но лондонский врач Джон Сноу нанес на карту случаи заражения в районе Сохо и пришел к выводу, что источником заражения была колонка для подачи водопроводной воды. Закрыв колонку, удалось остановить заболеваемость. Исследование Сноу внесло большой вклад в эпидемиологию.\nДругая важная визуализация — диаграммы сестры милосердия Флоренс Найтингейл, на которых она отмечала потери британской армии во время Крымской войны 1853–1856 годов. На диаграммах, которые теперь носят ее имя, она наглядно показала, что высокая смертность солдат связана не столько с боевыми ранами, сколько с антисанитарией. После публикации графиков в армии были проведены реформы, и смертей стало меньше.\nОтсчет именно журналистики данных, а не только инфографики известный дата-журналист Саймон Роджерс предлагает вести с 1821 года. Тогда в пилотном выпуске британской газеты Guardian было опубликовано первое дата-исследование в медиа: таблицы с данными о численности учеников школ и средних расходах на обучение. После этой публикации впервые стало известно, сколько на самом деле детей в Британии учатся бесплатно: около 25 тысяч, хотя официальная статистика говорила о 8 тысячах. \nЛюбопытно, что попытки понять, насколько официальные данные отражают реальность, с первого дата-материала Guardian и до сих пор остаются одной из главных тем в журналистике данных. В России только за последний год вышло несколько таких публикаций: например, альтернативная хроника пандемии «Новой Газеты», проект «Медиазоны» о смертности врачей, исследование «Важных историй» о реальных масштабах производственных травм, расследования про фальсификации выборов и другие.\n\nВторая половина 20 века. Первые компьютеры и журналисты-социологи \nВ 1967 году в американском Детройте произошли массовые беспорядки и погромы. Считалось, что в них участвовали в основном темнокожие малообразованные и безработные переселенцы с юга. Тогда журналист Филипп Мейер предложил изданию Detroit Free Press провести независимый опрос участников беспорядков, и его результаты оказались неожиданными. Выяснилось, что участие или неучастие в погромах не зависело от социального и экономического статуса людей. Люди с высшим образованием точно так же принимали участие в погромах, как и те, у кого его не было. А безработные южане, которых в первую очередь обвиняли в погромах, не сыграли в них большой роли. Эта публикация стала примером того, как журналистика данных может показать реальное положение дел и снизить социальную напряженность.\nЧерез несколько лет журналист Филипп Мейер, автор опроса и статьи об участниках беспорядков в Детройте, написал книгу «Precision Journalism: A Reporter’s Introduction to Social Science Methods» («Точная журналистика: введение в методы общественных наук для репортеров»). Автор утверждал: чтобы журналистика действительно была объективной, репортерам важно владеть не столько художественным словом, сколько научными методами сбора и анализа данных, основами социологии и статистики. Филипп Мейер полагал, что в первую очередь это поможет лучше отражать проблемы меньшинств и угнетаемых групп общества. До сих пор множество дата-материалов построены именно на этой идее — показать неравенство на данных.\n\nC конца 80-х годов и до сих пор журналистские расследования на данных вызывают большой резонанс. Например, в 1989 году Пулитцеровскую премию получил Билл Дедмен за расследование «Цвет денег» о том, как банки не дают кредиты темнокожим американцам с хорошими доходами. После этого Министерство юстиции обязало банки предъявлять одинаковые требования к заемщикам независимо от расы. В 1993-м победителем стал Стив Дойг за расследование «Что пошло не так?» о том, как непродуманное градостроительство повлияло на разрушения от урагана «Эндрю».\nСовременность. Дата-журналистика — новый панк!\n\n«Новым панком» журналистику данных провозгласил Саймон Роджерс, который начал вести DataBlog издания Guardian в 2009 году. Он сформулировал важные принципы дата-журналистики — прозрачность методологии и необходимость публиковать наборы данных целиком. В 2011 году Роджерс написал книгу Facts are sacred («Факты священны»), по-прежнему одну из главных в дата-журналистике.\n\nЗарождение и стремительное развитие журналистики данных в ее современном виде в 2000-х годах связано, конечно, с распространением интернета. Можно выделить три фактора, которые оказали большое влияние на формирование дата-журналистики.\n\nВо-первых, государства начали публиковать официальные открытые данные и статистику. \n\nВо-вторых, стали происходить утечки больших объемов информации, которые нужно было как-то обрабатывать и преподносить аудитории.\nВ-третьих, инструменты для создания дата-материалов с каждым годом становятся доступнее и проще: если десять лет назад анализом и визуализацией данных занимались в основном специалисты в этих областях — статисты, аналитики, дизайнеры, — то сейчас этими навыками может овладеть любой человек.\n\nВ 2010 году в Амстердаме прошла первая международная конференция по журналистике данных, после которой термин «дата-журналистика» начал упоминаться в научных статьях и на конференциях.\n\nВ том же году агентство Associated Press опубликовало серию сенсационных расследований о военных действиях США в Ираке. Журналисты проанализировали полмиллиона документов, полученных проектом Wikileaks, и визуализировали их с помощью графов и карт. Эти публикации показали огромный масштаб жертв в Ираке.\n\nЧерез пять лет Международный консорциум журналистов-расследователей получил доступ к «Панамскому досье» — утечке 11,5 миллиона документов фирмы-регистратора офшоров Mossack Fonseca. В течение года 400 журналистов из 77 стран работали над расследованиями об офшорных компаниях глав государств, чиновников, политиков и олигархов. Российскую часть расследования готовили журналисты «Новой Газеты» Роман Анин, Олеся Шмагун и Дмитрий Великовский (все признаны Минюстом иноагентами) — впоследствии авторы «Важных историй». «Панамское досье» 2016 года стало самым крупным совместным дата-журналистским расследованием в мире. Во многих странах против упомянутых чиновников и влиятельных лиц были проведены расследования, президент Исландии лишился поста. Авторы «Панамского досье» получили Пулитцеровскую премию.\n\nС тех пор происходило еще несколько крупных утечек данных об офшорах и финансовых операциях. В 2019 году было опубликовано расследование «Кошелек российской элиты» о выводе миллиардов рублей из России через серые схемы. Это стало громким событием в Европе, после которого банки были вынуждены пересмотреть подход к предотвращению «отмывания денег». Расследование получило главную награду в дата-журналистике — Sigma Awards. \n\nВ 2021 году были опубликованы «Документы Пандоры», которые по объему слитых документов даже превзошли «Панамский архив». В расследовании обеих утечек участвовали журналисты «Важных историй».\n\nНо несмотря на то, что расследования утечек информации вызывают большой общественный резонанс, чаще всего дата-журналистские материалы основаны не на них. Обычно источником служат официальные открытые данные, либо журналисты сами собирают наборы данных из разных ресурсов.\n\nОб этом можно судить по дата-материалам, которые публикуют лидеры современной дата-журналистики. Это в первую очередь команды изданий New York Times, Guardian, Financial Times, Washington Post, Wall Street Journal, Pudding, Propublica, Bloomberg, Reuters. Именно на них ориентируются все дата-журналистские команды в мире.\nТакже примеры лучших дата-материалов последних десяти лет можно найти на страницах дата-журналистских премий — Data Journalism Awards (до 2019 года) и Sigma Awards (c 2020 года). Среди работ, которые их получают, все чаще можно встретить дата-материалы на русском языке — об этом расскажем в следующей части. \n\nВ 2020 и 2021 году главной для дата-журналистики стала тема пандемии. Многие СМИ изучали и визуализировали данные о заражениях коронавирусом, о смертности и вакцинации. Самый известный материал сделало издание Washington Post. Это симуляция пандемии, которая показала, как стремительно растет число заражений, когда люди не изолируются. Эта история стала самой просматриваемой за всю историю Washington Post. \n\nДругие резонансные примеры — исчерпывающий гид по вакцинации от Reuter Graphics, хронология пандемии в данных от Financial Times, обновляемый дашборд New York Times, трекер новых штаммов коронавируса и другие дата-материалы по теме пандемии.\nИстория дата-журналистики в России\n\nДокомпьютерная эпоха. Инфографика царского и советского периода \n\nНесмотря на то что о журналистике данных в России начали говорить всего десять лет назад, а активно заниматься ей — меньше пяти лет назад, визуализация данных и печатная инфографика встречались намного раньше, минимум с 19-го века. \n\nАлексей Новичков, доцент Факультета коммуникаций, медиа и дизайна НИУ ВШЭ, экс-руководитель студии инфографики ТАСС, в своей лекции об истории российской инфографики начинает отсчет с научно-популярных журналов «Вокруг света», «Наука и жизнь» и «Огонек», где публиковались схемы различных технических изобретений.\nВ начале 20 века были изданы несколько сборников с визуализацией данных, созданных вручную. Их интересно рассматривать и сегодня. \nПомимо статистических сборников и иллюстраций в научно-популярных журналах, в СССР инфографика использовалась как средство пропаганды. Она должна была наглядно показывать достижения молодого советского государства. \nЖурнальная инфографика 2000-х и начала 2010-х\n\nВ России начала нулевых если и были журналистские расследования на данных, то это были единичные случаи. В то время активно развивалась инфографика в журналах. В отличие от современной дата-журналистики в России, она была чаще на научно-популярные темы, чем на острые социальные, и почти не отражала новостную повестку.\n\nПо мнению Алексея Новичкова, если считать инфографику оформлением материалов дата-журналистики, то пионерами в этой сфере можно назвать журнал «Всё Ясно». Он существовал с 2004 по 2007 год и полностью состоял из инфографики. \n\nТакже инфографикой занимались студия «Паровоз», газеты «Акция» и «Мой район», журналы «Русский репортер», «Большой город», «Вокруг света».\nДата-журналистика в России с 2011-го по настоящее время. Главные медиа, тексты и проекты \n\nРИА «Новости» и ТАСС\n\nВ 2010 году в Амстердаме прошла первая международная конференция по журналистике данных, а в 2011 году РИА «Новости» перевело пособие по дата-журналистике на русский язык.\n\n«До этого момента всерьез об этой профессии никто не слышал. Подразумевалось, что есть специализированные журналисты в области науки или экономики, которые имеют бэкграунд работы с данными в рамках своего профиля, но вот заниматься расследованиями или сторителлингом, основанном на данных, специализировано ещё никто не начал», — говорит Алексей Новичков, доцент факультета коммуникаций, медиа и дизайна ВШЭ, с 2011 по 2014 год работавший заместителем руководителя студии инфографики РИА «Новости».\n\nК 2012 году студия инфографики РИА стала одним из крупнейших инфографических бюро Европы и получала за свои работы награды на главных профильных конкурсах Information Is Beautiful и Malofiej. \n\nВскоре большие проекты по инфографике начал выпускать ТАСС. Проекты «Когда пришёл Наполеон», «Италия. История одного падения», и «Меркатор. О дивный плоский мир» — самые титулованные в истории российской мультимедийной инфографики.\n\nОба агентства, МИА «Россия сегодня» (до 2013 года — РИА «Новости») и ТАСС, делали и продолжают делать качественную инфографику (Алексей Новичков собрал их главные достижения в этой таблице). \n\nНо несмотря на то что именно РИА «Новости» первыми в России заговорили о журналистике данных, тематика их инфографики, как и инфографики ТАССа, была и остается познавательной и развлекательной, а не социальной и не расследовательской. \n\n«Мы смотрели на New York Times, Washington Post, Wall Street Journal, Bloomberg, — говорит Александр Богачев, который с 2014 по 2017 год был редактором и дизайнером студии инфографики МИА „Россия Сегодня“ (до 2013 называлось РИА «Новости»). — Я хотел, чтобы наши проекты были не только такими же красивыми, как у них, но чтобы они были такими же журналистскими — соответствовали актуальной повестке, имели социальную значимость. Но в РИА делать это было скорее нереально». \n\nГлавными именно дата-журналистскими материалами РИА «Новости» опрошенные нами коллеги называли те, что касались Госдумы и выборов, — например «20 лет Государственной думы», «Конфигуратор государственной думы», наглядное объяснение механики голосования на выборах в Госдуму (до сих пор актуальное) и визуализация их итогов.\n\n«Инфокультура», хакатоны и «журналистика данных» ВШЭ\n\nБольшую роль в развитии российской дата-журналистики сыграл основатель и директор проекта «Инфокультура» Иван Бегтин. Он добивался того, чтобы ведомства публиковали открытые данные в публичном доступе. \n\nХакатоны — мероприятия, где команды из программистов, дизайнеров и журналистов в короткие сроки с нуля создают дата-материалы, — тоже повлияли на формирование индустрии. Многие дата-журналисты, которые сейчас работают в СМИ, начали путь в профессию с таких хакатонов. \n\nПервый хакатон по дата-журналистике прошел в феврале 2016 года. Среди его организаторов были проект «Инфокультура» и магистерская программа по журналистике данных НИУ ВШЭ.\nВ 2016 году прошел первый набор на эту программу. Среди первых студентов были Ирина Долинина и Алеся Мараховская (обе журналистки признаны Минюстом иноагентами; работали в дата-отделе «Новой газеты», сейчас в «Важных историях»), Соня Савина (РБК, а сейчас «Важные истории»), Дада Линделл (РБК).\n\nРБК \n\nРБК стало одним из первых СМИ, которые начали заниматься не только инфографикой, а дата-журналистикой — то есть делать исследования на актуальные и социально значимые темы. Редактором отдела спецпроектов в 2017–2018 годах был Александр Богачев. Там же работали Соня Савина и Дада Линделл. \n\n«Каждое утро я читала ленту новостей и прикидывала, какую „горящую“ тему можно раскрыть через данные или интересно дополнить данными, чтобы выпустить заметку в тот же день», — рассказывает Соня Савина. Пример такого новостного материала на основе данных — публикация 2018 года о том, как во всех районах, где проходили «мусорные» протесты, результат действующего губернатора снизился по сравнению с прошлыми выборами. \n\nСреди множества дата-публикаций РБК Соня Савина отметила несколько наиболее интересных, на ее взгляд:\nанализ публикаций в соцсетях с хештегом #засобянина перед выборами мэра Москвы в 2018 году, который показал, что подавляющую часть постов в поддержку Собянина писали сотрудники его избирательного штаба;\nобновляемые графики о дипломатических конфликтах России с другими странами;\nкрасочный спецпроект с результатами президентских выборов президента 2018 года в интерактивных визуализациях;\nигра о том, как Россия жила при Путине.\n\nДата-журналистка Дада Линделл в 2019 году получила премию Data Journalism Awards за серию публикаций для РБК. В частности, за резонансное расследование о том, как в некоторых регионах России от ВИЧ умирают чаще, чем от убийств, суицида и ДТП, вместе взятых. Среди других больших расследований Дады — материалы о том, как в Москве меняют дорожное покрытие на одних и тех же улицах, как росли подмосковные свалки, как дорожали авиабилеты перед Чемпионатом мира и другие.\n«Новая Газета»\n\nВ 2018 году «Новая газета» организовала хакатон, на котором набрала первый дата-отдел в российских СМИ. До этого были отделы спецпроектов, инфографики, но дата-отдела еще нигде не было. В него вошли Андрей Заякин, Алексей Смагин, Ирина Долинина и Алеся Мароховская. \n\n«Сначала было немного странно, потому что и сама редакция не понимала, что от нас нужно, и мы сами не понимали, — рассказывает Алеся Мароховская, сейчас редакторка дата-отдела „Важных историй“. — [Главный редактор „Новой газеты“] Дмитрий Муратов рассказывал, что, когда появился дата-отдел, к нему пришел отдел культуры в расстроенных чувствах с вопросом „Мы что, плохо делаем свою работу? Зачем вы наняли целый дата-отдел, чтобы освещать даты? Мы что, плохо даты освещаем?“ Иногда к нам приходили со странными просьбами что-то нагуглить: „вот вы же с компьютерами сидите, нагуглите нам“. Приходилось долго объяснять, что мы не отдел гугления, а немного другими вещами занимаемся. Накапливался какой-то негатив к нам, потому что „вы там со своими компами сидите, долго ничего не выпускаете, еще и гуглить не хотите“. Был этап какой-то притирки. Стало проще, когда мы получили Редколлегию [за расследование о насилии над детьми], тогда коллеги немножко оттаяли и поняли, что мы не просто сидим за компами и ничего не делаем, а это всё-таки приносит какой-то толк».\n\nРасследования Алеси Мароховской и Ирины Долининой в 2018 и 2019 годах — «Кто поднимает Россию на дыбу» о пытках в колониях и «Я тебя и убью» о том, как в России смягчают наказание за издевательства над детьми, стали прорывными в плане работы с данными в журналистике. Они были сделаны на основе анализа судебных решений, в том числе методами машинного обучения. В дальнейшем судебные решения не раз становились основой дата-журналистских расследований.\n\nОдним из первых материалов дата-отдела было расследование «ВИП-кочевники», где авторы проанализировали почти 60 тысяч чиновников и с помощью программирования нашли целые кланы, которые вместе переходят с одного места работы на другое — и захватывают с собой подрядчиков-земляков. \n\nС 2020 года в «Новой» работает уже второе поколение дата-отдела: Екатерина Бонч-Осмоловская, Артем Щенников, Арнольд Хачатуров и Антонина Асанова, у которых уже успело выйти много больших текстов. Например, расследование о том, что происходит с войной в Донбассе в 2021 году, на основе данных из самых разных источников, об эпидемии ВИЧ, о школьном питании в Москве, о не-расследовании убийств в Чечне и другие.\n\nКроме того, дата-отдел «Новой» запустил альтернативный трекер COVID-19, который позволяет лучше понять, что происходит с коронавирусом в регионах по данным об избыточных смертях и поисковых запросах.\n\n«Медиазона»\n\nКогда мы спрашивали у дата-журналистов, какие у них любимые примеры журналистики данных на русском языке, многие называли два проекта «Медиазоны» 2020 года — про смертность врачей от коронавируса и «Минск избитый» о том, как в августе 2020-го силовики калечили протестующих в Беларуси.\n\nПомимо кропотливой работы с тяжелой темой и сложными данными, их отличают эмоциональные визуализации. Проект «Минск избитый» стал победителем Sigma.\nСпецифика «Медиазоны» — дата-исследования о политических преследованиях, тюрьмах, судебной системе: путеводитель по политзаключенным после зимних протестов 2021 года или исследование о том, как по следам политических процессов и протестов меняют законодательство. \n\nКак и у «Новой газеты», у «Медиазоны» есть интерактивный дашборд по коронавирусу, где помимо официальной смертности от COVID-19 показана и избыточная смертность в регионах.\n\n«Проект»\n\nВ августе 2021 года прокуратура признала издание «Проект» нежелательной организацией, и оно вынуждено было закрыться под угрозой уголовного преследования авторов. \n\nК сожалению, мы даже не можем дать ссылки на исследования «Проекта», где с 2018 по 2021 год публиковались качественные дата-исследования на самые разные темы — о том, как власти стремятся исправить статистику вместо того, чтобы решать проблемы, о загрязнении воздуха, о пожарах, о пытках в колониях, о нехватке мест в детских садах и другие.\n\n«Важные истории»\n\nС момента запуска весной 2020 года «Важные истории» делали расследования на данных, но для большей продуктивности и организованности осенью 2020-го появился целый дата-отдел. Можно сказать, что это самый крупный дата-отдел в России — в него входят пять человек.\n\nВ «Важных историях» собрались журналисты, которые уже имели большой опыт в журналистике данных, но решили немного изменить подход к историям. За год успели оформиться главные особенности дата-материалов, которые отличают «Важные истории» от других изданий, занимающихся журналистикой данных. \n\nВо-первых, помимо цифр, в них почти всегда есть личные истории людей из разных регионов страны.\n\nВо-вторых, все чаще дата-истории выходят не только в тексте, но и в формате видео. \n\nВ третьих, дата-журналисты в «Важных историях» многозадачны и проходят все этапы подготовки текста самостоятельно. \n\n«Если в РБК моей главной задачей было собрать и проанализировать данные, то теперь я отвечаю и за общение с героями материалов, и за производство визуализаций, — рассказывает Соня Савина. — А если история выходит не только в тесте, но и в видео, то пишу сценарий и работаю в кадре. У этого подхода есть свои плюсы и минусы: производство историй занимает у нас больше времени, но такое глубокое погружение в тему — от дата-раскопок до командировок по городам и селам — рождает качественные материалы, выполненные с любовью».\n\nНиже мы собрали несколько историй, где как раз хорошо видны эти особенности.\n\nЯ больше в этот ад не вернусь — я больше не хочу рожать в этой стране\n\nИсследования на данных о материнской и младенческой смертности, о сокращении мест в роддомах уже было бы достаточно, чтобы рассказать, почему в России страшно рожать детей. Но благодаря историям героев Соне Савиной удалось сделать об этом потрясающий эмоциональный текст и фильм в духе социальной дата-журналистики. \n\n«Я свидетель!» Кто помогает полицейским фальсифицировать уголовные дела за наркотики и Расходный материал «палочной» системы \n\nДва этих расследования о том, как полицейские привлекают наркозависимых понятых, чтобы фальсифицировать уголовные дела по «наркотическим» статьям, уникальны методом работы с данными. Алесе Мароховской удалось с помощью программирования подтвердить то, о чем все догадывались, и найти в судебных решениях 86 подставных понятых, которые участвовали в 269 делах.\n«Мне самой нравится тот метод, который мы использовали, чтобы доказать фальсификации уголовных дел, — говорит Алеся. — Была такая проблема, которую примерно все понимали, но ее было практически нереально доказать документально именно массово. Можно было доказывать в каждом отдельном случае, [что понятые связаны с полицейскими], разбирая каждое дело, разговаривая с адвокатами и свидетелями. А тут удалось автоматизировать процесс и найти какой-то паттерн. Лично я обожаю такие истории, когда есть красивый метод решения. Мне нравится именно то, что с не самыми простыми данными удалось обойтись программным методом и массово доказать фальсификации».\n\nВ Самаре Алеся Мароховская и Ирина Долинина несколько дней общались с бывшими оперативниками и с теми, против кого они годами фальсифицировали уголовные дела, и сняли об этом мощный фильм.\n\nРожаем как богатые — умираем как бедные. Почему в России сокращается население и Колокол, пила, топор\n\nЧуть больше года назад у «Важных историй» появились эксплейнеры в формате скроллителлинга. Вы скроллите вниз, а у вас меняются графики и выползает текст, который все объясняет. В формате скроллителлинга мы разбирались, правда ли население России сокращается из-за того, что женщины не хотят рожать, и каков был масштаб фальсификаций на голосовании по поправкам в Конституцию в 2020-м и на выборах в Госдуму в 2021-м.\nНефтяные аварии случаются каждые полчаса: исследование реальных масштабов загрязнений природы \n\nОсенью 2020 Юлия Алыкова и Полина Ужвак сделали исследование о том, что в России разливы нефти происходят каждые полчаса. «Мне очень нравится исследование про разливы нефти, потому что в нем шокирующие выводы, и интересно, что никто не догадался сделать этого раньше, — говорит Алеся Мароховская. — Когда года четыре назад в Россию приезжал журналист Вадим Макаренко из польской „Газеты Выборчей“, он спрашивал, какие у вас материалы заходят лучше всего — наверное, экология? Мы тогда ответили, что какая экология, у нас в России никому дела нет до экологии и никто в эту тему не совался. Хотя на самом деле тема экологии в мире в дата-исследованиях очень важная. И я рада, что мы начали одними из первых заниматься этим в России». \n\nЧуть больше чем за год авторы дата-отдела «Важных историй» получили четыре премии «Редколлегия».\n\nПомимо дата-команд «Важных историй», «Новой газеты», «Медиазоны» и РБК, материалы на данных, конечно, появляются и в других российских медиа. Например, у BBC резонанс вызвало расследование о том, как фермеры из Китая осваивают земли на Дальнем Востоке; у ОВД-инфо (признано иноагентом) — исследование и инфографика об иностранных агентах «Инотека»; в «Тинькофф Журнале», где работает дата-журналист Алексей Смагин, теперь тоже часто появляются исследования на данных. \n\nЧто происходит с журналистикой данных в соседних странах\n\nВ Украине самое титулованное издание, которые публикует дата-журналистику, — Texty.org.ua. С момента его основания в 2010 году авторы начали делать визуализации данных, а уже в 2012 году вошли в шорт-лист первого международного конкурса журналистики данных Data Journalism Awards с поисковиком по базе госзакупок. В 2016 они сделали оригинальную игру «Деньги, метры, два автомобиля», где предлагали читателю угадать официальный доход чиновника исходя из недвижимости и автопарка, которыми он владеет. \n\nДругой резонансный проект Texty — «Земляная проказа», в котором журналисты с помощью спутниковых данных и машинного обучения нашли места незаконной добычи янтаря. В 2020-м Texty получили премию Sigma за проект по поиску дезинформации из России с помощью методов компьютерной лингвистики и за сервис для разоблачения фейков «Фейкогрыз».\n\nВ Центральной Азии дата-журналистика развивается в первую очередь в Кыргызстане, где работает годовая стипендиальная программа по дата-журналистике международной НКО Internews и Школа Данных Кыргызстан. Школа данных организует ежегодную международную конференцию по дата-журналистике на русском языке LAMPA. В 2020 году сразу в трех кыргызских изданиях — 24.kg, kaktus.media и kloop.kg — появились дата-отделы. \n\nВ дата-отделе Kloop есть программисты, что позволяет делать сложные технические проекты. Например, «Лукошко» на основе машинного обучения. В него можно загрузить изображение любого политика и увидеть, как часто он мелькает на телевидении. Сервис «Кольца коррупции», созданный с помощью графов на основе объединенной базы госзакупок и зарегистрированных в Минюсте юридических лиц, позволяет в полуавтоматическом режиме выявлять коррупционные схемы.\n\nГлавный проект 2021 года — исследование масштабов фемицида (убийства женщин мужчинами на почве ненависти, гендерной дискриминации) в Кыргызстане «Я бы ее все равно убил», опубликованный в Kloop. По словам соосновательницы Школы Данных Кыргызстана, в прошлом главного ментора программы по дата-журналистике Internews Анастасии Валеевой, оно стало результатом многих лет работы по развитию дата-журналистики в Кыргызстане. Этот материал послужил основой для дискуссии о фемициде в Кыргызстане и всей Центральной Азии — и о том, как его остановить. Проект стал победителем международной премии по дата-журналистике Sigma.\n\nТакже Анастасия отметила дата-исследования о плачевном состоянии школ Кыргызстана и расследование о том, как Кыргызстан живет на деньги мигрантов.\n\nЧто дальше \nВо второй части нашего обзора дата-журналистики расскажем:\nо сегодняшних трендах в российской дата-журналистике и о том, что ее ждет в будущем;\nгде и зачем учиться журналистике данных и где работать.","blocks":[{"data":"Дата-журналистика на русском языке — относительно новое явление, и по-прежнему даже в медиа не все знают, что это такое. Чтобы восполнить этот пробел, мы решили посвятить пару мастерских обсуждению журналистики данных.","type":"p","className":""},{"data":"Какие медиа первыми начали делать дата-материалы? Кто и за что получил первые международные премии? Растет ли спрос на дата-журналистов? Чем дата-журналистика на русском языке принципиально отличается от англоязычной?","type":"p","className":""},{"data":"Мы подготовили этот обзор вместе с образовательной компанией «Нетология», где есть <a href=\"https://netology.ru/programs/data-journalist\" data-type=\"usual\" target=\"_blank\">курс</a> по журналистике данных. В первой части расскажем о зарождении этого направления в мире и России, а во второй — поговорим о трендах, о будущем дата-журналистики и о том, где и чему учиться и где работать.","type":"p","className":""},{"data":"<strong>Почему журналистику данных называют профессией будущего&nbsp;</strong>","type":"h2","className":""},{"data":"Дата-журналистами называют тех, кто в дополнение к традиционным журналистским навыкам умеет работать с данными: знает основы статистики, анализа данных и программирования и использует все это в своей работе.&nbsp;","type":"p","className":""},{"data":"В 2020 году издание РБК <a href=\"https://trends.rbc.ru/trends/education/5d6e48529a7947777002717b\" data-type=\"usual\" target=\"_blank\">включило</a> журналистику данных в список 100 профессий будущего, которые находятся на стыке разных дисциплин и будут востребованы в ближайшие 30 лет.&nbsp;","type":"p","className":""},{"data":"Связано это с тем, что объем информации в мире постоянно <a href=\"https://www.statista.com/statistics/871513/worldwide-data-created/\" data-type=\"usual\" target=\"_blank\">растет</a>, данные накапливаются — и нужны люди, которые могут делать выводы на основе данных и представлять их аудитории в понятном и удобном виде. Умение рассказать историю на основе данных — главный навык дата-журналистов.&nbsp;","type":"p","className":""},{"data":"В более широком понимании эту сферу называют <a href=\"https://www.nugit.co/what-is-data-storytelling/\" data-type=\"usual\" target=\"_blank\">дата-сторителлинг</a>. Дата-сторителлеров и дата-журналистов отличает от аналитиков данных именно умение найти интересную тему в данных, проанализировать их, написать текст или спродюсировать видео. Такие специалисты могут работать не только в медиа, но и в бизнесе, в некоммерческих и государственных организациях, потому что в них тоже все чаще требуются люди, которые умеют извлекать из данных смыслы и истории.&nbsp;","type":"p","className":""},{"data":"<strong>Зачем нужна журналистика данных&nbsp;</strong>","type":"h2","className":""},{"data":"Новости сыплются на нас каждый день, и за ними трудно понять, какие процессы на самом деле происходят в обществе. С помощью журналистики данных можно взглянуть на социальные проблемы системно, а не с точки зрения разрозненных фактов и отдельных историй.&nbsp;","type":"p","className":""},{"data":"В зарубежной практике много примеров, когда дата-журналистика и расследования приводила к большим изменениям. В силу политических причин в России дата-журналистика редко напрямую приводит к каким-то действиям со стороны государства, но она подсвечивает системные проблемы, вызывает резонанс и делает незаметное очевидным.&nbsp;","type":"p","className":""},{"data":"Например, в 2019 году благодаря расследованию «Новой газеты» и «Медиазоны» (Минюст признал «Медиазону» иностранным агентом) <a href=\"https://novayagazeta.ru/articles/2019/11/25/82847-ya-tebya-seychas-suka-ubivat-budu\" data-type=\"usual\" target=\"_blank\">«Я тебя сейчас, сука, убивать буду»</a> мы узнали о колоссальном масштабе домашнего насилия в России. Авторы выяснили, что большинство осужденных за убийство женщин защищались от мужей или сожителей. Тогда директор центра помощи жертвам домашнего насилия «Насилию.нет» (признан Минюстом иностранным агентом) Анна Ривина отметила, что несмотря на то, что правозащитники и раньше знали о такой проблеме, у них не было цифр и фактов, чтобы предъявить это органам власти и показать реальные масштабы домашнего насилия. Теперь эти цифры есть.&nbsp;","type":"p","className":""},{"data":"<a href=\"https://istories.media/investigations/2021/02/18/ya-svidetel-kto-pomogaet-politseiskim-falsifitsirovat-ugolovnie-dela-za-narkotiki/\" data-type=\"usual\" target=\"_blank\">Расследование</a> «Важных историй» о том, как полицейские с помощью «штатных» понятых фальсифицируют уголовные дела, впервые доказало массовость этой практики, о которой многие догадывались. Расследования о том, как власти скрывают число заболевших и погибших от коронавируса (<a href=\"https://zona.media/article/2021/07/20/29mln\" data-type=\"usual\" target=\"_blank\">например</a> «Медиазоны», «Холода» и «Медузы» (признана Минюстом иноагентом), <a href=\"https://novayagazeta.ru/coronavirus\" data-type=\"usual\" target=\"_blank\">«Новой газеты»</a>), напоминают людям, что пандемия еще не закончилась и нужно быть осторожными.&nbsp;","type":"p","className":""},{"data":"Несмотря на отсутствие прямой обратной связи, журналистика данных помогает лучше понять, как устроено наше общество и что с ним происходит. А понимание — это уже шаг к изменениям.","type":"p","className":""},{"data":"<strong>Развитие дата-журналистики на английском языке</strong>","type":"h2","className":""},{"data":"Дата-журналистика в России и других странах опирается в первую очередь на опыт изданий из США и Великобритании, поскольку они стали пионерами в этой области и до сих пор задают стандарты работы. Поэтому начнем рассказ с англоязычной дата-журналистики.","type":"p","className":""},{"data":"<em>Оговоримся, что наш обзор не претендует на полное изложение истории журналистики данных. О мировом опыте уже написаны целые книги (например, </em><a href=\"https://www.amazon.com/Infographic-Graphics-Communications-Foundations-Information/dp/0262043823\" data-type=\"usual\" target=\"_blank\"><em>вот</em></a><em> или </em><a href=\"https://gijn.org/data-journalism-books/\" data-type=\"usual\" target=\"_blank\"><em>вот</em></a><em>), а о русскоязычной дата-журналистике кому-то еще предстоит написать. Мы же остановимся только на некоторых этапах.</em>","type":"p","className":""},{"data":"<strong>Докомпьютерная эпоха. Первые графики и публикации</strong>","type":"p","className":""},{"data":"В поисках истоков журналистики данных можно зайти очень далеко в прошлое. Дата-журналистика ассоциируется в первую очередь с инфографикой и визуализацией данных, а они существовали еще до нашей эры. Авторы проекта <a href=\"https://www.datavis.ca/milestones/index.php?group=pre-1600\" data-type=\"usual\" target=\"_blank\">Milestones</a> предлагают считать первым образцом графического представления информации карту города Конья (сейчас это Турция) шестого тысячелетия до нашей эры.&nbsp;","type":"p","className":""},{"data":{"id":3101,"data":{"images":[{"credit":"Milestones Project","caption":"Карта города Конья, 6200 год до н.э. Считается самой древней картой. На ней изображены 80 домов, а сверху — извергающийся вулкан","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a36ca192c11d4df281c07ab4d00af492-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a36ca192c11d4df281c07ab4d00af492-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":685,"real_height_2x":1370},{"format":"jpeg","url_1x":"https://static.istories.media/uploaded/images/a36ca192c11d4df281c07ab4d00af492-1200xautopx_1x.jpeg","url_2x":"https://static.istories.media/uploaded/images/a36ca192c11d4df281c07ab4d00af492-1200xautopx_2x.jpeg","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":685,"real_height_2x":1370}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Однако графики в том виде, в каком мы привыкли их видеть, начали появляться в 19-м веке, когда стала накапливаться демографическая, медицинская и экономическая статистика.","type":"p","className":""},{"data":"В конце 18-го века шотландский экономист и инженер Уильям Плейфэр <a href=\"https://tableau.pro/datavizhistory\" data-type=\"usual\" target=\"_blank\">изобрел</a> самые популярные сейчас виды визуализации данных — столбчатую диаграмму, линейный график и пайчарт (круговую диаграмму). Их можно встретить почти в каждом дата-материале.&nbsp;","type":"p","className":""},{"data":{"id":3103,"data":{"images":[{"credit":"","caption":"Линейный график Уильяма Плейфэра, 1786. Показывает соотношение торгового баланса (соотношение экспорта и импорта) между Англией и Данией&Норвегией","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/dc14cc1f41164777bfc4783d9da4a542-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/dc14cc1f41164777bfc4783d9da4a542-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":886,"real_height_2x":1772},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/dc14cc1f41164777bfc4783d9da4a542-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/dc14cc1f41164777bfc4783d9da4a542-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":886,"real_height_2x":1772}]}]},"category":"image-embed"},"type":"image-embed"},{"data":{"id":3104,"data":{"images":[{"caption":"Столбчатая диаграмма Уильяма Плейфэра, 1786. Показывает торговый баланс (соотношение экспорта и импорта) между Шотландией и другими территориями","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bfe5092f1f024964b49e91cc3d1c337d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bfe5092f1f024964b49e91cc3d1c337d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":805,"real_height_2x":1610},{"format":"jpeg","url_1x":"https://static.istories.media/uploaded/images/bfe5092f1f024964b49e91cc3d1c337d-1200xautopx_1x.jpeg","url_2x":"https://static.istories.media/uploaded/images/bfe5092f1f024964b49e91cc3d1c337d-1200xautopx_2x.jpeg","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":805,"real_height_2x":1610}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В 18-м веке были опубликованы <a href=\"https://reprezent.ua/istorii_vizualizatsii\" data-type=\"usual\" target=\"_blank\">две</a> очень важные визуализации, которые буквально спасли жизни людей.&nbsp;","type":"p","className":""},{"data":"Первая — карта распространения холеры врача Джона Сноу. В 1854 году в Лондоне вспыхнула холера. Тогда считалось, что она передается воздушным путем. Но лондонский врач Джон Сноу нанес на карту случаи заражения в районе Сохо и пришел к выводу, что источником заражения была колонка для подачи водопроводной воды. Закрыв колонку, удалось остановить заболеваемость. Исследование Сноу внесло большой вклад в эпидемиологию.","type":"p","className":""},{"data":{"id":3107,"data":{"images":[{"caption":"Карта распространения холеры в Лондоне врача Джона Сноу, 1854. Черным отмечены случаи заболевания. Эта карта позволила понять, что холера передается не воздушным путем, как думали раньше, а фекально-оральным путем через водопроводную систему, потому что случаи заболевания сосредоточились вокруг одной колонки для подачи воды","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/49f903ed09db4da08238468d96d9ee40-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/49f903ed09db4da08238468d96d9ee40-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1126,"real_height_2x":2251},{"format":"jpeg","url_1x":"https://static.istories.media/uploaded/images/49f903ed09db4da08238468d96d9ee40-1200xautopx_1x.jpeg","url_2x":"https://static.istories.media/uploaded/images/49f903ed09db4da08238468d96d9ee40-1200xautopx_2x.jpeg","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1126,"real_height_2x":2251}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Другая важная визуализация — <a href=\"http://vivovoco.astronet.ru/VV/JOURNAL/SCIAM/FLORENCE/FLORENCE.HTM\" data-type=\"usual\" target=\"_blank\">диаграммы</a> сестры милосердия Флоренс Найтингейл, на которых она отмечала потери британской армии во время Крымской войны 1853–1856 годов. На диаграммах, которые теперь носят ее имя, она наглядно показала, что высокая смертность солдат связана не столько с боевыми ранами, сколько с антисанитарией. После публикации графиков в армии были проведены реформы, и смертей стало меньше.","type":"p","className":""},{"data":{"id":3108,"data":{"images":[{"caption":"Диаграммы сестры милосердия Флоренс Найтингейл, 1858. Показывают, как много смертей в армии вызваны не боевыми ранами, а антисанитарией","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/fa5cf6ed79dc4113985bac8aa9558ebd-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/fa5cf6ed79dc4113985bac8aa9558ebd-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":656,"real_height_2x":1312},{"format":"jpeg","url_1x":"https://static.istories.media/uploaded/images/fa5cf6ed79dc4113985bac8aa9558ebd-1200xautopx_1x.jpeg","url_2x":"https://static.istories.media/uploaded/images/fa5cf6ed79dc4113985bac8aa9558ebd-1200xautopx_2x.jpeg","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":656,"real_height_2x":1312}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Отсчет именно журналистики данных, а не только инфографики известный дата-журналист <a href=\"https://simonrogers.net/about/\" data-type=\"usual\" target=\"_blank\">Саймон Роджерс</a> предлагает вести с 1821 года. Тогда в пилотном выпуске британской газеты Guardian было <a href=\"https://www.theguardian.com/news/datablog/2011/sep/26/data-journalism-guardian\" data-type=\"usual\" target=\"_blank\">опубликовано</a> первое дата-исследование в медиа: таблицы с данными о численности учеников школ и средних расходах на обучение. После этой публикации впервые стало известно, сколько на самом деле детей в Британии учатся бесплатно: около 25 тысяч, хотя официальная статистика говорила о 8 тысячах.&nbsp;","type":"p","className":""},{"data":{"id":3149,"data":{"images":[{"credit":"DataBlog The Guardian","caption":"Фрагмент таблицы с численностью учеников школ в Англии и расходами на обучение, 1821. Считается первым примером дата-журналистики","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a014e78efb52425cb4e50b97ad86e060-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a014e78efb52425cb4e50b97ad86e060-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":580,"real_height_2x":1162},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a014e78efb52425cb4e50b97ad86e060-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a014e78efb52425cb4e50b97ad86e060-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":580,"real_height_2x":1162}]},{"credit":"DataBlog The Guardian","caption":"Оцифрованный фрагмент той же таблицы 1821 года","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b4d7285f01434947a24ab10391280eee-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b4d7285f01434947a24ab10391280eee-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":580,"real_height_2x":1162},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b4d7285f01434947a24ab10391280eee-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b4d7285f01434947a24ab10391280eee-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":580,"real_height_2x":1162}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Любопытно, что попытки понять, насколько официальные данные отражают реальность, с первого дата-материала Guardian и до сих пор остаются одной из главных тем в журналистике данных. В России только за последний год вышло несколько таких публикаций: например, альтернативная <a href=\"https://novayagazeta.ru/coronavirus\" data-type=\"usual\" target=\"_blank\">хроника</a> пандемии «Новой Газеты», <a href=\"https://zona.media/article/2020/05/19/martyrology\" data-type=\"usual\" target=\"_blank\">проект</a> «Медиазоны» о смертности врачей, <a href=\"https://istories.media/investigations/2021/06/10/nadoelo-uzhe-khoronit-tovarishchei/\" data-type=\"usual\" target=\"_blank\">исследование</a> «Важных историй» о реальных масштабах производственных травм, <a href=\"https://istories.media/reportages/2021/09/21/elektronnoe-golosovanie-pamfilovoi-zaostrilo-pilu-churova/\" data-type=\"usual\" target=\"_blank\">расследования</a> про фальсификации выборов и другие.","type":"p","className":""},{"data":"<strong>Вторая половина 20 века. Первые компьютеры и журналисты-социологи&nbsp;</strong>","type":"p","className":""},{"data":"В 1967 году в американском Детройте <a href=\"https://www.britannica.com/event/Detroit-Riot-of-1967\" data-type=\"usual\" target=\"_blank\">произошли</a> массовые беспорядки и погромы. Считалось, что в них участвовали в основном темнокожие малообразованные и безработные переселенцы с юга. Тогда журналист Филипп Мейер <a href=\"https://isr.umich.edu/news-events/insights-newsletter/article/revealing-the-roots-of-a-riot/\" data-type=\"usual\" target=\"_blank\">предложил</a> изданию Detroit Free Press провести независимый опрос участников беспорядков, и его результаты оказались неожиданными. Выяснилось, что участие или неучастие в погромах не зависело от социального и экономического статуса людей. Люди с высшим образованием точно так же принимали участие в погромах, как и те, у кого его не было. А безработные южане, которых в первую очередь обвиняли в погромах, не сыграли в них большой роли. Эта публикация стала примером того, как журналистика данных может показать реальное положение дел и снизить социальную напряженность.","type":"p","className":""},{"data":{"id":3111,"data":{"images":[{"credit":"Philip Meyer","caption":"Сенсационная публикация Detroit Free Press об участниках беспорядков 1967 года, один из первых примеров применения методов сбора и анализа данных в журналистике","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4cb4c0e3ce934756bf44e2192eab3cc9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4cb4c0e3ce934756bf44e2192eab3cc9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4cb4c0e3ce934756bf44e2192eab3cc9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4cb4c0e3ce934756bf44e2192eab3cc9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":400,"real_height_2x":800}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Через несколько лет журналист Филипп Мейер, автор опроса и статьи об участниках беспорядков в Детройте, написал <a href=\"https://books.google.com.tr/books/about/Precision_Journalism.html?id=uUzT0M_lPbYC&amp;redir_esc=y\" data-type=\"usual\" target=\"_blank\">книгу</a> «Precision Journalism: A Reporter’s Introduction to Social Science Methods» («Точная журналистика: введение в методы общественных наук для репортеров»). Автор утверждал: чтобы журналистика действительно была объективной, репортерам важно владеть не столько художественным словом, сколько научными методами сбора и анализа данных, основами социологии и статистики. Филипп Мейер полагал, что в первую очередь это поможет лучше отражать проблемы меньшинств и угнетаемых групп общества. До сих пор множество дата-материалов построены именно на этой идее — показать неравенство на данных.","type":"p","className":""},{"data":"C конца 80-х годов и до сих пор журналистские расследования на данных вызывают большой резонанс. Например, в 1989 году Пулитцеровскую премию получил Билл Дедмен за расследование <a href=\"http://powerreporting.com/color/\" data-type=\"usual\" target=\"_blank\">«Цвет денег»</a> о том, как банки не дают кредиты темнокожим американцам с хорошими доходами. После этого Министерство юстиции обязало банки предъявлять одинаковые требования к заемщикам независимо от расы. В 1993-м победителем стал Стив Дойг за расследование <a href=\"http://www.derivativeworks.com/2008/09/complete-scans.html\" data-type=\"usual\" target=\"_blank\">«Что пошло не так?»</a> о том, как непродуманное градостроительство повлияло на разрушения от урагана «Эндрю».","type":"p","className":""},{"data":{"id":3112,"data":{"images":[{"credit":"The Atlanta Journal-Constitution","caption":"Инфографика из расследования Билла Дедмена «Цвет денег» (1988) о том, как банки не выдают кредиты темнокожим американцам даже с хорошими доходами","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3d1f01a5686c40b39a8468df81cfa59f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3d1f01a5686c40b39a8468df81cfa59f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":2230,"real_height_2x":4459},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3d1f01a5686c40b39a8468df81cfa59f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3d1f01a5686c40b39a8468df81cfa59f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":2230,"real_height_2x":4459}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"<strong>Современность. Дата-журналистика — новый панк!</strong>","type":"p","className":""},{"data":"«Новым панком» журналистику данных <a href=\"https://www.theguardian.com/news/datablog/2012/may/24/data-journalism-punk\" data-type=\"usual\" target=\"_blank\">провозгласил</a> Саймон Роджерс, который начал вести <a href=\"https://www.theguardian.com/news/datablog/2009/mar/10/blogpost1\" data-type=\"usual\" target=\"_blank\">DataBlog</a> издания Guardian в 2009 году. Он сформулировал важные принципы дата-журналистики — прозрачность методологии и необходимость публиковать наборы данных целиком. В 2011 году Роджерс написал книгу <a href=\"https://books.google.ch/books/about/Facts_are_Sacred.html?id=C_7IMwEACAAJ&amp;redir_esc=y\" data-type=\"usual\" target=\"_blank\">Facts are sacred</a> («Факты священны»), по-прежнему одну из главных в дата-журналистике.","type":"p","className":""},{"data":"Зарождение и стремительное развитие журналистики данных в ее современном виде в 2000-х годах связано, конечно, с распространением интернета. Можно выделить три фактора, которые оказали большое влияние на формирование дата-журналистики.","type":"p","className":""},{"data":"Во-первых, государства начали публиковать официальные <a href=\"https://opendatahandbook.org/guide/en/what-is-open-data/\" data-type=\"usual\" target=\"_blank\">открытые данные</a> и статистику.&nbsp;","type":"p","className":""},{"data":"Во-вторых, стали происходить утечки больших объемов информации, которые нужно было как-то обрабатывать и преподносить аудитории.","type":"p","className":""},{"data":{"id":3153,"data":{"text":"Мы будем присылать вам только важные истории","title":"Подпишитесь на нашу рассылку"},"category":"mailing-embed"},"type":"mailing-embed"},{"data":"В-третьих, инструменты для создания дата-материалов с каждым годом становятся доступнее и проще: если десять лет назад анализом и визуализацией данных занимались в основном специалисты в этих областях — статисты, аналитики, дизайнеры, — то сейчас этими навыками может овладеть любой человек.","type":"p","className":""},{"data":"В 2010 году в Амстердаме прошла первая международная <a href=\"https://blogs.journalism.co.uk/2010/08/26/ddj-reasons-to-cheer-from-amsterdams-data-driven-journalism-conference/\" data-type=\"usual\" target=\"_blank\">конференция</a> по журналистике данных, после которой термин «дата-журналистика» начал упоминаться в научных статьях и на конференциях.","type":"p","className":""},{"data":"В том же году агентство Associated Press опубликовало серию сенсационных расследований о военных действиях США в Ираке. Журналисты проанализировали полмиллиона документов, полученных проектом <a href=\"https://wikileaks.org/\" data-type=\"usual\" target=\"_blank\">Wikileaks</a>, и <a href=\"https://www.theguardian.com/news/datablog/2010/dec/16/wikileaks-iraq-visualisation\" data-type=\"usual\" target=\"_blank\">визуализировали</a> их с помощью графов и карт. Эти публикации показали огромный масштаб жертв в Ираке.","type":"p","className":""},{"data":"Через пять лет Международный консорциум журналистов-расследователей получил доступ к «Панамскому досье» — утечке 11,5 миллиона документов фирмы-регистратора офшоров Mossack Fonseca. В течение года 400 журналистов из 77 стран работали над расследованиями об офшорных компаниях глав государств, чиновников, политиков и олигархов. <a href=\"https://krug.novayagazeta.ru/18-roman\" data-type=\"usual\" target=\"_blank\">Российскую часть</a> расследования готовили журналисты «Новой Газеты» Роман Анин, Олеся Шмагун и Дмитрий Великовский (все признаны Минюстом иноагентами) — впоследствии авторы «Важных историй». «Панамское досье» 2016 года стало самым крупным совместным дата-журналистским расследованием в мире. Во многих странах против упомянутых чиновников и влиятельных лиц были проведены расследования, президент Исландии лишился поста. Авторы «Панамского досье» получили Пулитцеровскую премию.","type":"p","className":""},{"data":"С тех пор происходило еще несколько крупных утечек данных об офшорах и финансовых операциях. В 2019 году было опубликовано расследование <a href=\"https://meduza.io/feature/2019/03/04/koshelek-rossiyskoy-elity\" data-type=\"usual\" target=\"_blank\">«Кошелек российской элиты»</a> о выводе миллиардов рублей из России через серые схемы. Это стало громким событием в Европе, после которого банки были вынуждены пересмотреть подход к предотвращению «отмывания денег». Расследование получило главную награду в дата-журналистике — <a href=\"https://datajournalism.com/awards\" data-type=\"usual\" target=\"_blank\">Sigma Awards</a>.&nbsp;","type":"p","className":""},{"data":"В 2021 году были опубликованы <a href=\"https://istories.media/pandora/\" data-type=\"usual\" target=\"_blank\">«Документы Пандоры»</a>, которые по объему слитых документов даже превзошли «Панамский архив». В расследовании обеих утечек участвовали журналисты «Важных историй».","type":"p","className":""},{"data":"Но несмотря на то, что расследования утечек информации вызывают большой общественный резонанс, чаще всего дата-журналистские материалы основаны не на них. Обычно источником служат официальные открытые данные, либо журналисты сами собирают наборы данных из разных ресурсов.","type":"p","className":""},{"data":"Об этом можно судить по дата-материалам, которые публикуют лидеры современной дата-журналистики. Это в первую очередь команды изданий <a href=\"https://www.nytimes.com/\" data-type=\"usual\" target=\"_blank\">New York Times</a>, <a href=\"https://www.theguardian.com/international\" data-type=\"usual\" target=\"_blank\">Guardian</a>, <a href=\"https://www.ft.com/\" data-type=\"usual\" target=\"_blank\">Financial Times</a>, <a href=\"https://www.washingtonpost.com/\" data-type=\"usual\" target=\"_blank\">Washington Post</a>, <a href=\"https://www.wsj.com/\" data-type=\"usual\" target=\"_blank\">Wall Street Journal</a>, <a href=\"https://pudding.cool/\" data-type=\"usual\" target=\"_blank\">Pudding</a>, <a href=\"https://www.propublica.org/\" data-type=\"usual\" target=\"_blank\">Propublica</a>, <a href=\"https://www.bloomberg.com/\" data-type=\"usual\" target=\"_blank\">Bloomberg</a>, <a href=\"https://graphics.reuters.com/\" data-type=\"usual\" target=\"_blank\">Reuters</a>. Именно на них ориентируются все дата-журналистские команды в мире.","type":"p","className":""},{"data":{"id":3150,"data":{"author":"— главные англоязычные издания, которые делают журналистику данных","header":"New York Times, Guardian, Financial Times, Washington Post, Wall Street Journal, Pudding, Propublica, Bloomberg, Reuters"},"category":"quotation-embed"},"type":"quotation-embed"},{"data":"Также примеры лучших дата-материалов последних десяти лет можно найти на страницах дата-журналистских премий — <a href=\"https://medium.com/data-journalism-awards\" data-type=\"usual\" target=\"_blank\">Data Journalism Awards</a> (до 2019 года) и <a href=\"https://sigmaawards.org/\" data-type=\"usual\" target=\"_blank\">Sigma Awards</a> (c 2020 года). Среди работ, которые их получают, все чаще можно встретить дата-материалы на русском языке — об этом расскажем в следующей части.&nbsp;","type":"p","className":""},{"data":"В 2020 и 2021 году главной для дата-журналистики стала тема пандемии. Многие СМИ изучали и визуализировали данные о заражениях коронавирусом, о смертности и вакцинации. Самый известный <a href=\"https://www.washingtonpost.com/graphics/2020/world/corona-simulator/\" data-type=\"usual\" target=\"_blank\">материал</a> сделало издание Washington Post. Это симуляция пандемии, которая показала, как стремительно растет число заражений, когда люди не изолируются. Эта история <a href=\"https://www.dezeen.com/2020/03/26/the-washington-post-coronavirus-inforgraphics-harry-stevens/\" data-type=\"usual\" target=\"_blank\">стала</a> самой просматриваемой за всю историю Washington Post.&nbsp;","type":"p","className":""},{"data":"Другие резонансные примеры — исчерпывающий <a href=\"http://graphics.reuters.com/HEALTH-CORONAVIRUS/VACCINE/yzdpxqxnwvx/index.html\" data-type=\"usual\" target=\"_blank\">гид</a> по вакцинации от Reuter Graphics, <a href=\"https://ig.ft.com/coronavirus-global-data/\" data-type=\"usual\" target=\"_blank\">хронология</a> пандемии в данных от Financial Times, обновляемый <a href=\"https://www.nytimes.com/interactive/2021/world/covid-cases.html\" data-type=\"usual\" target=\"_blank\">дашборд</a> New York Times, трекер новых <a href=\"https://www.axios.com/variants-tracker\" data-type=\"usual\" target=\"_blank\">штаммов</a> коронавируса и <a href=\"https://datajournalism.com/read/longreads/covid-19-data-journalism\" data-type=\"usual\" target=\"_blank\">другие</a> дата-материалы по теме пандемии.","type":"p","className":""},{"data":{"id":3113,"data":{"images":[{"credit":"Harry Stevens / The Washington Post, 2020","caption":"Визуализация из интерактивного материала The Washington Post, который наглядно показал важность социальной изоляции. Эта публикация стала самой популярной за всю историю The Washington Post","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c50d3117c64946f6abc5bbb9826f795e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c50d3117c64946f6abc5bbb9826f795e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":746,"real_height_2x":1492},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/c50d3117c64946f6abc5bbb9826f795e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/c50d3117c64946f6abc5bbb9826f795e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":746,"real_height_2x":1492}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"История дата-журналистики в России","type":"h2","className":""},{"data":"<strong>Докомпьютерная эпоха. Инфографика царского и советского периода&nbsp;</strong>","type":"p","className":""},{"data":"Несмотря на то что о журналистике данных в России начали говорить всего десять лет назад, а активно заниматься ей — меньше пяти лет назад, визуализация данных и печатная инфографика встречались намного раньше, минимум с 19-го века.&nbsp;","type":"p","className":""},{"data":"Алексей Новичков, доцент Факультета коммуникаций, медиа и дизайна НИУ ВШЭ, экс-руководитель студии инфографики ТАСС, в своей <a href=\"https://www.youtube.com/watch?v=7aPRnFhemJA\" data-type=\"usual\" target=\"_blank\">лекции</a> об истории российской инфографики начинает отсчет с научно-популярных журналов «Вокруг света», «Наука и жизнь» и «Огонек», где публиковались схемы различных технических изобретений.","type":"p","className":""},{"data":{"id":3114,"data":{"images":[{"credit":"Наука и жизнь, 1890, № 1","caption":"Инфографика изобретения Пуатевена для проведения опыта по исследованию свойств цвета. Один из первых опытов использования инфографики в СМИ","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd86bf56ae084115b9447f591af745da-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd86bf56ae084115b9447f591af745da-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1748,"real_height_2x":3495},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/bd86bf56ae084115b9447f591af745da-1200xautopx_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/bd86bf56ae084115b9447f591af745da-1200xautopx_2x.jpg","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1748,"real_height_2x":3495}]},{"credit":"Огонек, 1899, № 1","caption":"Инфографика с изображением красных кровяных телец (эритроцитов) в первом номере журнала «Огонек» в 1899","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4d907b3cb189423e8c1d8916e1f05e5f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4d907b3cb189423e8c1d8916e1f05e5f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1682,"real_height_2x":3364},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4d907b3cb189423e8c1d8916e1f05e5f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4d907b3cb189423e8c1d8916e1f05e5f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1682,"real_height_2x":3364}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"В начале 20 века были изданы несколько сборников с визуализацией данных, созданных вручную. Их интересно рассматривать и сегодня.&nbsp;","type":"p","className":""},{"data":{"id":3117,"data":{"images":[{"credit":"«Всеобщий географический и статистический карманный атлас» Издательства А.Ф. Маркса, 1908","caption":"Сравнение госдолга разных стран","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9cfcc13cdfcc4913b711bbc0f7df0c68-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9cfcc13cdfcc4913b711bbc0f7df0c68-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1134,"real_height_2x":2268},{"format":"jpeg","url_1x":"https://static.istories.media/uploaded/images/9cfcc13cdfcc4913b711bbc0f7df0c68-1200xautopx_1x.jpeg","url_2x":"https://static.istories.media/uploaded/images/9cfcc13cdfcc4913b711bbc0f7df0c68-1200xautopx_2x.jpeg","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1134,"real_height_2x":2268}]}]},"category":"image-embed"},"type":"image-embed"},{"data":{"id":3119,"data":{"images":[{"credit":"«Атлас диаграмм по экономическим вопросам» Ивана Озерова, 1909","caption":"Потребление чая на душу населения в Великобритании, Голландии, Германии, России и США","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a278f471f0a24808939bfb025b4efdea-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a278f471f0a24808939bfb025b4efdea-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":762,"real_height_2x":1523},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a278f471f0a24808939bfb025b4efdea-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a278f471f0a24808939bfb025b4efdea-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":762,"real_height_2x":1523}]}]},"category":"image-embed"},"type":"image-embed"},{"data":{"id":3123,"data":{"images":[{"credit":"Сборник «Россия в цифрах» Николая Рубакина, 1912","caption":"Профессии жителей Российской империи конца 19 века. Размер фигуры означает численность представителей определенной профессии. Большинство жителей Российской империи занимались сельским хозяйством","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b70e0e5e26b14539b6e278283a7bd767-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b70e0e5e26b14539b6e278283a7bd767-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":920,"real_height_2x":1840},{"format":"jpeg","url_1x":"https://static.istories.media/uploaded/images/b70e0e5e26b14539b6e278283a7bd767-1200xautopx_1x.jpeg","url_2x":"https://static.istories.media/uploaded/images/b70e0e5e26b14539b6e278283a7bd767-1200xautopx_2x.jpeg","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":920,"real_height_2x":1840}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Помимо статистических сборников и иллюстраций в научно-популярных журналах, в СССР инфографика использовалась как средство пропаганды. Она должна была наглядно показывать достижения молодого советского государства.&nbsp;","type":"p","className":""},{"data":{"id":3127,"data":{"images":[{"credit":"Институт Изостат, 1938. Собрание ГПИБ / Фото с сайта Галереи на Шабловке","caption":"Инфографика Изостата из альбома-выставки «СССР — страна равноправия женщин»","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2dd8c6daf21c40ebbacda1ca99c59942-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2dd8c6daf21c40ebbacda1ca99c59942-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":860,"real_height_2x":1720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2dd8c6daf21c40ebbacda1ca99c59942-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/2dd8c6daf21c40ebbacda1ca99c59942-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":860,"real_height_2x":1720}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"<strong>Журнальная инфографика 2000-х и начала 2010-х</strong>","type":"p","className":""},{"data":"В России начала нулевых если и были журналистские расследования на данных, то это были единичные случаи. В то время активно развивалась инфографика в журналах. В отличие от современной дата-журналистики в России, она была чаще на научно-популярные темы, чем на острые социальные, и почти не отражала новостную повестку.","type":"p","className":""},{"data":"По мнению Алексея Новичкова, если считать инфографику оформлением материалов дата-журналистики, то пионерами в этой сфере можно назвать журнал <a href=\"http://infographer.ru/vsyo-yasno/#prettyPhoto\" data-type=\"usual\" target=\"_blank\">«Всё Ясно»</a>. Он существовал с 2004 по 2007 год и полностью состоял из инфографики.&nbsp;","type":"p","className":""},{"data":"Также инфографикой занимались студия «Паровоз», газеты «Акция» и «Мой район», журналы «Русский репортер», «Большой город», «Вокруг света».","type":"p","className":""},{"data":{"id":3132,"data":{"images":[{"credit":"Журнал «Все ясно», 2007 / Фото агентства Infographer","caption":"Хроника перелета немецкого пилота Матиаса Руста на лёгкомоторном самолёте из Хельсинки в Москву в 1987 году","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2171c1bc400c49dcbdacae0ea93bcc19-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2171c1bc400c49dcbdacae0ea93bcc19-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1533,"real_height_2x":3066},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2171c1bc400c49dcbdacae0ea93bcc19-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/2171c1bc400c49dcbdacae0ea93bcc19-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1533,"real_height_2x":3066}]},{"credit":"Журнал «Все ясно», 2007 / Фото агентства Infographer","caption":"Инфографика о политзаключенных в России","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4741fde76d3049eab61068df32008e30-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4741fde76d3049eab61068df32008e30-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1533,"real_height_2x":3066},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4741fde76d3049eab61068df32008e30-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4741fde76d3049eab61068df32008e30-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1533,"real_height_2x":3066}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":{"id":3135,"data":{"images":[{"credit":"","caption":"Журнал Русский репортер, 2010","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d186fc74ef7740f2aee0c68bc9ae8f08-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d186fc74ef7740f2aee0c68bc9ae8f08-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":748,"real_height_2x":1496},{"format":"jpeg","url_1x":"https://static.istories.media/uploaded/images/d186fc74ef7740f2aee0c68bc9ae8f08-1200xautopx_1x.jpeg","url_2x":"https://static.istories.media/uploaded/images/d186fc74ef7740f2aee0c68bc9ae8f08-1200xautopx_2x.jpeg","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":748,"real_height_2x":1496}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"<strong>Дата-журналистика в России с 2011-го по настоящее время. Главные медиа, тексты и проекты&nbsp;</strong>","type":"p","className":""},{"data":"<strong>РИА «Новости» и ТАСС</strong>","type":"p","className":""},{"data":"В 2010 году в Амстердаме прошла первая международная конференция по журналистике данных, а в 2011 году РИА «Новости» перевело пособие по дата-журналистике на русский язык.","type":"p","className":""},{"data":"«До этого момента всерьез об этой профессии никто не слышал. Подразумевалось, что есть специализированные журналисты в области науки или экономики, которые имеют бэкграунд работы с данными в рамках своего профиля, но вот заниматься расследованиями или сторителлингом, основанном на данных, специализировано ещё никто не начал», — говорит Алексей Новичков, доцент факультета коммуникаций, медиа и дизайна ВШЭ, с 2011 по 2014 год работавший заместителем руководителя студии инфографики РИА «Новости».","type":"p","className":""},{"data":"К 2012 году студия инфографики РИА стала одним из крупнейших инфографических бюро Европы и получала за свои <a href=\"https://www.youtube.com/watch?v=fZ9iDlCg6FI\" data-type=\"usual\" target=\"_blank\">работы</a> награды на главных профильных конкурсах Information Is Beautiful и Malofiej. ","type":"p","className":""},{"data":"Вскоре большие проекты по инфографике начал выпускать ТАСС. Проекты <a href=\"https://1812.tass.ru/\" data-type=\"usual\" target=\"_blank\">«Когда пришёл Наполеон»</a>, <a href=\"https://italia.tass.ru/\" data-type=\"usual\" target=\"_blank\">«Италия. История одного падения»</a>, и <a href=\"https://merkator.tass.ru/\" data-type=\"usual\" target=\"_blank\">«Меркатор. О дивный плоский мир»</a> — самые титулованные в истории российской мультимедийной инфографики.","type":"p","className":""},{"data":"Оба агентства, МИА «Россия сегодня» (до 2013 года — РИА «Новости») и ТАСС, делали и продолжают делать качественную инфографику (Алексей Новичков собрал их главные достижения в этой <a href=\"https://docs.google.com/spreadsheets/d/1FfXfoiUY46WlVtwn_TTtCUch4DYU4oRC17fULXuXmOo/edit#gid=0\" data-type=\"usual\" target=\"_blank\">таблице</a>).&nbsp;","type":"p","className":""},{"data":"Но несмотря на то что именно РИА «Новости» первыми в России заговорили о журналистике данных, тематика их <a href=\"https://ria.ru/infografika/\" data-type=\"usual\" target=\"_blank\">инфографики</a>, как и <a href=\"https://infographics.tass.ru/\" data-type=\"usual\" target=\"_blank\">инфографики</a> ТАССа, была и остается познавательной и развлекательной, а не социальной и не расследовательской.&nbsp;","type":"p","className":""},{"data":"«Мы смотрели на New York Times, Washington Post, Wall Street Journal, Bloomberg, — говорит Александр Богачев, который с 2014 по 2017 год был редактором и дизайнером студии инфографики МИА „Россия Сегодня“ (до 2013 называлось РИА «Новости»). — Я хотел, чтобы наши проекты были не только такими же красивыми, как у них, но чтобы они были такими же журналистскими — соответствовали актуальной повестке, имели социальную значимость. Но в РИА делать это было скорее нереально».&nbsp;","type":"p","className":""},{"data":"Главными именно дата-журналистскими материалами РИА «Новости» опрошенные нами коллеги называли те, что касались Госдумы и выборов, — например <a href=\"https://ria.ru/20131212/983608028.html\" data-type=\"usual\" target=\"_blank\">«20 лет Государственной думы»</a>, <a href=\"https://ria.ru/20130627/946076857.html\" data-type=\"usual\" target=\"_blank\">«Конфигуратор государственной думы»</a>, наглядное <a href=\"https://ria.ru/20160801/1473289406.html\" data-type=\"usual\" target=\"_blank\">объяснение</a> механики голосования на выборах в Госдуму (до сих пор актуальное) и <a href=\"https://ria.ru/20160918/1476912507.html#/summary\" data-type=\"usual\" target=\"_blank\">визуализация</a> их итогов.","type":"p","className":""},{"data":"<strong>«Инфокультура», хакатоны и «журналистика данных» ВШЭ</strong>","type":"p","className":""},{"data":"Большую роль в развитии российской дата-журналистики сыграл основатель и директор проекта <a href=\"https://www.infoculture.ru/\" data-type=\"usual\" target=\"_blank\">«Инфокультура»</a> Иван Бегтин. Он добивался того, чтобы ведомства публиковали <a href=\"https://data.gov.ru/koncepciya-otkrytyh-dannyh\" data-type=\"usual\" target=\"_blank\">открытые данные</a> в публичном доступе.&nbsp;","type":"p","className":""},{"data":"Хакатоны — мероприятия, где команды из программистов, дизайнеров и журналистов в короткие сроки с нуля создают дата-материалы, — тоже повлияли на формирование индустрии. Многие дата-журналисты, которые сейчас работают в СМИ, начали путь в профессию с таких хакатонов.&nbsp;","type":"p","className":""},{"data":"Первый <a href=\"https://www.infoculture.ru/2016/03/02/kgi-v-vysshej-shkole-jekonomiki-proshel-pe/\" data-type=\"usual\" target=\"_blank\">хакатон</a> по дата-журналистике прошел в феврале 2016 года. Среди его организаторов были проект «Инфокультура» и магистерская программа по журналистике данных НИУ ВШЭ.","type":"p","className":""},{"data":{"id":3152,"data":{"text":"С вашей помощью мы сможем продолжать рассказывать истории о России  —  с данными и не только","title":"Поддержите «Важные истории»","buttonText":"Сделать пожертвование"},"category":"donate-embed"},"type":"donate-embed"},{"data":"В 2016 году прошел первый набор на эту программу. Среди первых студентов были Ирина Долинина и Алеся Мараховская (обе журналистки признаны Минюстом иноагентами; работали в дата-отделе «Новой газеты», сейчас в «Важных историях»), Соня Савина (РБК, а сейчас «Важные истории»), Дада Линделл (РБК).","type":"p","className":""},{"data":"<strong>РБК&nbsp;</strong>","type":"p","className":""},{"data":"РБК стало одним из первых СМИ, которые начали заниматься не только инфографикой, а дата-журналистикой — то есть делать исследования на актуальные и социально значимые темы. Редактором отдела спецпроектов в 2017–2018 годах был Александр Богачев. Там же работали Соня Савина и Дада Линделл.&nbsp;","type":"p","className":""},{"data":"«Каждое утро я читала ленту новостей и прикидывала, какую „горящую“ тему можно раскрыть через данные или интересно дополнить данными, чтобы выпустить заметку в тот же день», — рассказывает Соня Савина. Пример такого новостного материала на основе данных — <a href=\"https://www.rbc.ru/politics/10/09/2018/5b965dbb9a79470ea37ce211\" data-type=\"usual\" target=\"_blank\">публикация</a> 2018 года о том, как во всех районах, где проходили «мусорные» протесты, результат действующего губернатора снизился по сравнению с прошлыми выборами.&nbsp;","type":"p","className":""},{"data":"Среди множества дата-публикаций РБК Соня Савина отметила несколько наиболее интересных, на ее взгляд:","type":"p","className":""},{"data":"<li><a href=\"https://www.rbc.ru/politics/07/09/2018/5b90f9959a79476c0684a13b\" data-type=\"usual\" target=\"_blank\">анализ</a> публикаций в соцсетях с хештегом #засобянина перед выборами мэра Москвы в 2018 году, который показал, что подавляющую часть постов в поддержку Собянина писали сотрудники его избирательного штаба;</li><li>обновляемые <a href=\"https://www.rbc.ru/politics/15/03/2018/5aaa919c9a7947cd229d2039\" data-type=\"usual\" target=\"_blank\">графики</a> о дипломатических конфликтах России с другими странами;</li><li>красочный <a href=\"https://www.rbc.ru/politics/19/03/2018/5aaf83eb9a794725224a6534?from=center_1\" data-type=\"usual\" target=\"_blank\">спецпроект</a> с результатами президентских выборов президента 2018 года в интерактивных визуализациях;</li><li><a href=\"https://www.rbc.ru/politics/07/05/2018/5ae45e8a9a7947cdea03a501\" data-type=\"usual\" target=\"_blank\">игра</a> о том, как Россия жила при Путине.</li>","type":"ul","className":""},{"data":"Дата-журналистка Дада Линделл в 2019 году получила премию Data Journalism Awards за серию публикаций для РБК. В частности, за резонансное <a href=\"https://www.rbc.ru/society/11/03/2019/5c6c0ae49a79477703d915b7\" data-type=\"usual\" target=\"_blank\">расследование</a> о том, как в некоторых регионах России от ВИЧ умирают чаще, чем от убийств, суицида и ДТП, вместе взятых. Среди других больших расследований Дады — материалы о том, как в Москве <a href=\"https://www.rbc.ru/society/21/08/2019/5d5a951b9a7947b5b3dc6022\" data-type=\"usual\" target=\"_blank\">меняют</a> дорожное покрытие на одних и тех же улицах, как <a href=\"https://www.rbc.ru/society/13/05/2019/5ca1d0229a7947593d373650\" data-type=\"usual\" target=\"_blank\">росли</a> подмосковные свалки, как <a href=\"https://www.rbc.ru/economics/27/12/2017/5a40d7429a79472550cd83ab\" data-type=\"usual\" target=\"_blank\">дорожали</a> авиабилеты перед Чемпионатом мира и другие.","type":"p","className":""},{"data":{"id":3141,"data":{"images":[{"credit":"Александр Богачев, Дада Линделл, Софья Савина, Алексей Гаврилко-Алексеев, Евгений Николаев, Евгений Тонконогий, Александр Чиненов / РБК, 2018","caption":"Обложка интерактивного проекта РБК об итогах выборов президента в 2018","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/63cc856a14b8490d991edde14e328e0d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/63cc856a14b8490d991edde14e328e0d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1104,"real_height_2x":2208},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/63cc856a14b8490d991edde14e328e0d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/63cc856a14b8490d991edde14e328e0d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1104,"real_height_2x":2208}]},{"credit":"Дада Линделл, Полина Звездина, Евгений Тарасенко / РБК, 2019","caption":"Инфографика из расследования РБК о смертности россиян от ВИЧ","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/953678dc580d4afcac9b5f1af9e606f6-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/953678dc580d4afcac9b5f1af9e606f6-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1104,"real_height_2x":2208},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/953678dc580d4afcac9b5f1af9e606f6-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/953678dc580d4afcac9b5f1af9e606f6-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1104,"real_height_2x":2208}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"<strong>«Новая Газета»</strong>","type":"p","className":""},{"data":"В 2018 году «Новая газета» организовала хакатон, на котором набрала первый дата-отдел в российских СМИ. До этого были отделы спецпроектов, инфографики, но дата-отдела еще нигде не было. В него вошли Андрей Заякин, Алексей Смагин, Ирина Долинина и Алеся Мароховская.&nbsp;","type":"p","className":""},{"data":"«Сначала было немного странно, потому что и сама редакция не понимала, что от нас нужно, и мы сами не понимали, — рассказывает Алеся Мароховская, сейчас редакторка дата-отдела „Важных историй“. — [Главный редактор „Новой газеты“] Дмитрий Муратов рассказывал, что, когда появился дата-отдел, к нему пришел отдел культуры в расстроенных чувствах с вопросом „Мы что, плохо делаем свою работу? Зачем вы наняли целый дата-отдел, чтобы освещать даты? Мы что, плохо даты освещаем?“ Иногда к нам приходили со странными просьбами что-то нагуглить: „вот вы же с компьютерами сидите, нагуглите нам“. Приходилось долго объяснять, что мы не отдел гугления, а немного другими вещами занимаемся. Накапливался какой-то негатив к нам, потому что „вы там со своими компами сидите, долго ничего не выпускаете, еще и гуглить не хотите“. Был этап какой-то притирки. Стало проще, когда мы <a href=\"https://redkollegia.org/archives/text/ya-tebya-i-ubyu-kak-v-rossii-smyagchayut-nakazaniya-za-istyazaniya-i-ubijstva-detej-v-semyah-i-pochemu-vinovnyh-neredko-prosto-otpuskayut-issledovanie-novoj\" data-type=\"usual\" target=\"_blank\">получили</a> Редколлегию [за <a href=\"https://novayagazeta.ru/articles/2019/09/23/82057-ya-tebya-i-ubyu\" data-type=\"usual\" target=\"_blank\">расследование</a> о насилии над детьми], тогда коллеги немножко оттаяли и поняли, что мы не просто сидим за компами и ничего не делаем, а это всё-таки приносит какой-то толк».","type":"p","className":""},{"data":"Расследования Алеси Мароховской и Ирины Долининой в 2018 и 2019 годах — <a href=\"https://novayagazeta.ru/articles/2018/10/08/78095-kto-podnimaet-rossiyu-na-dybu\" data-type=\"usual\" target=\"_blank\">«Кто поднимает Россию на дыбу»</a> о пытках в колониях и <a href=\"https://novayagazeta.ru/articles/2019/09/23/82057-ya-tebya-i-ubyu\" data-type=\"usual\" target=\"_blank\">«Я тебя и убью»</a> о том, как в России смягчают наказание за издевательства над детьми, стали прорывными в плане работы с данными в журналистике. Они были сделаны на основе анализа судебных решений, в том числе методами машинного обучения. В дальнейшем судебные решения не раз становились основой дата-журналистских расследований.","type":"p","className":""},{"data":"Одним из первых материалов дата-отдела было расследование <a href=\"https://novayagazeta.ru/articles/2018/09/17/77842-svoih-ne-brosaem\" data-type=\"usual\" target=\"_blank\">«ВИП-кочевники»</a>, где авторы проанализировали почти 60 тысяч чиновников и с помощью программирования нашли целые кланы, которые вместе переходят с одного места работы на другое — и захватывают с собой подрядчиков-земляков.&nbsp;","type":"p","className":""},{"data":"С 2020 года в «Новой» работает уже второе поколение дата-отдела: Екатерина Бонч-Осмоловская, Артем Щенников, Арнольд Хачатуров и Антонина Асанова, у которых уже успело выйти много больших текстов. Например, <a href=\"https://novayagazeta.ru/articles/2021/08/24/muzhiki-chut-vypili-i-davai-babakhnem\" data-type=\"usual\" target=\"_blank\">расследование</a> о том, что происходит с войной в Донбассе в 2021 году, на основе данных из самых разных источников, об <a href=\"https://novayagazeta.ru/articles/2021/10/14/seks-bez-prosveta\" data-type=\"usual\" target=\"_blank\">эпидемии</a> ВИЧ, о школьном <a href=\"https://novayagazeta.ru/articles/2021/04/02/obedki\" data-type=\"usual\" target=\"_blank\">питании</a> в Москве, о <a href=\"https://novayagazeta.ru/articles/2021/10/07/svoikh-ne-raskryvaem\" data-type=\"usual\" target=\"_blank\">не-расследовании</a> убийств в Чечне и другие.","type":"p","className":""},{"data":"Кроме того, дата-отдел «Новой» запустил альтернативный <a href=\"https://novayagazeta.ru/coronavirus\" data-type=\"usual\" target=\"_blank\">трекер</a> COVID-19, который позволяет лучше понять, что происходит с коронавирусом в регионах по данным об избыточных смертях и поисковых запросах.","type":"p","className":""},{"data":"<strong>«Медиазона»</strong>","type":"p","className":""},{"data":"Когда мы спрашивали у дата-журналистов, какие у них любимые примеры журналистики данных на русском языке, многие называли два проекта «Медиазоны» 2020 года — про <a href=\"https://zona.media/article/2020/05/19/martyrology\" data-type=\"usual\" target=\"_blank\">смертность</a> врачей от коронавируса и <a href=\"https://mediazona.by/article/2020/10/13/minsk-beaten\" data-type=\"usual\" target=\"_blank\">«Минск избитый»</a> о том, как в августе 2020-го силовики калечили протестующих в Беларуси.","type":"p","className":""},{"data":"Помимо кропотливой работы с тяжелой темой и сложными данными, их отличают эмоциональные визуализации. Проект «Минск избитый» <a href=\"https://sigmaawards.org/brutalised-minsk-how-belarusian-police-beat-protesters/\" data-type=\"usual\" target=\"_blank\">стал</a> победителем Sigma.","type":"p","className":""},{"data":{"id":3143,"data":{"images":[{"credit":"Максим Литаврин, Давид Френкель, Никита Шулаев, Анна Козкина / Медиазона, 2020","caption":"Фрагмент инфографики «Медиазоны» о смертности врачей от коронавируса","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/dd678ff82cfb4cc8a9e9e2fa07a5db41-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/dd678ff82cfb4cc8a9e9e2fa07a5db41-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1144,"real_height_2x":2287},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/dd678ff82cfb4cc8a9e9e2fa07a5db41-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/dd678ff82cfb4cc8a9e9e2fa07a5db41-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1144,"real_height_2x":2287}]},{"credit":"Максим Литаврин, Давид Френкель, Егор Сковорода, Анастасия Бойко / Медиазона Беларусь, 2020","caption":"Фрагмент инфографики «Медиазоны Беларусь» о том, как силовики калечили протестующих","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1339163a61b0430f8932a31e3e0da059-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1339163a61b0430f8932a31e3e0da059-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1114,"real_height_2x":2228},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1339163a61b0430f8932a31e3e0da059-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1339163a61b0430f8932a31e3e0da059-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1114,"real_height_2x":2228}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Специфика «Медиазоны» — дата-исследования о политических преследованиях, тюрьмах, судебной системе: <a href=\"https://zona.media/jan-repressions\" data-type=\"usual\" target=\"_blank\">путеводитель</a> по политзаключенным после зимних протестов 2021 года или <a href=\"https://zona.media/article/2021/10/01/latajut-uk\" data-type=\"usual\" target=\"_blank\">исследование</a> о том, как по следам политических процессов и протестов меняют законодательство.&nbsp;","type":"p","className":""},{"data":"Как и у «Новой газеты», у «Медиазоны» есть интерактивный <a href=\"https://zona.media/coronadeaths\" data-type=\"usual\" target=\"_blank\">дашборд</a> по коронавирусу, где помимо официальной смертности от COVID-19 показана и избыточная смертность в регионах.","type":"p","className":""},{"data":"<strong>«Проект»</strong>","type":"p","className":""},{"data":"В августе 2021 года прокуратура <a href=\"https://meduza.io/feature/2021/07/15/proekt-ob-yavili-nezhelatelnoy-organizatsiey-a-ego-sotrudnikov-inoagentami-fakticheski-im-zapretili-pisat-a-chitatelyam-chitat\" data-type=\"usual\" target=\"_blank\">признала</a> издание «Проект» нежелательной организацией, и оно вынуждено было закрыться под угрозой уголовного преследования авторов.&nbsp;","type":"p","className":""},{"data":"К сожалению, мы даже не можем дать ссылки на исследования «Проекта», где с 2018 по 2021 год публиковались качественные дата-исследования на самые разные темы — о том, как власти стремятся исправить статистику вместо того, чтобы решать проблемы, о загрязнении воздуха, о пожарах, о пытках в колониях, о нехватке мест в детских садах и другие.","type":"p","className":""},{"data":"<strong>«Важные истории»</strong>","type":"p","className":""},{"data":"С момента запуска весной 2020 года «Важные истории» делали расследования на данных, но для большей продуктивности и организованности осенью 2020-го появился целый дата-отдел. Можно сказать, что это самый крупный дата-отдел в России — в него входят пять человек.","type":"p","className":""},{"data":"В «Важных историях» собрались журналисты, которые уже имели большой опыт в журналистике данных, но решили немного изменить подход к историям. За год успели оформиться главные особенности дата-материалов, которые отличают «Важные истории» от других изданий, занимающихся журналистикой данных.&nbsp;","type":"p","className":""},{"data":"Во-первых, помимо цифр, в них почти всегда есть личные истории людей из разных регионов страны.","type":"p","className":""},{"data":"Во-вторых, все чаще дата-истории выходят не только в тексте, но и в формате видео.&nbsp;","type":"p","className":""},{"data":"В третьих, дата-журналисты в «Важных историях» многозадачны и проходят все этапы подготовки текста самостоятельно.&nbsp;","type":"p","className":""},{"data":"«Если в РБК моей главной задачей было собрать и проанализировать данные, то теперь я отвечаю и за общение с героями материалов, и за производство визуализаций, — рассказывает Соня Савина. — А если история выходит не только в тесте, но и в видео, то пишу сценарий и работаю в кадре. У этого подхода есть свои плюсы и минусы: производство историй занимает у нас больше времени, но такое глубокое погружение в тему — от дата-раскопок до командировок по городам и селам — рождает качественные материалы, выполненные с любовью».","type":"p","className":""},{"data":"Ниже мы собрали несколько историй, где как раз хорошо видны эти особенности.","type":"p","className":""},{"data":"<li><a href=\"https://istories.media/reportages/2021/06/01/ya-bolshe-v-etot-ad-ne-vernus--ya-bolshe-ne-khochu-rozhat-v-etoi-strane/\" data-type=\"usual\" target=\"_blank\">Я больше в этот ад не вернусь — я больше не хочу рожать в этой стране</a></li>","type":"ul","className":""},{"data":"Исследования на данных о материнской и младенческой смертности, о сокращении мест в роддомах уже было бы достаточно, чтобы рассказать, почему в России страшно рожать детей. Но благодаря историям героев Соне Савиной удалось сделать об этом потрясающий эмоциональный текст и фильм в духе социальной дата-журналистики.&nbsp;","type":"p","className":""},{"data":"<li><a href=\"https://istories.media/investigations/2021/02/18/ya-svidetel-kto-pomogaet-politseiskim-falsifitsirovat-ugolovnie-dela-za-narkotiki/\" data-type=\"usual\" target=\"_blank\">«Я свидетель!» Кто помогает полицейским фальсифицировать уголовные дела за наркотики</a> и <a href=\"https://istories.media/investigations/2021/03/31/raskhodnii-material-palochnoi-sistemi/\" data-type=\"usual\" target=\"_blank\">Расходный материал «палочной» системы</a>&nbsp;</li>","type":"ul","className":""},{"data":"Два этих расследования о том, как полицейские привлекают наркозависимых понятых, чтобы фальсифицировать уголовные дела по «наркотическим» статьям, уникальны методом работы с данными. Алесе Мароховской удалось с помощью программирования подтвердить то, о чем все догадывались, и найти в судебных решениях 86 подставных понятых, которые участвовали в 269 делах.","type":"p","className":""},{"data":{"id":3145,"data":{"images":[{"credit":"Алеся Мароховская / Важные истории, Иван Голунов / Медуза, 2021","caption":"Граф связей понятых с полицейскими из расследования «Я свидетель. Кто помогает полицейским фальсифицировать уголовные дела за наркотики»","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d782d2b359d748f095bbbff1ed2f03f7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d782d2b359d748f095bbbff1ed2f03f7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":724,"real_height_2x":1448},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/d782d2b359d748f095bbbff1ed2f03f7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/d782d2b359d748f095bbbff1ed2f03f7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":724,"real_height_2x":1448}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"«Мне самой нравится тот метод, который мы использовали, чтобы доказать фальсификации уголовных дел, — говорит Алеся. — Была такая проблема, которую примерно все понимали, но ее было практически нереально доказать документально именно массово. Можно было доказывать в каждом отдельном случае, [что понятые связаны с полицейскими], разбирая каждое дело, разговаривая с адвокатами и свидетелями. А тут удалось автоматизировать процесс и найти какой-то паттерн. Лично я обожаю такие истории, когда есть красивый метод решения. Мне нравится именно то, что с не самыми простыми данными удалось обойтись программным методом и массово доказать фальсификации».","type":"p","className":""},{"data":"В Самаре Алеся Мароховская и Ирина Долинина несколько дней общались с бывшими оперативниками и с теми, против кого они годами фальсифицировали уголовные дела, и сняли об этом мощный <a href=\"https://www.youtube.com/watch?v=viuYhGvQUfI&amp;feature=emb_title\" data-type=\"usual\" target=\"_blank\">фильм</a>.","type":"p","className":""},{"data":"<li><a href=\"https://istories.media/reportages/2020/11/16/rozhaem-kak-bogatie--umiraem-kak-bednie-pochemu-v-rossii-sokrashchaetsya-naselenie/\" data-type=\"usual\" target=\"_blank\">Рожаем как богатые — умираем как бедные. Почему в России сокращается население</a> и <a href=\"https://istories.media/reportages/2020/07/20/kolokol-pila-topor/\" data-type=\"usual\" target=\"_blank\">Колокол, пила, топор</a></li>","type":"ul","className":""},{"data":"Чуть больше года назад у «Важных историй» появились эксплейнеры в формате скроллителлинга. Вы скроллите вниз, а у вас меняются графики и выползает текст, который все объясняет. В формате скроллителлинга мы <a href=\"https://istories.media/reportages/2020/11/16/rozhaem-kak-bogatie--umiraem-kak-bednie-pochemu-v-rossii-sokrashchaetsya-naselenie/\" data-type=\"usual\" target=\"_blank\">разбирались</a>, правда ли население России сокращается из-за того, что женщины не хотят рожать, и каков был масштаб фальсификаций на <a href=\"https://istories.media/reportages/2020/07/20/kolokol-pila-topor/\" data-type=\"usual\" target=\"_blank\">голосовании</a> по поправкам в Конституцию в 2020-м и на <a href=\"https://istories.media/reportages/2021/09/21/elektronnoe-golosovanie-pamfilovoi-zaostrilo-pilu-churova/\" data-type=\"usual\" target=\"_blank\">выборах</a> в Госдуму в 2021-м.","type":"p","className":""},{"data":{"id":3148,"data":{"images":[{"credit":"Алеся Мароховская, Алексей Смагин / Важные истории, 2020","caption":"Фрагмент эксплейнера «Колокол, пила, топор» о фальсификациях на голосовании по поправкам в Конституцию в 2020 году","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1acc7f89540742cabaaa4372e97c8843-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1acc7f89540742cabaaa4372e97c8843-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":846,"real_height_2x":1692},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1acc7f89540742cabaaa4372e97c8843-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1acc7f89540742cabaaa4372e97c8843-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":846,"real_height_2x":1692}]},{"credit":"Алеся Мароховская, Полина Ужвак, Юлия Алыкова / Важные истории, 2020","caption":"Фрагмент эксплейнера «Рожаем как богатые — умираем как бедные» о том, почему на самом деле в России сокращается население","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b406e7b9b50d4e298d81df11512fdcda-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b406e7b9b50d4e298d81df11512fdcda-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":846,"real_height_2x":1692},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b406e7b9b50d4e298d81df11512fdcda-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b406e7b9b50d4e298d81df11512fdcda-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":846,"real_height_2x":1692}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"<li><a href=\"https://istories.media/investigations/2020/10/15/neftyanie-avarii-sluchayutsya-kazhdie-polchasa-issledovanie-realnikh-masshtabov-zagryaznenii-prirodi/\" data-type=\"usual\" target=\"_blank\">Нефтяные аварии случаются каждые полчаса: исследование реальных масштабов загрязнений природы</a>&nbsp;</li>","type":"ul","className":""},{"data":"Осенью 2020 Юлия Алыкова и Полина Ужвак сделали исследование о том, что в России разливы нефти происходят каждые полчаса. «Мне очень нравится исследование про разливы нефти, потому что в нем шокирующие выводы, и интересно, что никто не догадался сделать этого раньше, — говорит Алеся Мароховская. — Когда года четыре назад в Россию приезжал журналист Вадим Макаренко из польской „Газеты Выборчей“, он спрашивал, какие у вас материалы заходят лучше всего — наверное, экология? Мы тогда ответили, что какая экология, у нас в России никому дела нет до экологии и никто в эту тему не совался. Хотя на самом деле тема экологии в мире в дата-исследованиях очень важная. И я рада, что мы начали одними из первых заниматься этим в России».&nbsp;","type":"p","className":""},{"data":"Чуть больше чем за год авторы дата-отдела «Важных историй» получили четыре премии <a href=\"https://redkollegia.org/laureates\" data-type=\"usual\" target=\"_blank\">«Редколлегия»</a>.","type":"p","className":""},{"data":"Помимо дата-команд «Важных историй», «Новой газеты», «Медиазоны» и РБК, материалы на данных, конечно, появляются и в других российских медиа. Например, у BBC резонанс вызвало <a href=\"https://www.bbc.com/russian/features-49978027\" data-type=\"usual\" target=\"_blank\">расследование</a> о том, как фермеры из Китая осваивают земли на Дальнем Востоке; у ОВД-инфо (признано иноагентом) — исследование и инфографика об иностранных агентах <a href=\"https://ovdinfo.org/inoteka\" data-type=\"usual\" target=\"_blank\">«Инотека»</a>; в «Тинькофф Журнале», где работает дата-журналист Алексей Смагин, теперь тоже часто появляются <a href=\"https://journal.tinkoff.ru/user195973/\" data-type=\"usual\" target=\"_blank\">исследования</a> на данных.&nbsp;","type":"p","className":""},{"data":"Что происходит с журналистикой данных в соседних странах","type":"h2","className":""},{"data":"В Украине самое титулованное издание, которые публикует дата-журналистику, — <a href=\"https://texty.org.ua/projects/\" data-type=\"usual\" target=\"_blank\">Texty.org.ua</a>. С момента его основания в 2010 году авторы начали делать визуализации данных, а уже в 2012 году вошли в шорт-лист первого международного конкурса журналистики данных Data Journalism Awards с <a href=\"https://z.texty.org.ua/\" data-type=\"usual\" target=\"_blank\">поисковиком</a> по базе госзакупок. В 2016 они сделали оригинальную <a href=\"https://texty.org.ua/d/static/decl_game/\" data-type=\"usual\" target=\"_blank\">игру</a> «Деньги, метры, два автомобиля», где предлагали читателю угадать официальный доход чиновника исходя из недвижимости и автопарка, которыми он владеет.&nbsp;","type":"p","className":""},{"data":"Другой резонансный проект Texty — <a href=\"https://texty.org.ua/d/2018/amber_eng/\" data-type=\"usual\" target=\"_blank\">«Земляная проказа»</a>, в котором журналисты с помощью спутниковых данных и машинного обучения нашли места незаконной добычи янтаря. В 2020-м Texty получили премию Sigma за <a href=\"https://topic-radar.texty.org/#/\" data-type=\"usual\" target=\"_blank\">проект</a> по поиску дезинформации из России с помощью методов компьютерной лингвистики и за сервис для разоблачения фейков <a href=\"https://fgz.texty.org/\" data-type=\"usual\" target=\"_blank\">«Фейкогрыз</a>».","type":"p","className":""},{"data":"В Центральной Азии дата-журналистика развивается в первую очередь в Кыргызстане, где работает годовая стипендиальная программа по дата-журналистике международной НКО Internews и <a href=\"http://opendata.kg/\" data-type=\"usual\" target=\"_blank\">Школа Данных Кыргызстан</a>. Школа данных организует ежегодную международную конференцию по дата-журналистике на русском языке <a href=\"https://lampa2021.tilda.ws/\" data-type=\"usual\" target=\"_blank\">LAMPA</a>. В 2020 году сразу в трех кыргызских изданиях — <a href=\"https://24.kg/\" data-type=\"usual\" target=\"_blank\">24.kg</a>, <a href=\"https://kaktus.media/\" data-type=\"usual\" target=\"_blank\">kaktus.media</a> и <a href=\"https://kloop.kg/\" data-type=\"usual\" target=\"_blank\">kloop.kg</a> — появились дата-отделы.&nbsp;","type":"p","className":""},{"data":"В дата-отделе Kloop есть программисты, что позволяет делать сложные технические проекты. Например, <a href=\"https://kloop.kg/blog/2020/10/12/lukoshko-kloop-kg/\" data-type=\"usual\" target=\"_blank\">«Лукошко»</a> на основе машинного обучения. В него можно загрузить изображение любого политика и увидеть, как часто он мелькает на телевидении. Сервис <a href=\"https://kloop.kg/blog/2020/07/15/kolca-korrupcii-goszakupki/\" data-type=\"usual\" target=\"_blank\">«Кольца коррупции»</a>, созданный с помощью графов на основе объединенной базы госзакупок и зарегистрированных в Минюсте юридических лиц, позволяет в полуавтоматическом режиме выявлять коррупционные схемы.","type":"p","className":""},{"data":"Главный проект 2021 года — исследование масштабов фемицида (убийства женщин мужчинами на почве ненависти, гендерной дискриминации) в Кыргызстане<a href=\"https://kloop.kg/blog/2020/12/17/ya-by-ee-vse-ravno-ubil-issledovanie-kloopa-o-femitside-v-kyrgyzstane/\" data-type=\"usual\" target=\"_blank\"> «Я бы ее все равно убил»</a>, опубликованный в Kloop. По словам соосновательницы Школы Данных Кыргызстана, в прошлом главного ментора программы по дата-журналистике Internews Анастасии Валеевой, оно стало результатом многих лет работы по развитию дата-журналистики в Кыргызстане. Этот материал послужил основой для дискуссии о фемициде в Кыргызстане и всей Центральной Азии — и о том, как его остановить. Проект стал<a href=\"http://sigmaawards.org/i-would-have-killed-her-anyway-kloops-investigation-of-femicide-in-kyrgyzstan/\" data-type=\"usual\" target=\"_blank\"> победителем</a> международной премии по дата-журналистике Sigma.","type":"p","className":""},{"data":"Также Анастасия отметила дата-исследования о плачевном состоянии <a href=\"https://rus.azattyk.org/a/schools/31439009.html\" data-type=\"usual\" target=\"_blank\">школ Кыргызстана</a> и расследование о том, как Кыргызстан живет на деньги <a href=\"https://kloop.kg/blog/2018/08/23/strana-na-izhdivenii-kyrgyzstan-vyzhivaet-na-dengi-migrantov-no-ne-umeet-ih-tratit/\" data-type=\"usual\" target=\"_blank\">мигрантов</a>.","type":"p","className":""},{"data":"Что дальше&nbsp;","type":"h2","className":""},{"data":"Во второй части нашего обзора дата-журналистики расскажем:","type":"p","className":""},{"data":"<li>о сегодняшних трендах в российской дата-журналистике и о том, что ее ждет в будущем;</li><li>где и зачем учиться журналистике данных и где работать. </li>","type":"ul","className":""}]},{"id":337,"header":"Парсинг с помощью Python. Урок 2","_path":"/workshops/2021/09/20/parsing-s-pomoshchyu-python-urok-2/","lead":"Учимся скрейпить сайты с помощью библиотеки Selenium","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/7ffb9d1516414e3cb0cec39b809dbc04-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-09-20","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Продолжаем изучать парсинг с Python. В прошлый раз мы использовали библиотеки Requests и Beautifulsoup — но не всегда можно обойтись только ими. Сегодня поговорим о библиотеке Selenium. \n\n\nС ее помощью мы можем имитировать действия пользователя в браузере, — то есть, сайт действительно будет открываться на компьютере, а затем скрипт будет выполнять прописанные нами действия.\n\nВ первом уроке по парсингу мы работали с сайтом «КиноПоиск» и его списком топ-250 фильмов. Это было довольно просто: при переходе со страницы на страницу ссылка менялась предсказуемо, и мы смогли прописать это условие в коде. Но есть сайты, где все работает иначе. \n\nНапример, реестр с информацией о государственных муниципальных учреждениях. Попробуем найти в нем онкологические диспансеры и посмотрим, как будет выглядеть ссылка.\n\n\nНа скриншоте видно, что после нашего запроса ссылка не изменилась. Она не изменится и когда мы перейдем на следующую страницу. Как раз для таких случаев пригодится библиотека Selenium,— скрипт сам забьет нужный запрос в поисковую строку, нажмет «Показать», начнет собирать нужные нам данные и так далее.\n\nЧтобы воспользоваться этой библиотекой, необходимо скачать ChromeDriver под вашу версию браузера Chrome (если версии не будут совпадать, ваш код не сработает). Распакуйте файл chromedriver, для удобства можно положить его в корневую директорию или на рабочий стол. \n\nДалее через Jupyter установим саму библиотеку с помощью pip install.\n\n\nТеперь импортируем из Selenium все необходимые нам команды и функции. Также нам сегодня пригодятся библиотеки Beautifulsoup, sleep и tqdm — импортируем и их. \n\n\nСледующие шаги будут похожи на то, что мы делали в прошлом уроке, но у библиотеки будет другой синтаксис. Сначала запустим наш ChromeDriver, на macOS это делается так: создаем переменную browser, указываем команду Chrome и в кавычках прописываем путь до ранее распакованного ChromeDriver.\n\n\nПосле выполнения команды откроется сам браузер.\n\n\nТеперь мы можем управлять браузером с помощью команд. Чтобы попасть на сайт, создадим переменную url и укажем нужный сайт (в нашем примере: https://bus.gov.ru/registry). По аналогии с Requests, воспользуемся методом get и передаем на вход эту переменную.\n\n\nСайт должен загрузиться в нашем Chrome. Забьем критерий поиска — чтобы это сделать, как и в прошлый раз, изучим HTML-код страницы с помощью функции «Посмотреть код» (делать это лучше в обычном браузере, а не в управляемом Selenium).\n\n\nКак видно в панели разработчика, здесь всё достаточно приятно и понятно, тег и класс выглядят уникальными. Но при этом стоит помнить об особенности Beautifulsoup, которая есть и в Selenium — если вы указываете запрос к какому-то элементу, запрос всегда будет выбирать первый элемент из кода. \n\nПоэтому сперва найдем этот тег на странице с помощью команды из группы find. Если после ввода find вы нажмете Tab на клавиатуре, появятся несколько параметров поиска на выбор: по имени класса, по CSS-селектору, по id и так далее.\n\n\nНам нужен tag_name, конкретно — input. \n\n\nСообщение, как на скриншоте выше, показывает, что пока мы всё сделали правильно — объект был найден браузером. Можем попробовать также поиск по class_name. Но будьте внимательны: если в HTML-коде внутри названия класса есть пробелы, то это на самом деле несколько разных названий. Поэтому, если скопировать всё целиком, то Selenium выдаст ошибку. \n\n\nДля примера возьмем первый класс элемента (search-input) и снова получим ответ от Selenium. Есть еще способы найти нужный элемент. Например, кликнуть правой кнопкой мыши на нужный кусок кода и в контекстном меню Copy выбрать Copy XPath.\n\n\nСнова воспользуемся командой find, но выберем поиск по xpath.\n\n\nПо аналогии в контекстном меню Copy можно выбрать Copy selector — тогда соответственно меняем критерий в find на css_selector.\n\nТаким же образом можно искать ссылки по тексту на странице. В шапке виден, например, кликабельный текст «Результаты независимой оценки». Критерий для команды find в таком случае будет link_text. Чтобы вытащить саму ссылку, добавим команду get по атрибуту href.\n\n\nВернемся к полю ввода. Выберем одну из наших поисковых функций и зададим этой переменной название input_tab. Добавим в нее наш поисковый запрос с помощью функции send_keys и проверим, выполнился ли запрос в окне браузера, которым управляет ChromeDriver.\n\n\nСледующий шаг — клик по кнопке «Показать». Посмотрим ее код. \n\n\nУ кнопки есть тег button и несколько классов. Чаще всего (и в нашем примере тоже) не стоит надеяться, что мы просто вызовем тег button, и это окажется именно нужная нам кнопка. Лучше вытащить конкретный XPath элемента самим. \n\nДля этого воспользуемся уже знакомой командой find_element_by_xpath, пропишем название тега, в котором хотим найти нужный XPath, и в квадратных скобках через @ добавим атрибут, по которому уточним запрос. В нашем случае самый удачный атрибут — type и его подходящее значение submit. \n\n\nНазовем эту переменную button, и следующим шагом просто кликнем на нее командой click.\n\n\nВ браузере должна появиться выдача по ранее введенному запросу.\n\nКстати, в этом случае можно было не искать кнопку, а с помощью команды send_keys имитировать нажатие Enter на клавиатуре, чтобы запустить поиск. Так можно имитировать нажатие любых клавиш или их сочетаний.\n\n\nТеперь, когда у нас есть отсортированная база, можем начать ее парсить. Например, попробуем получить ссылки на регистрационные данные каждой компании и сделать таблицу из этих ссылок и названий соответствующих компаний. \n\nВытянем название по уже привычной схеме: кликнем на «Посмотреть код» и найдем тег (a) и класс (result__title). Дальше воспользуемся сразу двумя библиотеками, Selenium и Beautifulsoup. Код страницы, который мы читаем с помощью Selenium, передаем в Beautifulsoup через команду browser.page_source. Теперь, если вызвать эту команду, мы увидим код страницы целиком.\n\n\nС помощью Beautifulsoup и команды find найдем тег a и класс result__title, сразу переведя результат в текст и убрав лишние пробельные символы (командой strip). Назовем переменную name.\n\n\nСледующий шаг — ссылка на регистрационные данные. Снова кликнем на «Посмотреть код», находим тег и класс. Классов указано несколько, возьмем только второй, потому что он выглядит уникальным для этого элемента.\n\n\nСоздаем переменную link, вводим необходимые тег и класс, запросим href командой get. В начало добавим домен, чтобы получить ссылку целиком.\n\n\nМы разобрались с первым элементом из списка поисковой выдачи. Но нам нужно пройтись по всем, а еще не забыть про следующие страницы. Посмотрим, в каких тегах лежат все наши данные. \n\n\nПо карточкам можно пройтись как с помощью Beautifulsoup, так и с помощью Selenium. Сначала сделаем так, как уже делали в прошлом уроке. Введем команду findAll, чтобы найти все нужные div-ы с классом result. Проверим с помощью len, сколько их на странице. Должно получиться 10. \n\n\nЕсли выполнять то же через Selenium, нужно использовать переменную browser, команду find_elements_by_class_name (обратите внимание: elements сейчас во множественном числе, а не в единственном, как мы писали ранее сегодня) и название класса result. Для уверенности можно снова перепроверить длину списка.\n\n\nСоберем все необходимые команды в одну ячейку, чтобы с ними было удобнее работать. Организации, которые мы собираем со страницы сайта, положим в переменную orgs. \n\n\nСоздаем цикл. Для каждой организации будем доставать сначала название, затем ссылку. В цикле не забудьте заменить soup на org. Добавим в начало ячейки переменную data, куда запишем все результаты. \n\n\nТеперь запускаем код. Но он вернет нам ошибку.\n\n\nДело в том, что Selenium устроен таким образом, что пока страница не прогрузится целиком, функции Beautifulsoup не смогут ничего найти. Здесь нам поможет библиотека sleep — сделаем небольшую задержку между поисковым запросом и непосредственно сбором данных со страницы.\n\n\nЗапросим содержание data — и увидим, что в этот раз всё получилось.\n\n\nОсталось дописать только автопереходы между страницами. Проверим код кнопки «Следующая», чтобы дописать эту команду в цикл. \n\n\nСтраниц в нашем случае 9 — значит, необходимо 9 раз кликнуть на кнопку «Следующая» и собрать данные. Воспользуемся, как и в прошлом уроке, циклом for p in range 10 (на 1 больше, чем нужно). Попросим скрипт печатать не только количество собранных карточек, но и пройденную страницу.\n\nДопишем команду find по названию класса pagination_next и непосредственно click. После перехода добавим задержку с помощью sleep, чтобы данные успели прогрузиться.\n\n\nТеперь можно снова запросить содержание data, чтобы получить все названия организаций и ссылки, который выводит сайт по нашему запросу. После этого их можно сохранить в таблицу, как мы делали в прошлый раз, и работать с ними дальше.\n\nОстались вопросы? Задавайте их в нашем Telegram-чате, постараемся ответить.","blocks":[{"data":"Продолжаем изучать парсинг с Python. В <a href=\"https://istories.media/workshops/2021/09/10/parsing-s-pomoshchyu-python-urok-1/\" data-type=\"usual\" target=\"_blank\">прошлый раз</a> мы использовали библиотеки <strong>Requests</strong> и <strong>Beautifulsoup</strong> — но не всегда можно обойтись только ими. Сегодня поговорим о библиотеке <strong>Selenium</strong>. ","type":"p","className":""},{"data":{"id":2937,"data":{"url":"https://www.youtube.com/embed/oqS-bR5m1bI","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=oqS-bR5m1bI","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"С ее помощью мы можем имитировать действия пользователя в браузере, —&nbsp;то есть, сайт действительно будет открываться на компьютере, а затем скрипт будет выполнять прописанные нами действия.","type":"p","className":""},{"data":"В <a href=\"https://istories.media/workshops/2021/09/10/parsing-s-pomoshchyu-python-urok-1/\" data-type=\"usual\" target=\"_blank\">первом уроке по парсингу</a> мы работали с сайтом «КиноПоиск» и его списком топ-250 фильмов. Это было довольно просто: при переходе со страницы на страницу ссылка менялась предсказуемо, и мы смогли прописать это условие в коде. Но есть сайты, где все работает иначе.&nbsp;","type":"p","className":""},{"data":"Например, <a href=\"https://bus.gov.ru/registry\" data-type=\"usual\" target=\"_blank\">реестр с информацией о государственных муниципальных учреждениях</a>. Попробуем найти в нем онкологические диспансеры и посмотрим, как будет выглядеть ссылка.","type":"p","className":""},{"data":{"id":2938,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/af9af4e8317345dbbfc68f3746e84d48-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/af9af4e8317345dbbfc68f3746e84d48-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":616,"real_height_2x":1234},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/af9af4e8317345dbbfc68f3746e84d48-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/af9af4e8317345dbbfc68f3746e84d48-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":616,"real_height_2x":1234}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"На скриншоте видно, что после нашего запроса ссылка не изменилась. Она не изменится и когда мы перейдем на следующую страницу. Как раз для таких случаев пригодится библиотека <strong>Selenium</strong>,— скрипт сам забьет нужный запрос в поисковую строку, нажмет «Показать», начнет собирать нужные нам данные и так далее.","type":"p","className":""},{"data":"Чтобы воспользоваться этой библиотекой, необходимо <a href=\"https://chromedriver.chromium.org/downloads\" data-type=\"usual\" target=\"_blank\">скачать ChromeDriver</a> под вашу версию браузера Chrome (если версии не будут совпадать, ваш код не сработает). Распакуйте файл <strong>chromedriver</strong>, для удобства можно положить его в корневую директорию или на рабочий стол.&nbsp;","type":"p","className":""},{"data":"Далее через <strong>Jupyter</strong> установим саму библиотеку с помощью <strong>pip install</strong>.","type":"p","className":""},{"data":{"id":2939,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4f6bf3f79cbb4d02a82bf64a9ab1d20b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4f6bf3f79cbb4d02a82bf64a9ab1d20b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":176,"real_height_2x":352},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4f6bf3f79cbb4d02a82bf64a9ab1d20b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4f6bf3f79cbb4d02a82bf64a9ab1d20b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":176,"real_height_2x":352}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь импортируем из <strong>Selenium</strong> все необходимые нам команды и функции.&nbsp;Также нам сегодня пригодятся библиотеки <strong>Beautifulsoup</strong>, <strong>sleep</strong> и <strong>tqdm</strong> — импортируем и их.&nbsp;","type":"p","className":""},{"data":{"id":2940,"data":{"images":[{"credit":"Библиотека tqdm нужна для того, чтобы в Jupyter отображалась полоска, заполняемая по мере прогресса работы основного скрипта","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/287f38ced1004dae97c120b699f8afef-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/287f38ced1004dae97c120b699f8afef-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":184,"real_height_2x":367},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/287f38ced1004dae97c120b699f8afef-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/287f38ced1004dae97c120b699f8afef-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":184,"real_height_2x":367}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Следующие шаги будут похожи на то, что мы делали в <a href=\"https://istories.media/workshops/2021/09/10/parsing-s-pomoshchyu-python-urok-1/\" data-type=\"usual\" target=\"_blank\">прошлом уроке</a>, но у библиотеки будет другой синтаксис. Сначала запустим наш ChromeDriver, на macOS это делается так: создаем переменную <strong>browser</strong>, указываем команду Chrome и в кавычках прописываем путь до ранее распакованного ChromeDriver.","type":"p","className":""},{"data":{"id":2941,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/531b0c478357481aa14dd1f1a1616670-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/531b0c478357481aa14dd1f1a1616670-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":78,"real_height_2x":156},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/531b0c478357481aa14dd1f1a1616670-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/531b0c478357481aa14dd1f1a1616670-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":78,"real_height_2x":156}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"После выполнения команды откроется сам браузер.","type":"p","className":""},{"data":{"id":2942,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/966292be70014e35b3a15fca551e9bf1-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/966292be70014e35b3a15fca551e9bf1-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":302,"real_height_2x":604},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/966292be70014e35b3a15fca551e9bf1-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/966292be70014e35b3a15fca551e9bf1-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":302,"real_height_2x":604}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь мы можем управлять браузером с помощью команд. Чтобы попасть на сайт, создадим переменную <strong>url</strong> и укажем нужный сайт (в нашем примере: <a href=\"https://bus.gov.ru/registry\" data-type=\"usual\" target=\"_blank\">https://bus.gov.ru/registry</a>). По аналогии с <strong>Requests</strong>, воспользуемся методом <strong>get</strong> и передаем на вход эту переменную.","type":"p","className":""},{"data":{"id":2943,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a42251d979f84fe6b939ef25454d5e70-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a42251d979f84fe6b939ef25454d5e70-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":202,"real_height_2x":405},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a42251d979f84fe6b939ef25454d5e70-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a42251d979f84fe6b939ef25454d5e70-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":202,"real_height_2x":405}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Сайт должен загрузиться в нашем Chrome. Забьем критерий поиска — чтобы это сделать, как и в прошлый раз, изучим HTML-код страницы с помощью функции «Посмотреть код» (делать это лучше в обычном браузере, а не в управляемом <strong>Selenium</strong>).","type":"p","className":""},{"data":{"id":2944,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d5a94939bca14da89cab5d09aca63be6-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d5a94939bca14da89cab5d09aca63be6-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":408,"real_height_2x":816},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/d5a94939bca14da89cab5d09aca63be6-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/d5a94939bca14da89cab5d09aca63be6-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":408,"real_height_2x":816}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Как видно в панели разработчика, здесь всё достаточно приятно и понятно, тег и класс выглядят уникальными. Но при этом стоит помнить об особенности <strong>Beautifulsoup</strong>, которая есть и в <strong>Selenium</strong> —&nbsp;если вы указываете запрос к какому-то элементу, запрос всегда будет выбирать первый элемент из кода.&nbsp;","type":"p","className":""},{"data":"Поэтому сперва найдем этот тег на странице с помощью команды из группы <strong>find</strong>. Если после ввода <strong>find</strong> вы нажмете <strong>Tab</strong> на клавиатуре, появятся несколько параметров поиска на выбор: по имени класса, по CSS-селектору, по <strong>id</strong> и так далее.","type":"p","className":""},{"data":{"id":2945,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/33e6f78cc34a48eeabb9b5c587593bde-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/33e6f78cc34a48eeabb9b5c587593bde-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":407,"real_height_2x":814},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/33e6f78cc34a48eeabb9b5c587593bde-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/33e6f78cc34a48eeabb9b5c587593bde-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":407,"real_height_2x":814}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Нам нужен<strong> tag_name</strong>, конкретно —&nbsp;<strong>input</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2946,"data":{"images":[{"credit":"Вся страница теперь — объект Selenium","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/fdfd1c40ff2c48058f3ca0da309ca64e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/fdfd1c40ff2c48058f3ca0da309ca64e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":107,"real_height_2x":214},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/fdfd1c40ff2c48058f3ca0da309ca64e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/fdfd1c40ff2c48058f3ca0da309ca64e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":107,"real_height_2x":214}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Сообщение, как на скриншоте выше, показывает, что пока мы всё сделали правильно — объект был найден браузером. Можем попробовать также поиск по <strong>class_name</strong>. Но будьте внимательны: если в HTML-коде внутри названия класса есть пробелы, то это на самом деле несколько разных названий. Поэтому, если скопировать всё целиком, то <strong>Selenium</strong> выдаст ошибку.&nbsp;","type":"p","className":""},{"data":{"id":2947,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/57ad7fefbf974c2fbc1b9ef0e3725e8a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/57ad7fefbf974c2fbc1b9ef0e3725e8a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":508,"real_height_2x":1016},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/57ad7fefbf974c2fbc1b9ef0e3725e8a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/57ad7fefbf974c2fbc1b9ef0e3725e8a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":508,"real_height_2x":1016}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Для примера возьмем первый класс элемента (<strong>search-input</strong>) и снова получим ответ от <strong>Selenium</strong>.&nbsp;Есть еще способы найти нужный элемент. Например, кликнуть правой кнопкой мыши на нужный кусок кода и в контекстном меню <strong>Copy</strong> выбрать <strong>Copy XPath</strong>.","type":"p","className":""},{"data":{"id":2948,"data":{"images":[{"credit":"XPath — это прямой путь до элемента в дереве сайта","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9ddbdd12aa814a018936524fd425093e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9ddbdd12aa814a018936524fd425093e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":588,"real_height_2x":1175},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9ddbdd12aa814a018936524fd425093e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9ddbdd12aa814a018936524fd425093e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":588,"real_height_2x":1175}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Снова воспользуемся командой <strong>find</strong>, но выберем поиск по <strong>xpath</strong>.","type":"p","className":""},{"data":{"id":2949,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/977c52bf05394fd8b0da9fba21064c7d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/977c52bf05394fd8b0da9fba21064c7d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":100,"real_height_2x":202},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/977c52bf05394fd8b0da9fba21064c7d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/977c52bf05394fd8b0da9fba21064c7d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":100,"real_height_2x":202}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"По аналогии в контекстном меню <strong>Copy</strong> можно выбрать <strong>Copy selector</strong> — тогда соответственно меняем критерий в <strong>find</strong> на <strong>css_selector</strong>.","type":"p","className":""},{"data":"Таким же образом можно искать ссылки по тексту на странице. В шапке виден, например, кликабельный текст «Результаты независимой оценки». Критерий для команды <strong>find</strong> в таком случае будет <strong>link_text</strong>. Чтобы вытащить саму ссылку, добавим команду <strong>get</strong> по атрибуту <strong>href</strong>.","type":"p","className":""},{"data":{"id":2950,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5345dce4bde9400fba078536f0e13a04-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5345dce4bde9400fba078536f0e13a04-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":110,"real_height_2x":220},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5345dce4bde9400fba078536f0e13a04-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5345dce4bde9400fba078536f0e13a04-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":110,"real_height_2x":220}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Вернемся к полю ввода. Выберем одну из наших поисковых функций и зададим этой переменной название <strong>input_tab</strong>. Добавим в нее наш поисковый запрос с помощью функции <strong>send_keys</strong> и проверим, выполнился ли запрос в окне браузера, которым управляет ChromeDriver.","type":"p","className":""},{"data":{"id":2951,"data":{"images":[{"credit":"Просим Selenium поискать «онкологический диспансер»...","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c7958dbd8a54419dba237a004be631b8-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c7958dbd8a54419dba237a004be631b8-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":287,"real_height_2x":574},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/c7958dbd8a54419dba237a004be631b8-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/c7958dbd8a54419dba237a004be631b8-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":287,"real_height_2x":574}]},{"credit":"...и он ищет","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bea98332744640a886081164f220e49b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bea98332744640a886081164f220e49b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":648,"real_height_2x":1296},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bea98332744640a886081164f220e49b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/bea98332744640a886081164f220e49b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":648,"real_height_2x":1296}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Следующий шаг — клик по кнопке «Показать». Посмотрим ее код.&nbsp;","type":"p","className":""},{"data":{"id":2970,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/0632e1a149da48ca9eed909ceafc020f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/0632e1a149da48ca9eed909ceafc020f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":542,"real_height_2x":1084},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/0632e1a149da48ca9eed909ceafc020f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/0632e1a149da48ca9eed909ceafc020f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":542,"real_height_2x":1084}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"У кнопки есть тег <strong>button</strong> и несколько классов. Чаще всего (и в нашем примере тоже) не стоит надеяться, что мы просто вызовем тег <strong>button</strong>, и это окажется именно нужная нам кнопка. Лучше вытащить конкретный <strong>XPath</strong> элемента самим. ","type":"p","className":""},{"data":"Для этого воспользуемся уже знакомой командой<strong> find_element_by_xpath</strong>, пропишем название тега, в котором хотим найти нужный <strong>XPath</strong>, и в квадратных скобках через <strong>@</strong> добавим атрибут, по которому уточним запрос. В нашем случае самый удачный атрибут — <strong>type</strong> и его подходящее значение <strong>submit</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2952,"data":{"images":[{"credit":"Обратите внимание на синтаксис и особенно на кавычки: сначала одинарные, затем двойные","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/165365df15f047cdb39795c5cc3e4850-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/165365df15f047cdb39795c5cc3e4850-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":150,"real_height_2x":299},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/165365df15f047cdb39795c5cc3e4850-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/165365df15f047cdb39795c5cc3e4850-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":150,"real_height_2x":299}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Назовем эту переменную <strong>button</strong>, и следующим шагом просто кликнем на нее командой <strong>click</strong>.","type":"p","className":""},{"data":{"id":2953,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/6c92a011963444658ed46550b61c3a69-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/6c92a011963444658ed46550b61c3a69-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":180,"real_height_2x":359},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/6c92a011963444658ed46550b61c3a69-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/6c92a011963444658ed46550b61c3a69-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":180,"real_height_2x":359}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В браузере должна появиться выдача по ранее введенному запросу.","type":"p","className":""},{"data":"Кстати, в этом случае можно было не искать кнопку, а с помощью команды <strong>send_keys</strong> имитировать нажатие <strong>Enter</strong> на клавиатуре, чтобы запустить поиск. Так можно имитировать нажатие любых клавиш или их сочетаний.","type":"p","className":""},{"data":{"id":2954,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/dc54bb53e8cc4e93b3639eb83949f545-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/dc54bb53e8cc4e93b3639eb83949f545-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":159,"real_height_2x":318},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/dc54bb53e8cc4e93b3639eb83949f545-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/dc54bb53e8cc4e93b3639eb83949f545-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":159,"real_height_2x":318}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь, когда у нас есть отсортированная база, можем начать ее парсить. Например, попробуем получить ссылки на регистрационные данные каждой компании и сделать таблицу из этих ссылок и названий соответствующих компаний.&nbsp;","type":"p","className":""},{"data":"Вытянем название по уже привычной схеме: кликнем на «Посмотреть код»&nbsp;и найдем тег (<strong>a</strong>) и класс (<strong>result__title</strong>). Дальше воспользуемся сразу двумя библиотеками, <strong>Selenium</strong> и <strong>Beautifulsoup</strong>. Код страницы, который мы читаем с помощью <strong>Selenium</strong>, передаем в <strong>Beautifulsoup</strong> через команду <strong>browser.page_source</strong>. Теперь, если вызвать эту команду, мы увидим код страницы целиком.","type":"p","className":""},{"data":{"id":2956,"data":{"images":[{"credit":"Раньше мы получали код с помощью r.text","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/0970e20460eb4df1be8dd1301ebacfbe-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/0970e20460eb4df1be8dd1301ebacfbe-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":260,"real_height_2x":520},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/0970e20460eb4df1be8dd1301ebacfbe-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/0970e20460eb4df1be8dd1301ebacfbe-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":260,"real_height_2x":520}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"С помощью <strong>Beautifulsoup</strong> и команды <strong>find</strong> найдем тег <strong>a</strong> и класс <strong>result__title</strong>, сразу переведя результат в текст и убрав лишние пробельные символы (командой <strong>strip</strong>). Назовем переменную <strong>name</strong>.","type":"p","className":""},{"data":{"id":2955,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c1ef1799073e4a28b451ce4d495246cf-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c1ef1799073e4a28b451ce4d495246cf-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":95,"real_height_2x":190},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/c1ef1799073e4a28b451ce4d495246cf-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/c1ef1799073e4a28b451ce4d495246cf-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":95,"real_height_2x":190}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Следующий шаг — ссылка на регистрационные данные. Снова кликнем на «Посмотреть код», находим тег и класс. Классов указано несколько, возьмем только второй, потому что он выглядит уникальным для этого элемента.","type":"p","className":""},{"data":{"id":2957,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/05f24bda212240e8a24eee379a345c73-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/05f24bda212240e8a24eee379a345c73-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":382,"real_height_2x":765},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/05f24bda212240e8a24eee379a345c73-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/05f24bda212240e8a24eee379a345c73-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":382,"real_height_2x":765}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Создаем переменную <strong>link</strong>, вводим необходимые тег и класс, запросим <strong>href</strong> командой <strong>get</strong>. В начало добавим домен, чтобы получить ссылку целиком.","type":"p","className":""},{"data":{"id":2958,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/61bf2c0878804544ba56754944f85e17-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/61bf2c0878804544ba56754944f85e17-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":120,"real_height_2x":241},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/61bf2c0878804544ba56754944f85e17-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/61bf2c0878804544ba56754944f85e17-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":120,"real_height_2x":241}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы разобрались с первым элементом из списка поисковой выдачи. Но нам нужно пройтись по всем, а еще не забыть про следующие страницы. Посмотрим, в каких тегах лежат все наши данные.&nbsp;","type":"p","className":""},{"data":{"id":2960,"data":{"images":[{"credit":"В нашем случае это тег div с классом result","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ed8933b84554447db5cf86a1825889a4-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ed8933b84554447db5cf86a1825889a4-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":404,"real_height_2x":809},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ed8933b84554447db5cf86a1825889a4-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ed8933b84554447db5cf86a1825889a4-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":404,"real_height_2x":809}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"По карточкам можно пройтись как с помощью <strong>Beautifulsoup</strong>, так и с помощью <strong>Selenium</strong>. Сначала сделаем так, как уже делали в <a href=\"https://istories.media/workshops/2021/09/10/parsing-s-pomoshchyu-python-urok-1/\" data-type=\"usual\" target=\"_blank\">прошлом уроке</a>. Введем команду <strong>findAll</strong>, чтобы найти все нужные <strong>div</strong>-ы с классом <strong>result</strong>.&nbsp;Проверим с помощью <strong>len</strong>, сколько их на странице. Должно получиться <strong>10</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2961,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/dff77cdc8fae44f4badf119e2ff626c9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/dff77cdc8fae44f4badf119e2ff626c9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":164,"real_height_2x":328},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/dff77cdc8fae44f4badf119e2ff626c9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/dff77cdc8fae44f4badf119e2ff626c9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":164,"real_height_2x":328}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если выполнять то же через <strong>Selenium</strong>, нужно использовать переменную <strong>browser</strong>, команду <strong>find_elements_by_class_name</strong> (обратите внимание: <strong>elements </strong>сейчас во множественном числе, а не в единственном, как мы писали ранее сегодня) и название класса <strong>result</strong>. Для уверенности можно снова перепроверить длину списка.","type":"p","className":""},{"data":{"id":2962,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/219a93d41dc043ddaa32f7a5661e66ef-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/219a93d41dc043ddaa32f7a5661e66ef-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":156,"real_height_2x":312},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/219a93d41dc043ddaa32f7a5661e66ef-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/219a93d41dc043ddaa32f7a5661e66ef-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":156,"real_height_2x":312}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Соберем все необходимые команды в одну ячейку, чтобы с ними было удобнее работать. Организации, которые мы собираем со страницы сайта, положим в переменную <strong>orgs</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2963,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/0950d6c921c24082a4bbf53ffb4ab063-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/0950d6c921c24082a4bbf53ffb4ab063-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":314,"real_height_2x":627},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/0950d6c921c24082a4bbf53ffb4ab063-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/0950d6c921c24082a4bbf53ffb4ab063-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":314,"real_height_2x":627}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Создаем цикл. Для каждой организации будем доставать сначала название, затем ссылку. В цикле не забудьте заменить <strong>soup</strong> на <strong>org</strong>. Добавим в начало ячейки переменную <strong>data</strong>, куда запишем все результаты.&nbsp;","type":"p","className":""},{"data":{"id":2964,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1b2be7ae3d4f4c52907af562d7182676-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1b2be7ae3d4f4c52907af562d7182676-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":408,"real_height_2x":818},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1b2be7ae3d4f4c52907af562d7182676-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1b2be7ae3d4f4c52907af562d7182676-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":408,"real_height_2x":818}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь запускаем код. Но он вернет нам ошибку.","type":"p","className":""},{"data":{"id":2965,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4e962c3f84e24d4aa66191536b7130cb-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4e962c3f84e24d4aa66191536b7130cb-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":351,"real_height_2x":702},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4e962c3f84e24d4aa66191536b7130cb-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4e962c3f84e24d4aa66191536b7130cb-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":351,"real_height_2x":702}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Дело в том, что <strong>Selenium</strong> устроен таким образом, что пока страница не прогрузится целиком, функции <strong>Beautifulsoup</strong> не смогут ничего найти. Здесь нам поможет библиотека <strong>sleep</strong> —&nbsp;сделаем небольшую задержку между поисковым запросом и непосредственно сбором данных со страницы.","type":"p","className":""},{"data":{"id":2966,"data":{"images":[{"credit":"В конце дописали print(len(data)), чтобы проверить работоспособность кода. Напечаталось 10 — значит, скрипт прошелся по всем карточкам","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/91d8b030cee84936b0776bf6319aa5f5-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/91d8b030cee84936b0776bf6319aa5f5-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":546,"real_height_2x":1092},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/91d8b030cee84936b0776bf6319aa5f5-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/91d8b030cee84936b0776bf6319aa5f5-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":546,"real_height_2x":1092}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Запросим содержание <strong>data</strong> — и увидим, что в этот раз всё получилось.","type":"p","className":""},{"data":{"id":2967,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/86e96ec0b34a4242a9a80fc1c8d15bbe-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/86e96ec0b34a4242a9a80fc1c8d15bbe-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":405,"real_height_2x":810},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/86e96ec0b34a4242a9a80fc1c8d15bbe-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/86e96ec0b34a4242a9a80fc1c8d15bbe-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":405,"real_height_2x":810}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Осталось дописать только автопереходы между страницами. Проверим код кнопки&nbsp;«Следующая», чтобы дописать эту команду в цикл.&nbsp;","type":"p","className":""},{"data":{"id":2968,"data":{"images":[{"credit":"Очень удобный класс","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/78a61da91feb43ab9d86ae6faef3e2fa-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/78a61da91feb43ab9d86ae6faef3e2fa-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":286,"real_height_2x":571},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/78a61da91feb43ab9d86ae6faef3e2fa-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/78a61da91feb43ab9d86ae6faef3e2fa-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":286,"real_height_2x":571}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Страниц в нашем случае 9 — значит, необходимо 9 раз кликнуть на кнопку «Следующая» и собрать данные. Воспользуемся, как и в прошлом уроке, циклом<strong> for p in range 10</strong> (на 1 больше, чем нужно). Попросим скрипт печатать не только количество собранных карточек, но и пройденную страницу.","type":"p","className":""},{"data":"Допишем команду <strong>find</strong> по названию класса <strong>pagination_next </strong>и непосредственно <strong>click</strong>. После перехода добавим задержку с помощью <strong>sleep</strong>, чтобы данные успели прогрузиться.","type":"p","className":""},{"data":{"id":2969,"data":{"images":[{"credit":"Лучше ставить задержку в районе 10 секунд","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7bc169e4fcb94601812da209c30a549b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7bc169e4fcb94601812da209c30a549b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":574,"real_height_2x":1148},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7bc169e4fcb94601812da209c30a549b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7bc169e4fcb94601812da209c30a549b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":574,"real_height_2x":1148}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь можно снова запросить содержание <strong>data</strong>, чтобы получить все названия организаций и ссылки, который выводит сайт по нашему запросу. После этого их можно сохранить в таблицу, как мы делали в <a href=\"https://istories.media/workshops/2021/09/10/parsing-s-pomoshchyu-python-urok-1/\" data-type=\"usual\" target=\"_blank\">прошлый раз</a>, и работать с ними дальше.","type":"p","className":""},{"data":"Остались вопросы? Задавайте их в нашем <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">Telegram-чате</a>, постараемся ответить.","type":"p","className":""}]},{"id":329,"header":"Парсинг с помощью Python. Урок 1","_path":"/workshops/2021/09/10/parsing-s-pomoshchyu-python-urok-1/","lead":"Учимся скрейпить сайты с помощью библиотек Beautifulsoup и Requests","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/398b3de3d1a04d7dbb3809df47eb8018-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-09-10","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Этим уроком мы начинаем курс, про который нас часто спрашивали — курс по парсингу данных с помощью Python. Мы уже рассказывали о парсинге без программирования, с помощью расширений для браузера, но их возможности ограничены и подходят не для всех сайтов. А вот Python поможет вам спарсить практически что угодно.\n\n\nЧтобы правильно парсить, нужно понимать, как устроены сайты. Почти все они сверстаны с помощью языка HTML. Разберемся в его устройстве на примере сайта «КиноПоиск» и попробуем спарсить список из 250 лучших фильмов по версии пользователей сайта. \n\nПохожим на «КиноПоиск» образом устроены многие сайты, с которых журналистам бывает необходимо собрать данные, поэтому он хорошо подойдет для примера.\n\n\nДля этого курса мы используем браузер Google Chrome, поэтому, чтобы вам было проще понимать наши действия и не путаться в названиях функций, советуем использовать его же. Но в других браузерах, Firefox или Opera, например, все эти функции тоже есть. \n\nЕсли вы кликнете на любое место сайта правой кнопкой мыши и нажмете на «Посмотреть код», то справа появится панель с кодом HTML (ее еще называют панелью разработчика). \n\n\nЭтот язык строится по тегам. Главный — html, в head обычно прописана метаинформация (заголовок, например), а нас сейчас интересует тег body, где лежит основная информация страницы. \n\n\nЧтобы посмотреть код конкретного элемента, нужно кликнуть именно на него и нажать «Посмотреть код» — тогда в панели разработчика подсветится нужный тег.\n\n\nИ наоборот, если двигаться по коду в панели справа, то слева, на самой странице, будет подсвечиваться сверстанный этим тегом элемент.\n\nНа страницах со списками одни и те же теги (название, оценка и так далее) повторяются от карточки к карточке. Поэтому нужно обнаружить и выписать эти конкретные теги. Но сначала вытащим весь код страницы, и здесь пригодится библиотека Requests — мы уже рассказывали о ней, советуем сначала прочитать тот урок и установить ее.\n\nОткрываем Jupyter, импортируем библиотеку с помощью import requests. Чтобы обратиться к сайту, создаем переменную url и присваиваем ей значение нужного сайта (у нас это ссылка на топ «КиноПоиска»).\n\n\nОтправим на сервер запрос с помощью команды get, на вход которой мы передаем переменную url. С помощью команды text посмотрим, что получилось.\n\n\nКак видите, код получился нечитаемым. Справиться с этим поможет другая библиотека, Beautifulsoup. Импортируем ее с помощью команды from bs4 import BeautifulSoup. Возможно, для этого понадобится сначала установить библиотеку через pip install. \n\n\nМы должны передать библиотеке ответ, полученный с помощью Requests. Создадим переменную soup, передадим r.text и укажем необходимый формат (в нашем случае lxml).\n\n\nКод упорядочен, теги идут один за одним — теперь мы можем вынимать из кода то, что нам нужно. Для этого вернемся в браузер, на страницу с данными. Как видно на скриншоте, подряд расположены несколько тегов div с классом desktop-rating-selection-file-item — это карточка каждого из фильмов в списке.\n\n\nСначала вытащим данные только из первой карточки, а затем перепишем код так, чтобы он сработал на все фильмы со страницы. Скопируем название класса — для этого два раза кликните на него мышкой и нажмите Ctrl+C (Cmd+C для macOS). \n\nВ Beautifulsoup есть команда find — укажем ей нужный тег (div) и через запятую класс (desktop-rating-selection-file-item). После class обязательно нужно поставить нижнее подчеркивание.\n\n\nОтобразился уже не весь код, а только нужный элемент, в котором видно название фильма. Вернемся на сайт, чтобы углубиться в карточку и посмотреть, как называются нужные нам детали. Кликнем на название фильма «Зеленая миля» и снова выберем «Посмотреть код». \n\nНапример, мы видим, что ссылка на фильм лежит в теге a и имеет собственный класс selection-film-item-meta__link. В теге a, в свою очередь, есть теги p с русским и оригинальным названиями фильмов. Эти три элемента мы и заберем.\n\n\nДополним нашу первую команду: ставим точку, снова пишем find, указываем тег a и его класс.\n\n\nЧтобы сделать ссылку на фильм работающей, в начале нужно дописать к ней домен. Сама ссылка лежит внутри тега, поэтому find мы применить не сможем. Воспользуемся командой get и укажем нужный атрибут (в нашем случае href).\n\n\nДопишем в начало команды домен «КиноПоиска» и запустим еще раз — так мы получим готовую ссылку. Положим этот код в переменную link. \n\n\nПо аналогии достанем русскоязычное и оригинальное названия. Возьмем тот же код, допишем новый find, укажем нужные тег и класс. Чтобы очистить результат от ненужных элементов кода, добавим в конце команду text. Эти переменные назовем russian_name и original_name соответственно.\n\n\nЕще мы можем достать из карточки страну производства и жанр — все будет работать точно так же, только класс будет не p, как у названий, а span. Страну положим в переменную country.\n\nОднако в коде «КиноПоиска» страна и жанр имеют одинаковый класс selection-film-item-meta__meta-additional-item — а команда find находит только первое соответствие вашему запросу. Применим команду findAll, а все остальное оставим как раньше, чтобы получить список. \n\n\nЧтобы вытащить только жанр, добавим нумерацию в квадратных скобках (не забывайте, что в Python отсчет идет с 0, поэтому нам нужен номер 1) и команду text. Переменную назовем film_type.\n\n\nОсновную информацию о фильме мы достали, но можем получить и кое-что еще — например, оценку. Проверим, как называется класс этого элемента на странице «КиноПоиска» с помощью уже известного метода «Посмотреть код». Как видите, нам повезло — класс имеет уникальное название, глубоко копать не придется.\n\n\nСкопируем ту часть изначальной команды find, где мы заходим в первый div карточки фильма и сразу укажем новый поиск по тегу span и классу rating__value rating__value_positive (и не забудем про text). Переменную назовем rate.\n\n\nМы уже сделали почти всю работу, но пока что наш код работает только для первой карточки фильма в списке. Исправим это. Создадим переменную films, зададим новый поиск по самому первому div, но уже с командой findAll. И заодно посмотрим длину списка с помощью команды len. Их будет 50, потому что список топ-250 разбит на 5 страниц. Далее мы научим код ходить и по другим страницам.\n\n\nНапишем цикл для каждого film в списке films. Пока скопируем команду по поиску link и посмотрим, что там нужно поправить. Нам не нужен запрос к первому div, потому что до этого мы обратились к нему через findAll — заменим его на film. Повторим так с каждым элементом.\n\n\nСоздадим переменную data, в который будем добавлять все переменные, которые запрашиваем.\n\n\nЗапустим код и посмотрим, что отображается в data.\n\n\nВсе ровно так, как нам было нужно. Осталось только разобраться, как собирать данные и со следующих страниц. Если мы перейдем на вторую страницу списка, то увидим, что ссылка в адресной строке браузера изменилась — там появилось page=2. \n\n\nТо есть, нам нужно передать этот параметр в цикл. Создадим перед циклом переменную url и воспользуемся методом f-строк, чтобы поместить внутрь фигурных скобок тот параметр, который нам нужен — номер страницы. Назовем параметр p и поместим его в цикл в промежутке от 1 до 6. \n\nПеременную data при этом нужно вынести в начало кода, чтобы она не перезаписывалась с каждым новым циклом, а дополнялась. После этого скопируем код для запуска Requests и Beautifulsoup. \n\n\nКод готов к работе. Но еще мы советуем добавить временные промежутки между запросами, чтобы не перегружать сервер, к которому обращаемся. Вернемся в область, где ранее импортировали Beautifulsoup, и импортируем из библиотеки time функцию sleep. \n\n\nВ основной код допишем, чтобы между запросами проходило 3 секунды. Чтобы в реальном времени проверить работоспособность скрипта, добавим команду print.\n\n\nВсе должно сработать. Если сейчас снова проверить длину нашего списка командой len(data), там будет 250 — как и в топе «КиноПоиска». Теперь сохраним наши данные в таблицу. Снова вернемся в область импорта и добавим туда Pandas и используем его для записи в csv. \n\n\nВведем названия для колонок — пусть они дублируют названия переменных, которые мы присвоили ранее (не забудьте поместить их в 'кавычки'). И после этого экспортируем наши данные.\n\n\nПоследнее, что мы разберем на этом уроке — как научить код не ломаться и продолжать работу, если у фильма не будет указано какого-то из параметров. Пропишем, например, исключение для рейтинга фильма (rate) — если его нет, будет стоять прочерк.\n\n\n«КиноПоиск» поддался нашему скрипту без проблем, но бывают сайты, запросы с которых не хотят отдавать нам необходимую информацию. Как с этим справиться — расскажем в следующих уроках.\n\nЕсли у вас что-то не получилось — пишите в наш Telegram-чат, постараемся подсказать.","blocks":[{"data":"Этим уроком мы начинаем курс, про который нас часто спрашивали — курс по парсингу данных с помощью Python. Мы уже рассказывали о <a href=\"https://istories.media/workshops/2020/09/09/table-capture-ckreipim-saiti-bez-programmirovaniya/\" data-type=\"usual\" target=\"_blank\">парсинге без программирования</a>, с помощью расширений для браузера, но их возможности ограничены и подходят не для всех сайтов. А вот Python поможет вам спарсить практически что угодно.","type":"p","className":""},{"data":{"id":2864,"data":{"url":"https://www.youtube.com/embed/0ws5tsRBgL8","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=0ws5tsRBgL8","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Чтобы правильно парсить, нужно понимать, как устроены сайты. Почти все они сверстаны с помощью языка HTML. Разберемся в его устройстве&nbsp;на примере сайта «КиноПоиск» и попробуем спарсить <a href=\"https://www.kinopoisk.ru/lists/top250/\" data-type=\"usual\" target=\"_blank\">список</a> из 250 лучших фильмов по версии пользователей сайта.&nbsp;","type":"p","className":""},{"data":"Похожим на «КиноПоиск» образом устроены многие сайты, с которых журналистам бывает необходимо собрать данные, поэтому он хорошо подойдет для примера.","type":"p","className":""},{"data":{"id":2865,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/28d0b9bb42744a5abf35e177c7e990c8-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/28d0b9bb42744a5abf35e177c7e990c8-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":568,"real_height_2x":1136},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/28d0b9bb42744a5abf35e177c7e990c8-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/28d0b9bb42744a5abf35e177c7e990c8-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":568,"real_height_2x":1136}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Для этого курса мы используем браузер Google Chrome, поэтому, чтобы вам было проще понимать наши действия и не путаться в названиях функций, советуем использовать его же. Но в других браузерах, Firefox или Opera, например, все эти функции тоже есть.&nbsp;","type":"p","className":""},{"data":"Если вы кликнете на любое место сайта правой кнопкой мыши и нажмете на «<strong>Посмотреть код</strong>», то справа появится панель с кодом HTML (ее еще называют панелью разработчика). ","type":"p","className":""},{"data":{"id":2866,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/fbe1e81ca7074f0589a445e8c3c9de5e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/fbe1e81ca7074f0589a445e8c3c9de5e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":485,"real_height_2x":970},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/fbe1e81ca7074f0589a445e8c3c9de5e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/fbe1e81ca7074f0589a445e8c3c9de5e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":485,"real_height_2x":970}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Этот язык строится по тегам. Главный —&nbsp;<strong>html</strong>, в <strong>head</strong> обычно прописана метаинформация (заголовок, например), а нас сейчас интересует тег <strong>body</strong>, где лежит основная информация страницы.&nbsp;","type":"p","className":""},{"data":{"id":2867,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e54a4c3dec474747a6c1eae245cfc9db-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e54a4c3dec474747a6c1eae245cfc9db-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":534,"real_height_2x":1070},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e54a4c3dec474747a6c1eae245cfc9db-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e54a4c3dec474747a6c1eae245cfc9db-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":534,"real_height_2x":1070}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы посмотреть код конкретного элемента, нужно кликнуть именно на него и нажать «<strong>Посмотреть код</strong>» — тогда в панели разработчика подсветится нужный тег.","type":"p","className":""},{"data":{"id":2868,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f0371b0180904bf1976ae4161cfcbd97-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f0371b0180904bf1976ae4161cfcbd97-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":536,"real_height_2x":1073},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f0371b0180904bf1976ae4161cfcbd97-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f0371b0180904bf1976ae4161cfcbd97-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":536,"real_height_2x":1073}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"И наоборот, если двигаться по коду в панели справа, то слева, на самой странице, будет подсвечиваться сверстанный этим тегом элемент.","type":"p","className":""},{"data":"На страницах со списками одни и те же теги (название, оценка и так далее) повторяются от карточки к карточке. Поэтому нужно обнаружить и выписать эти конкретные теги. Но сначала вытащим весь код страницы, и здесь пригодится библиотека <strong>Requests</strong> —&nbsp;мы уже <a href=\"https://istories.media/workshops/2021/04/23/pishem-svoego-robota-na-python-urok-3/\" data-type=\"usual\" target=\"_blank\">рассказывали</a> о ней, советуем сначала прочитать тот урок и установить ее.","type":"p","className":""},{"data":"Открываем <strong>Jupyter</strong>, импортируем библиотеку с помощью <strong>import requests</strong>. Чтобы обратиться к сайту, создаем переменную <strong>url</strong> и присваиваем ей значение нужного сайта (у нас это ссылка на топ «КиноПоиска»).","type":"p","className":""},{"data":{"id":2869,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/713c8fd400e84982b7b50ace322cf427-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/713c8fd400e84982b7b50ace322cf427-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":492,"real_height_2x":984},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/713c8fd400e84982b7b50ace322cf427-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/713c8fd400e84982b7b50ace322cf427-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":492,"real_height_2x":984}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Отправим на сервер запрос с помощью команды <strong>get</strong>, на вход которой мы передаем переменную <strong>url</strong>. С помощью команды <strong>text</strong> посмотрим, что получилось.","type":"p","className":""},{"data":{"id":2870,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ded904a26e2649be8381713ab32d0db0-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ded904a26e2649be8381713ab32d0db0-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":405,"real_height_2x":810},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ded904a26e2649be8381713ab32d0db0-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ded904a26e2649be8381713ab32d0db0-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":405,"real_height_2x":810}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Как видите, код получился нечитаемым. Справиться с этим поможет другая библиотека, <strong>Beautifulsoup</strong>. Импортируем ее с помощью команды<strong> from bs4 import BeautifulSoup</strong>. Возможно, для этого понадобится сначала <a href=\"https://istories.media/workshops/2021/04/16/pishem-svoego-robota-na-python-urok-2/\" data-type=\"usual\" target=\"_blank\">установить</a> библиотеку через <strong>pip install</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2871,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f82cb161b288417cbe0c426bb9df8131-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f82cb161b288417cbe0c426bb9df8131-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":202,"real_height_2x":405},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f82cb161b288417cbe0c426bb9df8131-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f82cb161b288417cbe0c426bb9df8131-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":202,"real_height_2x":405}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы должны передать библиотеке ответ, полученный с помощью <strong>Requests</strong>. Создадим переменную <strong>soup</strong>, передадим <strong>r.text </strong>и укажем необходимый формат (в нашем случае <strong>lxml</strong>).","type":"p","className":""},{"data":{"id":2872,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ac7b57cab999401f87d4c3d71da74caf-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ac7b57cab999401f87d4c3d71da74caf-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":506,"real_height_2x":1012},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ac7b57cab999401f87d4c3d71da74caf-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ac7b57cab999401f87d4c3d71da74caf-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":506,"real_height_2x":1012}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Код упорядочен, теги идут один за одним — теперь мы можем вынимать из кода то, что нам нужно. Для этого вернемся в браузер, на страницу с данными. Как видно на скриншоте, подряд расположены несколько тегов <strong>div</strong> с классом <strong>desktop-rating-selection-file-item</strong> — это карточка каждого из фильмов в списке.","type":"p","className":""},{"data":{"id":2873,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c5d213263c0c411d9b6f05a0cf771376-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c5d213263c0c411d9b6f05a0cf771376-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":458,"real_height_2x":916},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/c5d213263c0c411d9b6f05a0cf771376-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/c5d213263c0c411d9b6f05a0cf771376-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":458,"real_height_2x":916}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Сначала вытащим данные только из первой карточки, а затем перепишем код так, чтобы он сработал на все фильмы со страницы. Скопируем название класса — для этого два раза кликните на него мышкой и нажмите <strong>Ctrl+C</strong> (<strong>Cmd+C</strong> для macOS). ","type":"p","className":""},{"data":"В <strong>Beautifulsoup</strong> есть команда <strong>find</strong> —&nbsp;укажем ей нужный тег (<strong>div</strong>) и через запятую класс (<strong>desktop-rating-selection-file-item</strong>). После <strong>class</strong> обязательно нужно поставить нижнее подчеркивание.","type":"p","className":""},{"data":{"id":2874,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/818aee665aa84fdda67c2419b53d92fd-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/818aee665aa84fdda67c2419b53d92fd-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":298,"real_height_2x":595},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/818aee665aa84fdda67c2419b53d92fd-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/818aee665aa84fdda67c2419b53d92fd-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":298,"real_height_2x":595}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Отобразился уже не весь код, а только нужный элемент, в котором видно название фильма. Вернемся на сайт, чтобы углубиться в карточку и посмотреть, как называются нужные нам детали. Кликнем на название фильма «Зеленая миля» и снова выберем «<strong>Посмотреть код</strong>».&nbsp;","type":"p","className":""},{"data":"Например, мы видим, что ссылка на фильм лежит в теге <strong>a</strong> и имеет собственный класс <strong>selection-film-item-meta__link</strong>. В теге <strong>a</strong>, в свою очередь, есть теги <strong>p</strong> с русским и оригинальным названиями фильмов. Эти три элемента мы и заберем.","type":"p","className":""},{"data":{"id":2875,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/73c7b2c7b0e948f69851536cd28f4f8c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/73c7b2c7b0e948f69851536cd28f4f8c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":453,"real_height_2x":906},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/73c7b2c7b0e948f69851536cd28f4f8c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/73c7b2c7b0e948f69851536cd28f4f8c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":453,"real_height_2x":906}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Дополним нашу первую команду: ставим точку, снова пишем <strong>find</strong>, указываем тег <strong>a</strong> и его класс.","type":"p","className":""},{"data":{"id":2876,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ea518b0ccb844f5fb6cac7c3423cab54-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ea518b0ccb844f5fb6cac7c3423cab54-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":124,"real_height_2x":248},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ea518b0ccb844f5fb6cac7c3423cab54-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ea518b0ccb844f5fb6cac7c3423cab54-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":124,"real_height_2x":248}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы сделать ссылку на фильм работающей, в начале нужно дописать к ней домен. Сама ссылка лежит внутри тега, поэтому <strong>find</strong> мы применить не сможем. Воспользуемся командой <strong>get</strong> и укажем нужный атрибут (в нашем случае <strong>href</strong>).","type":"p","className":""},{"data":{"id":2877,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/6bcce13ba7ae4da3b9b783d2c9d61974-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/6bcce13ba7ae4da3b9b783d2c9d61974-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":141,"real_height_2x":282},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/6bcce13ba7ae4da3b9b783d2c9d61974-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/6bcce13ba7ae4da3b9b783d2c9d61974-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":141,"real_height_2x":282}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Допишем в начало команды домен «КиноПоиска» и запустим еще раз — так мы получим готовую ссылку. Положим этот код в переменную <strong>link</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2878,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/fa30b72dd6a74dd79f3227c5b8a2d6dc-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/fa30b72dd6a74dd79f3227c5b8a2d6dc-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":118,"real_height_2x":236},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/fa30b72dd6a74dd79f3227c5b8a2d6dc-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/fa30b72dd6a74dd79f3227c5b8a2d6dc-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":118,"real_height_2x":236}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"По аналогии достанем русскоязычное и оригинальное названия. Возьмем тот же код, допишем новый <strong>find</strong>, укажем нужные тег и класс. Чтобы очистить результат от ненужных элементов кода, добавим в конце команду <strong>text</strong>. Эти переменные назовем <strong>russian_name</strong> и <strong>original_name</strong> соответственно.","type":"p","className":""},{"data":{"id":2893,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/125fd8b6ca594efb9df493cb86400ab0-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/125fd8b6ca594efb9df493cb86400ab0-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":198,"real_height_2x":395},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/125fd8b6ca594efb9df493cb86400ab0-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/125fd8b6ca594efb9df493cb86400ab0-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":198,"real_height_2x":395}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Еще мы можем достать из карточки страну производства и жанр — все будет работать точно так же, только класс будет не <strong>p</strong>, как у названий, а <strong>span</strong>. Страну положим в переменную <strong>country</strong>.","type":"p","className":""},{"data":"Однако в коде «КиноПоиска»&nbsp;страна и жанр имеют одинаковый класс <strong>selection-film-item-meta__meta-additional-item</strong> — а команда <strong>find</strong> находит только первое соответствие вашему запросу. Применим команду <strong>findAll</strong>, а все остальное оставим как раньше, чтобы получить список.&nbsp;","type":"p","className":""},{"data":{"id":2896,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9e9691e750484014a922f644c380b07c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9e9691e750484014a922f644c380b07c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":226,"real_height_2x":453},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9e9691e750484014a922f644c380b07c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9e9691e750484014a922f644c380b07c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":226,"real_height_2x":453}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы вытащить только жанр, добавим нумерацию в квадратных скобках (не забывайте, что в Python отсчет идет с <strong>0</strong>, поэтому нам нужен номер <strong>1</strong>) и команду <strong>text</strong>. Переменную назовем <strong>film_type</strong>.","type":"p","className":""},{"data":{"id":2897,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/23a968b5d4e248338f9d2b8815a6984a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/23a968b5d4e248338f9d2b8815a6984a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":100,"real_height_2x":199},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/23a968b5d4e248338f9d2b8815a6984a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/23a968b5d4e248338f9d2b8815a6984a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":100,"real_height_2x":199}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Основную информацию о фильме мы достали, но можем получить и кое-что еще —&nbsp;например, оценку. Проверим, как называется класс этого элемента на странице «КиноПоиска» с помощью уже известного метода «Посмотреть код». Как видите, нам повезло —&nbsp;класс имеет уникальное название, глубоко копать не придется.","type":"p","className":""},{"data":{"id":2898,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5198bf234b9640ce99441e449860bf52-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5198bf234b9640ce99441e449860bf52-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":287,"real_height_2x":574},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5198bf234b9640ce99441e449860bf52-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5198bf234b9640ce99441e449860bf52-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":287,"real_height_2x":574}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Скопируем ту часть изначальной команды <strong>find</strong>, где мы заходим в первый <strong>div</strong> карточки фильма и сразу укажем новый поиск по тегу <strong>span</strong> и классу <strong>rating__value rating__value_positive</strong> (и не забудем про <strong>text</strong>). Переменную назовем <strong>rate</strong>.","type":"p","className":""},{"data":{"id":2899,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f1ae3c3a7f974a63ad75dfaf9c9f2625-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f1ae3c3a7f974a63ad75dfaf9c9f2625-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":96,"real_height_2x":191},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f1ae3c3a7f974a63ad75dfaf9c9f2625-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f1ae3c3a7f974a63ad75dfaf9c9f2625-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":96,"real_height_2x":191}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы уже сделали почти всю работу, но пока что наш код работает только для первой карточки фильма в списке. Исправим это. Создадим переменную <strong>films</strong>, зададим новый поиск по самому первому <strong>div</strong>, но уже с командой <strong>findAll</strong>. И заодно посмотрим длину списка с помощью команды <strong>len</strong>. Их будет 50, потому что список топ-250 разбит на 5 страниц. Далее мы научим код ходить и по другим страницам.","type":"p","className":""},{"data":{"id":2900,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/17974662102c4366ad9a7626c0206621-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/17974662102c4366ad9a7626c0206621-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":126,"real_height_2x":253},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/17974662102c4366ad9a7626c0206621-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/17974662102c4366ad9a7626c0206621-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":126,"real_height_2x":253}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Напишем цикл для каждого <strong>film</strong> в списке <strong>films</strong>. Пока скопируем команду по поиску <strong>link</strong> и посмотрим, что там нужно поправить. Нам не нужен запрос к первому <strong>div</strong>, потому что до этого мы обратились к нему через <strong>findAll</strong> — заменим его на <strong>film</strong>. Повторим так с каждым элементом.","type":"p","className":""},{"data":{"id":2901,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/71e2318613024ff18c24886f144506fe-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/71e2318613024ff18c24886f144506fe-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":204,"real_height_2x":408},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/71e2318613024ff18c24886f144506fe-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/71e2318613024ff18c24886f144506fe-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":204,"real_height_2x":408}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Создадим переменную <strong>data</strong>, в который будем добавлять все переменные, которые запрашиваем.","type":"p","className":""},{"data":{"id":2902,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/31632ce734ff4166b804b087b337ad04-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/31632ce734ff4166b804b087b337ad04-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":280,"real_height_2x":559},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/31632ce734ff4166b804b087b337ad04-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/31632ce734ff4166b804b087b337ad04-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":280,"real_height_2x":559}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Запустим код и посмотрим, что отображается в <strong>data</strong>.","type":"p","className":""},{"data":{"id":2903,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d9eca3cde6824f52947516dae043e722-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d9eca3cde6824f52947516dae043e722-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":556,"real_height_2x":1112},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/d9eca3cde6824f52947516dae043e722-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/d9eca3cde6824f52947516dae043e722-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":556,"real_height_2x":1112}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Все ровно так, как нам было нужно. Осталось только разобраться, как собирать данные и со следующих страниц. Если мы перейдем на вторую страницу списка, то увидим, что ссылка в адресной строке браузера изменилась —&nbsp;там появилось <strong>page=2</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2904,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d0b71bea867d41c38fedaf03acb3a0bd-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d0b71bea867d41c38fedaf03acb3a0bd-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":338,"real_height_2x":676},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/d0b71bea867d41c38fedaf03acb3a0bd-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/d0b71bea867d41c38fedaf03acb3a0bd-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":338,"real_height_2x":676}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"То есть, нам нужно передать этот параметр в цикл. Создадим перед циклом переменную <strong>url</strong> и воспользуемся <a href=\"https://istories.media/workshops/2020/11/18/vvedenie-v-python-chast-3/\" data-type=\"usual\" target=\"_blank\">методом f-строк</a>, чтобы поместить внутрь фигурных скобок тот параметр, который нам нужен — номер страницы. Назовем параметр <strong>p</strong> и поместим его в цикл в промежутке от <strong>1</strong> до <strong>6</strong>. ","type":"p","className":""},{"data":"Переменную <strong>data</strong> при этом нужно вынести в начало кода, чтобы она не перезаписывалась с каждым новым циклом, а дополнялась. После этого скопируем код для запуска <strong>Requests</strong> и <strong>Beautifulsoup</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2908,"data":{"images":[{"credit":"Извините, на скрине ошибка: последнее значение в range должно быть 6, иначе скрипт пройдет только по четырем страницам","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/320ec112700a4c19b98a1cc80c2b88fa-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/320ec112700a4c19b98a1cc80c2b88fa-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":424,"real_height_2x":848},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/320ec112700a4c19b98a1cc80c2b88fa-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/320ec112700a4c19b98a1cc80c2b88fa-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":424,"real_height_2x":848}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Код готов к работе. Но еще мы советуем добавить временные промежутки между запросами, чтобы не перегружать сервер, к которому обращаемся. Вернемся в область, где ранее импортировали <strong>Beautifulsoup</strong>, и импортируем из библиотеки <strong>time</strong> функцию <strong>sleep</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2909,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ae380e115b7740ed95b343d45145c1b9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ae380e115b7740ed95b343d45145c1b9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":372,"real_height_2x":745},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ae380e115b7740ed95b343d45145c1b9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ae380e115b7740ed95b343d45145c1b9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":372,"real_height_2x":745}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В основной код допишем, чтобы между запросами проходило 3 секунды. Чтобы в реальном времени проверить работоспособность скрипта, добавим команду <strong>print</strong>.","type":"p","className":""},{"data":{"id":2910,"data":{"images":[{"credit":"Ошибка с позапрошлого скрина исправлена: последнее значение в range — 6, поэтому скрипт прошел по всем пяти страницам","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/744998daabd24b09955f0901d8211d33-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/744998daabd24b09955f0901d8211d33-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":594,"real_height_2x":1188},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/744998daabd24b09955f0901d8211d33-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/744998daabd24b09955f0901d8211d33-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":594,"real_height_2x":1188}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Все должно сработать. Если сейчас снова проверить длину нашего списка командой <strong>len(data)</strong>, там будет 250 — как и в топе «КиноПоиска». Теперь сохраним наши данные в таблицу. Снова вернемся в область импорта и добавим туда <a href=\"https://istories.media/workshops/2021/03/05/python-biblioteka-pandas-chast-1/\" data-type=\"usual\" target=\"_blank\">Pandas</a> и используем его для записи в <strong>csv</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2913,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8323eb8ef0d34ba58e8fcfc657dffb1e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8323eb8ef0d34ba58e8fcfc657dffb1e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":274,"real_height_2x":548},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8323eb8ef0d34ba58e8fcfc657dffb1e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/8323eb8ef0d34ba58e8fcfc657dffb1e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":274,"real_height_2x":548}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Введем названия для колонок —&nbsp;пусть они дублируют названия переменных, которые мы присвоили ранее (не забудьте поместить их в 'кавычки'). И после этого экспортируем наши данные.","type":"p","className":""},{"data":{"id":2914,"data":{"images":[{"credit":"Код для импорта данных в таблицу csv","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8b3dbd2f173c413687fb6d5c13d77d66-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8b3dbd2f173c413687fb6d5c13d77d66-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":124,"real_height_2x":247},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8b3dbd2f173c413687fb6d5c13d77d66-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/8b3dbd2f173c413687fb6d5c13d77d66-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":124,"real_height_2x":247}]},{"credit":"Итоговая таблица в csv","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/254299b4e8024a93bdc674bfd020167d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/254299b4e8024a93bdc674bfd020167d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":534,"real_height_2x":1069},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/254299b4e8024a93bdc674bfd020167d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/254299b4e8024a93bdc674bfd020167d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":534,"real_height_2x":1069}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Последнее, что мы разберем на этом уроке —&nbsp;как научить код не ломаться и продолжать работу, если у фильма не будет указано какого-то из параметров. Пропишем, например, исключение для рейтинга фильма (<strong>rate</strong>) — если его нет, будет стоять прочерк.","type":"p","className":""},{"data":{"id":2915,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1f45de83f2b544fe918ac9ada00fedde-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1f45de83f2b544fe918ac9ada00fedde-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":402,"real_height_2x":805},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1f45de83f2b544fe918ac9ada00fedde-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1f45de83f2b544fe918ac9ada00fedde-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":402,"real_height_2x":805}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"«КиноПоиск»&nbsp;поддался нашему скрипту без проблем, но бывают сайты, запросы с которых не хотят отдавать нам необходимую информацию. Как с этим справиться —&nbsp;расскажем в следующих уроках.","type":"p","className":""},{"data":"Если у вас что-то не получилось — пишите в наш <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">Telegram-чат</a>, постараемся подсказать.","type":"p","className":""}]},{"id":328,"header":"Пишем своего робота на Python. Урок 16","_path":"/workshops/2021/09/03/pishem-svoego-robota-na-python-urok-16/","lead":"Последний урок курса. Структурируем код и учимся обращаться к функциям как к библиотекам","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/af0afb2bf2c4407bbe0533b459e19a0e-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-09-03","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Вот мы и добрались до последнего урока по созданию робота-анализатора госконтрактов. Мы уже написали весь код, научились удаленно и по расписанию запускать скрипт, а сегодня разберемся, как лучше оформлять код, чтобы с ним было проще работать и он был понятен людям со стороны.\nСейчас наш проект это набор функций, которые собраны в одном файле. Так он выглядит, потому что мы последовательно разбирались с каждой функцией по отдельности. На самом деле структуру этого кода можно организовать более удобно.\n\nДавайте вынесем некоторые функции в отдельные файлы, чтобы к ним можно было обращаться через import как к библиотекам. Например, функцию, которая получала на вход словарь и находила его значение по ключу, сделаем отдельным файлом dict_key_finder.py. \n\n\nТакже создадим отдельный файл и для отправки письма — send_email.py. Мы немного перестроили код, там появились функции, которые называются по-другому, но суть осталась прежней. Теперь там есть функция def create_message, которая парсит датасет от «ГосЗатрат» и превращает его в письмо.\n\n\nДалее — функция def send_empty_email, которая отправляет пустое письмо, если за указанный период времени в указанном регионе не набралось госконтрактов, удовлетворяющих заданным параметрам. \n\n\nЕсли же всё в порядке, сработает функция def send_email_with_contracts, которая соберет контракты в письмо.\n\n\nДополнительная функция def error_message — чтобы вам пришло сообщение об ошибке, если скрипт сломается. \n\n\nСписок получателей тоже вынесем в отдельный файл email_reciepients.py. У нас там только один тестовый адрес, но их может быть столько, сколько вам необходимо.\n\n\nСоздадим следующий файл — get_contracts_from_clearspending.py, где мы будем обращаться к серверу «ГосЗатрат» и получать оттуда контракты. \n\n\nФайл clearspending_contract_parser.py будет парсить датасет и возвращать нам объект, который далее можно помещать в письмо.\n\n\nТеперь в файле main.py мы можем обращаться ко всем этим файлам как к библиотекам и импортировать оттуда нужные нам функции. \n\n\nИзменилась и структура главного файла — появилась функция def main и конструкция if __name__ == \"__main__\". \n\n\nТак код станет гораздо чище. Все переменные внутри def main будут локальными, а извне — глобальными. К тому же стало проще запускать тесты — мы можем импортировать код в виртуальное окружение и проверить на ошибки. \n\nРобот готов! Полный код мы выложили на GitHub, чтобы вы могли внимательнее изучить его. Если появятся вопросы — как всегда, пишите в наш чат в Telegram, постараемся ответить.","blocks":[{"data":"Вот мы и добрались до последнего урока по созданию робота-анализатора госконтрактов. Мы уже написали весь код, научились удаленно и по расписанию запускать скрипт, а сегодня разберемся, как лучше оформлять код, чтобы с ним было проще работать и он был понятен людям со стороны.","type":"p","className":""},{"data":{"id":2853,"data":{"url":"https://www.youtube.com/embed/gML34_Uvmfk","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=gML34_Uvmfk","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Сейчас наш проект это набор функций, которые собраны в одном файле. Так он выглядит, потому что мы последовательно разбирались с каждой функцией по отдельности. На самом деле структуру этого кода можно организовать более удобно.","type":"p","className":""},{"data":"Давайте вынесем некоторые функции в отдельные файлы, чтобы к ним можно было обращаться через <strong>import</strong> как к библиотекам. Например, функцию, которая получала на вход <a href=\"https://istories.media/workshops/2020/12/09/vvedenie-v-python-chast-6-slovari/\" data-type=\"usual\" target=\"_blank\">словарь</a> и находила его значение по ключу, сделаем отдельным файлом <strong>dict_key_finder.py</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2854,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1b3c8303af354255be3ab0a6f48df6f7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1b3c8303af354255be3ab0a6f48df6f7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":562,"real_height_2x":1124},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1b3c8303af354255be3ab0a6f48df6f7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1b3c8303af354255be3ab0a6f48df6f7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":562,"real_height_2x":1124}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Также создадим отдельный файл и для отправки письма — <strong>send_email.py</strong>. Мы немного перестроили код, там появились функции, которые называются по-другому, но суть осталась прежней. Теперь там есть функция <strong>def create_message</strong>, которая парсит датасет от «ГосЗатрат» и превращает его в письмо.","type":"p","className":""},{"data":{"id":2855,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3342f9361cf44e4da96dc9200e82257d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3342f9361cf44e4da96dc9200e82257d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":588,"real_height_2x":1176},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3342f9361cf44e4da96dc9200e82257d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3342f9361cf44e4da96dc9200e82257d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":588,"real_height_2x":1176}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Далее — функция <strong>def send_empty_email</strong>, которая отправляет пустое письмо, если за указанный период времени в указанном регионе не набралось госконтрактов, удовлетворяющих заданным параметрам.&nbsp;","type":"p","className":""},{"data":{"id":2856,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b130d397961041cf8e72e8dbf553fd49-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b130d397961041cf8e72e8dbf553fd49-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":515,"real_height_2x":1030},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b130d397961041cf8e72e8dbf553fd49-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b130d397961041cf8e72e8dbf553fd49-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":515,"real_height_2x":1030}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если же всё в порядке, сработает функция <strong>def send_email_with_contracts</strong>, которая соберет контракты в письмо.","type":"p","className":""},{"data":{"id":2857,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/cc4bfbfe3dc54a77af0b62d99bd0b807-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/cc4bfbfe3dc54a77af0b62d99bd0b807-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":560,"real_height_2x":1119},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/cc4bfbfe3dc54a77af0b62d99bd0b807-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/cc4bfbfe3dc54a77af0b62d99bd0b807-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":560,"real_height_2x":1119}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Дополнительная функция <strong>def error_message</strong> — чтобы вам пришло сообщение об ошибке, если скрипт <a href=\"https://istories.media/workshops/2021/06/05/pishem-svoego-robota-na-python-urok-7/\" data-type=\"usual\" target=\"_blank\">сломается</a>.&nbsp;","type":"p","className":""},{"data":{"id":2858,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/6a38c63b1f7a4a08ad5d59e8a5534b0d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/6a38c63b1f7a4a08ad5d59e8a5534b0d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":763,"real_height_2x":1526},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/6a38c63b1f7a4a08ad5d59e8a5534b0d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/6a38c63b1f7a4a08ad5d59e8a5534b0d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":763,"real_height_2x":1526}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Список получателей тоже вынесем в отдельный файл <strong>email_reciepients.py</strong>. У нас там только один тестовый адрес, но их может быть столько, сколько вам необходимо.","type":"p","className":""},{"data":{"id":2859,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/fdc0334b0c0149c68d8a9786acb9d87c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/fdc0334b0c0149c68d8a9786acb9d87c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":324,"real_height_2x":648},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/fdc0334b0c0149c68d8a9786acb9d87c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/fdc0334b0c0149c68d8a9786acb9d87c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":324,"real_height_2x":648}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Создадим следующий файл —&nbsp;<strong>get_contracts_from_clearspending.py</strong>, где мы будем обращаться к серверу «ГосЗатрат» и получать оттуда контракты.&nbsp;","type":"p","className":""},{"data":{"id":2860,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/786369046b814715a38e96d6ee402f71-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/786369046b814715a38e96d6ee402f71-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":572,"real_height_2x":1143},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/786369046b814715a38e96d6ee402f71-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/786369046b814715a38e96d6ee402f71-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":572,"real_height_2x":1143}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Файл <strong>clearspending_contract_parser.py</strong> будет парсить датасет и возвращать нам объект, который далее можно помещать в письмо.","type":"p","className":""},{"data":{"id":2861,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/384ffbf981ca4f248b198baf95ea1af3-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/384ffbf981ca4f248b198baf95ea1af3-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":635,"real_height_2x":1270},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/384ffbf981ca4f248b198baf95ea1af3-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/384ffbf981ca4f248b198baf95ea1af3-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":635,"real_height_2x":1270}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь в файле <strong>main.py</strong> мы можем обращаться ко всем этим файлам как к библиотекам и импортировать оттуда нужные нам функции.&nbsp;","type":"p","className":""},{"data":{"id":2862,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e409a30d562e49789f3024ab44e35965-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e409a30d562e49789f3024ab44e35965-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":372,"real_height_2x":744},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e409a30d562e49789f3024ab44e35965-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e409a30d562e49789f3024ab44e35965-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":372,"real_height_2x":744}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Изменилась и структура главного файла — появилась функция <strong>def main</strong> и конструкция <strong>if __name__ == \"__main__\"</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2863,"data":{"images":[{"credit":"def main","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e0a035b5fc344683a0ec7da0bd47558b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e0a035b5fc344683a0ec7da0bd47558b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":589,"real_height_2x":1178},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e0a035b5fc344683a0ec7da0bd47558b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e0a035b5fc344683a0ec7da0bd47558b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":589,"real_height_2x":1178}]},{"credit":"if __name__ == \"__main__\"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/65861bef37ce4937b738feadcc1251c5-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/65861bef37ce4937b738feadcc1251c5-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":488,"real_height_2x":976},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/65861bef37ce4937b738feadcc1251c5-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/65861bef37ce4937b738feadcc1251c5-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":488,"real_height_2x":976}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Так код станет гораздо чище. Все переменные внутри <strong>def main</strong> будут локальными, а извне — глобальными. К тому же стало проще запускать тесты — мы можем импортировать код в <a href=\"https://istories.media/workshops/2021/04/16/pishem-svoego-robota-na-python-urok-2/\" data-type=\"usual\" target=\"_blank\">виртуальное окружение</a> и проверить на <a href=\"https://istories.media/workshops/2021/06/11/pishem-svoego-robota-na-python-urok-/\" data-type=\"usual\" target=\"_blank\">ошибки</a>.&nbsp;","type":"p","className":""},{"data":"Робот готов! Полный код мы <a href=\"https://github.com/iStoriesMedia/robot\" data-type=\"usual\" target=\"_blank\">выложили на GitHub</a>, чтобы вы могли внимательнее изучить его. Если появятся вопросы — как всегда, пишите в наш <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">чат</a> в Telegram, постараемся ответить. ","type":"p","className":""}]},{"id":317,"header":"Пишем своего робота на Python. Урок 15","_path":"/workshops/2021/08/27/pishem-svoego-robota-na-python-urok-15/","lead":"Запускаем автоматический скрипт на виртуальной машине с удаленного сервера","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/ab28400305ce44f2a25f48b3ce5958cb-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-08-27","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"В прошлых выпусках мы узнали, как запускать скрипты автоматически по расписанию и как создать свою виртуальную машину. Сегодня мы объединим эти знания и удаленно запустим скрипт на виртуальной машине, чтобы его работа не была привязана к вашему компьютеру.\n\n\nДля начала запустим виртуальную машину, если она была выключена. Когда слева от названия появится зеленая галочка — машина готова к работе.\nЕсть несколько обязательных настроек, что всё работало как надо. Проверьте, чтобы у пунктов «Allow HTTP traffic» и «Allow HTTPS traffic» стояли галочки, и чтобы ко всем API «облака» был предоставлен полный доступ.\nНажмем на «SSH» в столбике «Connect», чтобы подключиться к виртуальной машине. \nПосле этого откроется консоль, по своим свойствам идентичная терминалу — она распознает ваш аккаунт. Теперь нужно загрузить файлы нашего проекта на сервер. \n\nСоздадим директорию командой mkdir <название> (у нас оно будет new_robot). Проверить, что она появилась в корневом каталоге, можно командой ls.\nЧтобы загрузить файл, нажмите на шестеренку в правом верхнем углу и далее на «Upload file». \nСуществует другой способ — с помощью специальных команд Google Cloud. Подробнее о них можно узнать в официальном гайде. Этот способ пригодится нам для загрузки, например, файла .env, куда мы безопасно сохраняли логин и пароль — через «Upload file» он не загрузится и даже не отобразится в списке доступных файлов.\n\nКоманда, которая нам нужна, выглядит так: \ngcloud compute scp ~/robot/.env ~/.env instance-1:~\n\n«~/robot/.env» — расположение файла на вашем компьютере.\n«~/.env» — будущее название файла на вашей виртуальной машине.\n«instance-1:~» — название виртуальной машины и будущее расположение файла (в данном случае — корневая директория).\nПосле запуска команды у нас попросят уточнить временную зону, нажимаем Y. Далее с помощью cat .env можем проверить правильность данных в загруженном файле.\nПосле загрузки всех файлов на сервер нужно переместить их в ранее созданную папку. Для этого введем mv <название файла> <название папки> для каждого файла.\nРазберемся, как правильно написать bash-файл для виртуальной машины, чтобы скрипт запускался автоматически. Вернемся в окно Python и создадим файл runVM.sh. Начало у него стандартное: #!/bin/bash. Далее указываем директорию, в которой лежит наш проект. Следующей строкой запускаем главный файл (на нашем сервере по умолчанию установлен python3).\nЭтот файл тоже загрузим на сервер и переместим в папку проекта. Не забудьте с помощью команды ls проверить, что в папке находятся все нужные файлы.\nЗапускаем bash-файл как обычно: командой bash runVM.sh. Если необходимо настроить crontab, чтобы изменить время и частоту запуска скрипта, сделать это можно точно так же, как мы делали в уроке #13.\n\nТеперь можете не волноваться, включен ваш компьютер или выключен — скрипт будет запускаться на удаленном сервере до тех пор, пока вы не выключите виртуальную машину. \n\nЕсли у вас что-то не получилось — пишите в наш Telegram-чат, постараемся подсказать.","blocks":[{"data":"В прошлых выпусках мы узнали, как запускать скрипты автоматически по расписанию и как создать свою виртуальную машину. Сегодня мы объединим эти знания и удаленно запустим скрипт на виртуальной машине, чтобы его работа не была привязана к вашему компьютеру.","type":"p","className":""},{"data":{"id":2802,"data":{"url":"https://www.youtube.com/embed/JyewZDaeCEc","text":"Съемка и монтаж: Глеб Лиманский","caption":"","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=JyewZDaeCEc","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Для начала запустим виртуальную машину, если она была выключена. Когда слева от названия появится зеленая галочка —&nbsp;машина готова к работе.","type":"p","className":""},{"data":{"id":2797,"data":{"images":[{"credit":"Кликайте на название виртуальной машины","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/777b027c62c84e80a5bcb809377daed0-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/777b027c62c84e80a5bcb809377daed0-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":416,"real_height_2x":834},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/777b027c62c84e80a5bcb809377daed0-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/777b027c62c84e80a5bcb809377daed0-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":416,"real_height_2x":834}]},{"credit":"Кликайте на треугольник, чтобы запустить ее","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/19be3bf452f24ac091efb9726cd43aec-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/19be3bf452f24ac091efb9726cd43aec-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":351,"real_height_2x":702},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/19be3bf452f24ac091efb9726cd43aec-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/19be3bf452f24ac091efb9726cd43aec-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":351,"real_height_2x":702}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Есть несколько обязательных настроек, что всё работало как надо. Проверьте, чтобы у пунктов «<strong>Allow HTTP traffic</strong>» и «<strong>Allow HTTPS traffic</strong>» стояли галочки, и чтобы ко всем API&nbsp;«облака» был предоставлен полный доступ.","type":"p","className":""},{"data":{"id":2798,"data":{"images":[{"credit":"Разрешена передача трафика по протоколам HTTP и HTTPS","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5df3e5265e174626813249a0b0c92a8f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5df3e5265e174626813249a0b0c92a8f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":831,"real_height_2x":1662},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5df3e5265e174626813249a0b0c92a8f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5df3e5265e174626813249a0b0c92a8f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":831,"real_height_2x":1662}]},{"credit":"Разрешен полный доступ к API Google Cloud","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a27975b8c2e34a72b75eb64e601dcbff-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a27975b8c2e34a72b75eb64e601dcbff-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":658,"real_height_2x":1316},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a27975b8c2e34a72b75eb64e601dcbff-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a27975b8c2e34a72b75eb64e601dcbff-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":658,"real_height_2x":1316}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Нажмем на «<strong>SSH</strong>» в столбике «<strong>Connect</strong>», чтобы подключиться к виртуальной машине.&nbsp;","type":"p","className":""},{"data":{"id":2799,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f8f76f4b87fc4a42b39856295ed4fe04-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f8f76f4b87fc4a42b39856295ed4fe04-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":421,"real_height_2x":842},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f8f76f4b87fc4a42b39856295ed4fe04-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f8f76f4b87fc4a42b39856295ed4fe04-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":421,"real_height_2x":842}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"После этого откроется консоль, по своим свойствам идентичная терминалу — она распознает ваш аккаунт. Теперь нужно загрузить файлы нашего проекта на сервер.&nbsp;","type":"p","className":""},{"data":"Создадим директорию командой <strong>mkdir &lt;название&gt;</strong> (у нас оно будет <strong>new_robot</strong>). Проверить, что она появилась в корневом каталоге, можно командой <strong>ls</strong>.","type":"p","className":""},{"data":{"id":2800,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f2984cb77a7b4e0b9f58de828e23240e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f2984cb77a7b4e0b9f58de828e23240e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":553,"real_height_2x":1106},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f2984cb77a7b4e0b9f58de828e23240e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f2984cb77a7b4e0b9f58de828e23240e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":553,"real_height_2x":1106}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы загрузить файл, нажмите на шестеренку в правом верхнем углу и далее на «<strong>Upload file</strong>».&nbsp;","type":"p","className":""},{"data":{"id":2801,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2a045d74782b42f1a022bff1e7e60ffb-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2a045d74782b42f1a022bff1e7e60ffb-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":402,"real_height_2x":805},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2a045d74782b42f1a022bff1e7e60ffb-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/2a045d74782b42f1a022bff1e7e60ffb-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":402,"real_height_2x":805}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Существует другой способ — с помощью специальных команд Google Cloud. Подробнее о них можно узнать в <a href=\"https://cloud.google.com/compute/docs/instances/transfer-files\" data-type=\"usual\" target=\"_blank\">официальном гайде</a>. Этот способ пригодится нам для загрузки, например, файла <strong>.env</strong>, куда мы <a href=\"https://istories.media/workshops/2021/07/27/pishem-svoego-robota-na-python-urok-12/\" data-type=\"usual\" target=\"_blank\">безопасно сохраняли логин и пароль</a> —&nbsp;через «<strong>Upload file</strong>» он не загрузится и даже не отобразится в списке доступных файлов.","type":"p","className":""},{"data":"Команда, которая нам нужна, выглядит так: ","type":"p","className":""},{"data":"<strong>gcloud compute scp ~/robot/.env ~/.env instance-1:~</strong>","type":"p","className":""},{"data":"«<strong>~/robot/.env</strong>» —&nbsp;<em>расположение файла на вашем компьютере.</em>","type":"p","className":""},{"data":"«<strong>~/.env</strong>» —&nbsp;<em>будущее название файла на вашей виртуальной машине.</em>","type":"p","className":""},{"data":"«<strong>instance-1:~</strong>» — <em>название виртуальной машины и будущее расположение файла (в данном случае —&nbsp;корневая директория).</em>","type":"p","className":""},{"data":{"id":2803,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/433b910782794a8abaed31a3a37b6892-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/433b910782794a8abaed31a3a37b6892-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":168,"real_height_2x":336},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/433b910782794a8abaed31a3a37b6892-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/433b910782794a8abaed31a3a37b6892-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":168,"real_height_2x":336}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"После запуска команды у нас попросят уточнить временную зону, нажимаем <strong>Y</strong>. Далее с помощью <strong>cat .env</strong> можем проверить правильность данных в загруженном файле.","type":"p","className":""},{"data":{"id":2804,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d477040fefe8476ca99793eb5ac41983-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d477040fefe8476ca99793eb5ac41983-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":378,"real_height_2x":756},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/d477040fefe8476ca99793eb5ac41983-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/d477040fefe8476ca99793eb5ac41983-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":378,"real_height_2x":756}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"После загрузки всех файлов на сервер нужно переместить их в ранее созданную папку. Для этого введем <strong>mv &lt;название файла&gt; &lt;название папки&gt;</strong> для каждого файла.","type":"p","className":""},{"data":{"id":2805,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ac64391158e54200958cc5f78790e550-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ac64391158e54200958cc5f78790e550-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":696,"real_height_2x":1393},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ac64391158e54200958cc5f78790e550-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ac64391158e54200958cc5f78790e550-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":696,"real_height_2x":1393}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Разберемся, как правильно написать <a href=\"https://istories.media/workshops/2021/08/06/pishem-svoego-robota-na-python-urok-13/\" data-type=\"usual\" target=\"_blank\">bash-файл</a> для виртуальной машины, чтобы скрипт запускался автоматически. Вернемся в окно Python и создадим файл <strong>runVM.sh</strong>. Начало у него стандартное: <strong>#!/bin/bash</strong>. Далее указываем директорию, в которой лежит наш проект. Следующей строкой запускаем главный файл (на нашем сервере по умолчанию установлен <strong>python3</strong>).","type":"p","className":""},{"data":{"id":2806,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d55c90a5099d4c1f96c60f88f2014c5a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d55c90a5099d4c1f96c60f88f2014c5a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":361,"real_height_2x":722},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/d55c90a5099d4c1f96c60f88f2014c5a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/d55c90a5099d4c1f96c60f88f2014c5a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":361,"real_height_2x":722}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Этот файл тоже загрузим на сервер и переместим в папку проекта. Не забудьте с помощью команды <strong>ls</strong> проверить, что в папке находятся все нужные файлы.","type":"p","className":""},{"data":{"id":2807,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e2bab748f81f4f5fae50e449679260cc-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e2bab748f81f4f5fae50e449679260cc-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":226,"real_height_2x":452},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e2bab748f81f4f5fae50e449679260cc-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e2bab748f81f4f5fae50e449679260cc-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":226,"real_height_2x":452}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Запускаем bash-файл как обычно: командой<strong> bash runVM.sh</strong>. Если необходимо настроить <strong>crontab</strong>, чтобы изменить время и частоту запуска скрипта, сделать это можно точно так же, как мы делали в <a href=\"https://istories.media/workshops/2021/08/06/pishem-svoego-robota-na-python-urok-13/\" data-type=\"usual\" target=\"_blank\">уроке #13</a>.","type":"p","className":""},{"data":"Теперь можете не волноваться, включен ваш компьютер или выключен —&nbsp;скрипт будет запускаться на удаленном сервере до тех пор, пока вы не выключите виртуальную машину.&nbsp;","type":"p","className":""},{"data":"Если у вас что-то не получилось —&nbsp;пишите в наш <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">Telegram-чат</a>, постараемся подсказать.","type":"p","className":""}]},{"id":306,"header":"Пишем своего робота на Python. Урок 14","_path":"/workshops/2021/08/13/pishem-svoego-robota-na-python-urok-14/","lead":"Учимся настраивать и запускать виртуальную машину с помощью Google Cloud Platform","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/ae4d8d97815a4ac3a1303d7b72d40889-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-08-13","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Сегодня мы будем разбираться, как настроить удаленный сервер с помощью Google. \nЛогинимся в Google-почту и заходим на console.cloud.google.com — здесь мы будем создавать виртуальную машину для нашего робота по отбору госконтрактов.\n\nСлева сверху будет уведомление «Your free trial is waiting...» — Google дает нам аванс в $300, чтобы сперва потестировать его продукт бесплатно. Чтобы воспользоваться предложением, нажмите «Activate» в правой верхней части экрана.\n\n\nДалее нужно будет заполнить несколько полей: страна, телефон, адрес и данные банковской карты. Не переживайте, с вас ничего не спишут, если вы потом отмените подписку до окончания пробного периода. Когда все введёте, нажмите «Start My Free Trial». Появится небольшой опрос — его можно пропустить.\n\nТеперь нужно создать проект, в котором вы будете работать. На скрине видно название нашей корпоративной почты «istories.media» справа от логотипа, у вас там скорее всего будет написано «My First Project» — нажмите на него, а затем — на «New Project».\n\n\nНазовите его как вам удобно и нажмите «Create». Перейдем к созданию виртуальной машины: в левом меню нам нужна вкладка «Compute Engine», а в ней — пункт «VM Instances». \n\n\nВ появившемся окне выберите только что созданный проект, нажмите «Continue», а в следующем окне — на «Enable». Теперь в верхней строке нажмите «Create Instance». Пропишем параметры непосредственно виртуальной машины.\n\n\nName: можно записать как вам удобно. Мы оставим «instance-1».\nRegion и Zone: выберите свою временную зону. Мы выберем «europe-central2».\nMachine type: можно выбрать технические характеристики сервера. Мы оставим изначальный вариант.\nBoot disk → Change: можно выбрать операционную систему (Operating system) и ее версию (Version). Мы оставим изначальную Debian (Linux).\n\n\nПосле этого можно нажать «Create». Виртуальная машина появится в списке и начнет загружаться. Если захотите что-то поменять в настройках — нажмите на ее название, а затем на «Edit».\n\n\nСейчас виртуальная машина работает по протоколу SSH. Если бы мы выбрали операционную систему Windows, можно было бы выбрать вариант «Open in browser window», и она бы работала внутри вкладки браузера как удаленный рабочий стол. \n\n\nС этой машиной уже можно работать дальше, загружать на нее скрипты и запускать их удаленно, но этим мы займемся в следующий раз. Если что-то не получилось, напишите нам в Telegram-чат — постараемся помочь.","blocks":[{"data":"Сегодня мы будем разбираться, как настроить удаленный сервер с помощью Google. ","type":"p","className":""},{"data":{"id":2810,"data":{"url":"https://www.youtube.com/embed/E7lhxMmmSWo","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=E7lhxMmmSWo","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Логинимся в Google-почту и заходим на <a href=\"https://console.cloud.google.com/\" data-type=\"usual\" target=\"_blank\">console.cloud.google.com</a> — здесь мы будем создавать виртуальную машину для нашего робота по отбору госконтрактов.","type":"p","className":""},{"data":"Слева сверху будет уведомление «Your free trial is waiting...» — Google дает нам аванс в $300, чтобы сперва потестировать его продукт бесплатно. Чтобы воспользоваться предложением, нажмите «<strong>Activate</strong>» в правой верхней части экрана.","type":"p","className":""},{"data":{"id":2763,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e68c3c7dd9b543008cc4491a2c3c05cc-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e68c3c7dd9b543008cc4491a2c3c05cc-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":317,"real_height_2x":634},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e68c3c7dd9b543008cc4491a2c3c05cc-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e68c3c7dd9b543008cc4491a2c3c05cc-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":317,"real_height_2x":634}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Далее нужно будет заполнить несколько полей: страна, телефон, адрес и данные банковской карты. Не переживайте, с вас ничего не спишут, если вы потом отмените подписку до окончания пробного периода. Когда все введёте, нажмите «<strong>Start My Free Trial</strong>». Появится небольшой опрос — его можно пропустить.","type":"p","className":""},{"data":"Теперь нужно создать проект, в котором вы будете работать. На скрине видно название нашей корпоративной почты «istories.media» справа от логотипа, у вас там скорее всего будет написано «<strong>My First Project</strong>» —&nbsp;нажмите на него, а затем — на «<strong>New Project</strong>».","type":"p","className":""},{"data":{"id":2764,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9a2fb477a9224c54bd84aec9a735c61b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9a2fb477a9224c54bd84aec9a735c61b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":363,"real_height_2x":726},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9a2fb477a9224c54bd84aec9a735c61b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9a2fb477a9224c54bd84aec9a735c61b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":363,"real_height_2x":726}]},{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/63742257dad34a1b81deb8431017ebdb-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/63742257dad34a1b81deb8431017ebdb-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":455,"real_height_2x":910},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/63742257dad34a1b81deb8431017ebdb-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/63742257dad34a1b81deb8431017ebdb-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":455,"real_height_2x":910}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Назовите его как вам удобно и нажмите «<strong>Create</strong>». Перейдем к созданию виртуальной машины: в левом меню нам нужна вкладка «<strong>Compute Engine</strong>», а в ней —&nbsp;пункт «<strong>VM Instances</strong>».&nbsp;","type":"p","className":""},{"data":{"id":2765,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/dcc70439c00e450194fd2bf0c0c62f4f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/dcc70439c00e450194fd2bf0c0c62f4f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":674,"real_height_2x":1349},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/dcc70439c00e450194fd2bf0c0c62f4f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/dcc70439c00e450194fd2bf0c0c62f4f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":674,"real_height_2x":1349}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В появившемся окне выберите только что созданный проект, нажмите «<strong>Continue</strong>», а в следующем окне —&nbsp;на «<strong>Enable</strong>». Теперь в верхней строке нажмите «<strong>Create Instance</strong>». Пропишем параметры непосредственно виртуальной машины.","type":"p","className":""},{"data":{"id":2766,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d5150f12d10b4b71903c432359b663f4-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d5150f12d10b4b71903c432359b663f4-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":264,"real_height_2x":530},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/d5150f12d10b4b71903c432359b663f4-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/d5150f12d10b4b71903c432359b663f4-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":264,"real_height_2x":530}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"<strong>Name</strong>: можно записать как вам удобно. <em>Мы оставим «instance-1».</em>","type":"p","className":""},{"data":"<strong>Region</strong> и <strong>Zone</strong>: выберите свою временную зону. <em>Мы выберем «europe-central2».</em>","type":"p","className":""},{"data":"<strong>Machine type</strong>: можно выбрать технические характеристики сервера. <em>Мы оставим изначальный вариант.</em>","type":"p","className":""},{"data":"<strong>Boot disk</strong> → <strong>Change</strong>: можно выбрать операционную систему (Operating system) и ее версию (Version). <em>Мы оставим изначальную Debian (Linux).</em>","type":"p","className":""},{"data":{"id":2767,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1f6b06e75b34466a91ab40c693aca795-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1f6b06e75b34466a91ab40c693aca795-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":668,"real_height_2x":1338},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1f6b06e75b34466a91ab40c693aca795-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1f6b06e75b34466a91ab40c693aca795-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":668,"real_height_2x":1338}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"После этого можно нажать «<strong>Create</strong>». Виртуальная машина появится в списке и начнет загружаться. Если захотите что-то поменять в настройках — нажмите на ее название, а затем на «<strong>Edit</strong>».","type":"p","className":""},{"data":{"id":2768,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/33fe3542b5f848668b135a1a51cbb97e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/33fe3542b5f848668b135a1a51cbb97e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":433,"real_height_2x":866},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/33fe3542b5f848668b135a1a51cbb97e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/33fe3542b5f848668b135a1a51cbb97e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":433,"real_height_2x":866}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Сейчас виртуальная машина работает по протоколу SSH. Если бы мы выбрали операционную систему Windows, можно было бы выбрать вариант «<strong>Open in browser window</strong>», и она бы работала внутри вкладки браузера как удаленный рабочий стол.&nbsp;","type":"p","className":""},{"data":{"id":2769,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9f3b6892338c4f4bbb421af273f417dc-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9f3b6892338c4f4bbb421af273f417dc-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":571,"real_height_2x":1142},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9f3b6892338c4f4bbb421af273f417dc-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9f3b6892338c4f4bbb421af273f417dc-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":571,"real_height_2x":1142}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"С этой машиной уже можно работать дальше, загружать на нее скрипты и запускать их удаленно, но этим мы займемся в следующий раз. Если что-то не получилось, напишите нам в <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">Telegram-чат</a> —&nbsp;постараемся помочь.","type":"p","className":""}]},{"id":301,"header":"Пишем своего робота на Python. Урок 13","_path":"/workshops/2021/08/06/pishem-svoego-robota-na-python-urok-13/","lead":"Учимся запускать скрипт на Python в нужное нам время автоматически с помощью bash и crontab.","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/8873458a5d904f52bc99ba2ae7738ef6-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-08-06","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Продолжаем писать робота-анализатора госконтрактов. Сегодня мы разберемся, как научить скрипт запускаться самостоятельно, без вашего участия — вы будете указывать только нужное время.\nНам понадобятся bash и crontab, начнем с первого. У bash есть определенный язык, который мы можем использовать в терминале. Сперва нужно создать файл, с которым bash сможет взаимодействовать, то есть, запускать его и исполнять его команды.  \n\nОткроем проект и создадим новый файл runscript.sh. Он всегда должен начинаться со строчки #!/bin/bash. \n\nПосле этого можем прописать команду к исполнению, она будет работать, как и любая из предыдущих наших команд в терминале: напишем python3 и название файла, который нужно запустить. После этого в терминале пишем команду bash и название нашего скрипта.\n\n\nКогда команда выполнилась, на вашу почту должно прийти письмо с госконтрактами. Еще нужно активировать среду, в которой мы работали, когда писали наш проект. Добавим в скрипт еще одну строчку с командой source и ссылкой — ее можно увидеть, когда вы запускаете виртуальное окружение.\n\n\nТо, что мы делали сейчас — это все-таки ручная работа. Разберемся, как ее автоматизировать — для этого пригодится crontab. Возвращаемся в терминал и с помощью команды crontab -l проверяем, есть ли какие-то уже запущенные кронтабы. В нашем случае их быть не должно.\n\n\nЧтобы создать кронтаб, вводим crontab -e и попадаем в программу vi, где можем его написать. В этом нам поможет сайт crontab guru. С помощью звездочек и цифр мы можем указать, как часто хотим запускать выполнение скрипта. Пять звездочек означают, что скрипт будет исполняться каждую минуту. \n\n\nЕсли, например, мы укажем в минутах 0, а в часах 21, то код будет выполняться каждый день в 9 вечера. \n\n\nДля примера попробуем запускать скрипт каждую минуту. Чтобы начать писать что-то в vi, нужно сначала нажать букву i. Теперь пропишем параметры для crontab (в нашем случае * * * * *) и в конце добавим bash runscript.sh. Чтобы закончить редактуру файла vi, нажимаем клавишу Esc и пишем :wq. \n\n\nПроверим, появился ли он в списке уже известной нам командой crontab -l. \n\n\nЧтобы следить за рассылками, в терминале используем команду mail. Она покажет, приходили ли вам письма и сколько.\n\n\nТеперь пора остановить скрипт. Для этого пропишем crontab -r. Перепроверить его можно той же командой crontab -l. \n\nС помощью crontab можно запускать не только скрипты на Python, но и какие-то другие процессы — но для этого компьютер должен быть включен. В следующий раз разберемся, как делать все то же самое, но на удаленном сервере, чтобы работа скрипта не была привязана к вашему компьютеру. \n\nЕсли у вас появились вопросы, вы можете задать их в нашем Telegram-чате.","blocks":[{"data":"Продолжаем писать робота-анализатора госконтрактов. Сегодня мы разберемся, как научить скрипт запускаться самостоятельно, без вашего участия —&nbsp;вы будете указывать только нужное время.","type":"p","className":""},{"data":{"id":2809,"data":{"url":"https://www.youtube.com/embed/P3bfC9lHuis","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=P3bfC9lHuis","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Нам понадобятся <strong>bash</strong> и <strong>crontab</strong>, начнем с первого. У <strong>bash</strong> есть определенный язык, который мы можем использовать в терминале. Сперва нужно создать файл, с которым <strong>bash</strong> сможет взаимодействовать, то есть, запускать его и исполнять его команды.&nbsp;&nbsp;","type":"p","className":""},{"data":"Откроем проект и создадим новый файл <strong>runscript.sh</strong>. Он всегда должен начинаться со строчки<strong> #!/bin/bash</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2770,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ddba04bf3b0e461891e7ac1f058f7748-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ddba04bf3b0e461891e7ac1f058f7748-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":398,"real_height_2x":796},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ddba04bf3b0e461891e7ac1f058f7748-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ddba04bf3b0e461891e7ac1f058f7748-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":398,"real_height_2x":796}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"После этого можем прописать команду к исполнению, она будет работать, как и любая из предыдущих наших команд в терминале: напишем <strong>python3</strong> и название файла, который нужно запустить. После этого в терминале пишем команду <strong>bash</strong> и название нашего скрипта.","type":"p","className":""},{"data":{"id":2771,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/969e89dafc324709899d531ff0dcfa0e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/969e89dafc324709899d531ff0dcfa0e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":408,"real_height_2x":816},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/969e89dafc324709899d531ff0dcfa0e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/969e89dafc324709899d531ff0dcfa0e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":408,"real_height_2x":816}]},{"caption":"Так как скрипт лежит в корневой директории, путь мы не прописываем, только название","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5ad9084d9dce46dea57ca5b30cfbacb9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5ad9084d9dce46dea57ca5b30cfbacb9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":466,"real_height_2x":932},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5ad9084d9dce46dea57ca5b30cfbacb9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5ad9084d9dce46dea57ca5b30cfbacb9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":466,"real_height_2x":932}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Когда команда выполнилась, на вашу почту должно прийти письмо с госконтрактами. Еще нужно активировать среду, в которой мы работали, когда писали наш проект. Добавим в скрипт еще одну строчку с командой <strong>source</strong> и ссылкой — ее можно увидеть, когда вы запускаете виртуальное окружение.","type":"p","className":""},{"data":{"id":2772,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7bb997ac1b4c4d219d59c777a3f7d066-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7bb997ac1b4c4d219d59c777a3f7d066-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":287,"real_height_2x":574},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7bb997ac1b4c4d219d59c777a3f7d066-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7bb997ac1b4c4d219d59c777a3f7d066-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":287,"real_height_2x":574}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"То, что мы делали сейчас —&nbsp;это все-таки ручная работа. Разберемся, как ее автоматизировать — для этого пригодится <strong>crontab</strong>. Возвращаемся в терминал и с помощью команды<strong> crontab -l </strong>проверяем, есть ли какие-то уже запущенные кронтабы. В нашем случае их быть не должно.","type":"p","className":""},{"data":{"id":2727,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7d7a8b2406ed44638f9c4ea07412b778-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7d7a8b2406ed44638f9c4ea07412b778-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":302,"real_height_2x":604},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7d7a8b2406ed44638f9c4ea07412b778-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7d7a8b2406ed44638f9c4ea07412b778-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":302,"real_height_2x":604}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы создать кронтаб, вводим <strong>crontab -e</strong> и попадаем в программу <strong>vi</strong>, где можем его написать. В этом нам поможет сайт <a href=\"https://crontab.guru/\" data-type=\"usual\" target=\"_blank\">crontab guru</a>. С помощью звездочек и цифр мы можем указать, как часто хотим запускать выполнение скрипта. Пять звездочек означают, что скрипт будет исполняться каждую минуту.&nbsp;","type":"p","className":""},{"data":{"id":2728,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/36aa058c6f2e4912bfb749dddde89a75-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/36aa058c6f2e4912bfb749dddde89a75-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":498,"real_height_2x":998},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/36aa058c6f2e4912bfb749dddde89a75-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/36aa058c6f2e4912bfb749dddde89a75-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":498,"real_height_2x":998}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если, например, мы укажем в минутах 0, а в часах 21, то код будет выполняться каждый день в 9 вечера. ","type":"p","className":""},{"data":{"id":2729,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/90bbd0baa1ce4f4a8ec6df9e1d61000e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/90bbd0baa1ce4f4a8ec6df9e1d61000e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":482,"real_height_2x":964},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/90bbd0baa1ce4f4a8ec6df9e1d61000e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/90bbd0baa1ce4f4a8ec6df9e1d61000e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":482,"real_height_2x":964}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Для примера попробуем запускать скрипт каждую минуту. Чтобы начать писать что-то в <strong>vi</strong>, нужно сначала нажать букву i. Теперь пропишем параметры для <strong>crontab</strong> (в нашем случае <strong>* * * * *</strong>) и в конце добавим <strong>bash runscript.sh</strong>. Чтобы закончить редактуру файла vi, нажимаем клавишу Esc и пишем <strong>:wq</strong>. ","type":"p","className":""},{"data":{"id":2730,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/34378e6c291841b5a736893a67d1ac77-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/34378e6c291841b5a736893a67d1ac77-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":316,"real_height_2x":631},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/34378e6c291841b5a736893a67d1ac77-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/34378e6c291841b5a736893a67d1ac77-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":316,"real_height_2x":631}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Проверим, появился ли он в списке уже известной нам командой <strong>crontab -l</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2731,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/82b68503b1fc422483787b87ed6c5d8d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/82b68503b1fc422483787b87ed6c5d8d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":344,"real_height_2x":688},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/82b68503b1fc422483787b87ed6c5d8d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/82b68503b1fc422483787b87ed6c5d8d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":344,"real_height_2x":688}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы следить за рассылками, в терминале используем команду <strong>mail</strong>. Она покажет, приходили ли вам письма и сколько.","type":"p","className":""},{"data":{"id":2732,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7bbf25519328445cbd6296355217ed01-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7bbf25519328445cbd6296355217ed01-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":218,"real_height_2x":435},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7bbf25519328445cbd6296355217ed01-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7bbf25519328445cbd6296355217ed01-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":218,"real_height_2x":435}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь пора остановить скрипт. Для этого пропишем <strong>crontab -r</strong>. Перепроверить его можно той же командой <strong>crontab -l</strong>.&nbsp;","type":"p","className":""},{"data":"С помощью <strong>crontab</strong> можно запускать не только скрипты на Python, но и какие-то другие процессы — но для этого компьютер должен быть включен. В следующий раз разберемся, как делать все то же самое, но на удаленном сервере, чтобы работа скрипта не была привязана к вашему компьютеру. ","type":"p","className":""},{"data":"Если у вас появились вопросы, вы можете задать их в нашем <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">Telegram-чате</a>.","type":"p","className":""}]},{"id":295,"header":"Пишем своего робота на Python. Урок 12","_path":"/workshops/2021/07/27/pishem-svoego-robota-na-python-urok-12/","lead":"Учимся работать с личными данными при написании кода: узнаем, как безопасно обращаться к логинам, паролям и любым персональным данным через переменные окружения.","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/f5fb65807fa141d39942720027a5a075-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-07-27","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":true,"category":"workshops","locale":"ru","authors_list":[{"id":2517,"last_name":"","first_name":"Редакция","last_name_en":"","first_name_en":"Editors","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"На предыдущем 11-м занятии мы отправляли госконтракты себе на почту. И данные для входа в свою почту — логин и пароль — мы прописывали прямо в коде. \nЭто небезопасно, потому что мы этот код можем кому-то отправить, выложить на GitHub и забыть про то, что у нас там личные данные. Поэтому всегда, когда требуется ввод личных данных, принято хранить их в отдельном файле, который, в отличие от кода, никуда не передается.\n\nПервым шагом переместим все переменные (в нашем случае логин и пароль) в файл config.py, чтобы их было удобно редактировать в одном месте. Если эта переменная будет использована в каких-то других файлах, мы сможем не заходить отдельно в каждый из них, чтобы что-то поменять, а будем изменять все в одном месте — config.py. \nПримечание: в этом уроке пароль и почта ненастоящие.\n\nПосле того как мы перенесли логин и пароль в файл config.py, удалим эти строки из основного файла, который отправляет госконтракты на почту (send_email.py) и в начало добавим строку импорта этих данных из файла config.py. Не забываем сохранять изменения командой Ctrl + S или Command + S. \nНа этом уроке мы не будем отправлять контракты, а только потренируемся импортировать логины и пароли в код безопасным способом. Поэтому закомментируем последние строки файла send_email.py, которые непосредственно отвечают за отправку контрактов на почту, а вместо этого выведем две строки с print: просто распечатаем почту и пароль, чтобы убедиться, что они корректно передаются в программу. \nПопробуем распечатать логи и пароль, запустив программу send_emial.py в терминале (не забудьте указать путь к папке, в которой она находится). Логин и пароль корректно передаются. \nМы переместили все переменные в один файл config, и теперь нам удобно их менять, чтобы изменения отображались во всех файлах. Но это по-прежнему код, который нам может потребоваться куда-то выложить и передать. И персональные данные принято передавать через переменные окружения (environment variables, их еще переводят как переменные среды). \n\nКогда любая программа запускается, то ей передаются некие переменные, которые описывают ее окружение: где она запущена, на какой операционной системе, из какой папки, при каких обстоятельствах и так далее. Эти переменные можно увидеть, если ввести в терминале команду env.\nИ к этим системным переменным окружения мы можем добавить свои, чтобы они тоже передавались нашей программе при запуске. В нашем случае мы можем прописать логин и пароль в качестве таких переменных окружения. \n\nДля этого создаем файл .env и теперь туда записываем логин и пароль. Этот файл мы никому не будем передавать и будем его беречь от посторонних.\nУстанавливаем библиотеку python-dotenv командой pip3 install python-dotenv.\nТеперь в файле config убираем свои логины пароли и меняем на следующие строки:\nСохраняем все изменения в файлах config и .env. Теперь логин и пароль автоматически будут подтягиваться из файла .env через переменные окружения. Проверим, запустив программу send_email.py. Логин и пароль распечатались.\nТеперь наша программа может отправлять контракты безопасным способом, и мы не рискуем потерять свои персональные данные. Если у вас остались вопросы, заходите в наш в Telegram-чат.\n\nSottel\nCrampton\nSondale\nвладели\nсменились\nпринадлежало \n\n\nSottel Services Ltd\nCrampton Finance Ltd\nInvestment Advisors Ltd\nприобрела\nприобрела\nпередала\nпродав\nкомпании\nуказал\nChina EC IX Ltd\nсоцсетям\n\nпоказывают\nучредил\nбенефициаром\nбенефициаром\nвладельцем\nбенефициаром\nбенефициаром\nбенефициаром\nбенефициаром\nчерез\nприобрела\nпланируют\nвидео\nневзоров","blocks":[{"data":{"id":2671,"data":{"url":"https://www.youtube.com/embed/NpjHelVCCRU","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=NpjHelVCCRU","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"На предыдущем <a href=\"https://istories.media/workshops/2021/07/09/pishem-svoego-robota-na-python-urok-11/\" data-type=\"usual\" target=\"_blank\">11-м занятии</a> мы отправляли госконтракты себе на почту. И данные для входа в свою почту — логин и пароль — мы прописывали прямо в коде. ","type":"p","className":""},{"data":{"id":2661,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8595cb3460e4477e8bd2b0f397f07e39-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8595cb3460e4477e8bd2b0f397f07e39-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":586,"real_height_2x":1172},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8595cb3460e4477e8bd2b0f397f07e39-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/8595cb3460e4477e8bd2b0f397f07e39-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":586,"real_height_2x":1172}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Это небезопасно, потому что мы этот код можем кому-то отправить, выложить на GitHub и забыть про то, что у нас там личные данные. Поэтому всегда, когда требуется ввод личных данных, принято хранить их в отдельном файле, который, в отличие от кода, никуда не передается.","type":"p","className":""},{"data":"Первым шагом переместим все переменные (в нашем случае логин и пароль) в файл <strong>config.py,</strong> чтобы их было удобно редактировать в одном месте. Если эта переменная будет использована в каких-то других файлах, мы сможем не заходить отдельно в каждый из них, чтобы что-то поменять, а будем изменять все в одном месте — <strong>config.py. </strong>","type":"p","className":""},{"data":{"id":2662,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4e4adddc763946478954e7783a497be9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4e4adddc763946478954e7783a497be9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":143,"real_height_2x":286},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4e4adddc763946478954e7783a497be9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4e4adddc763946478954e7783a497be9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":143,"real_height_2x":286}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Примечание: в этом уроке пароль и почта ненастоящие.","type":"p","className":""},{"data":"После того как мы перенесли логин и пароль в файл config.py, удалим эти строки из основного файла, который отправляет госконтракты на почту (<strong>send_email.py</strong>) и в начало добавим строку импорта этих данных из файла config.py. Не забываем сохранять изменения командой Ctrl + S или Command + S. ","type":"p","className":""},{"data":{"id":2663,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f25d607510084d2e8c88deec9c7d4789-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f25d607510084d2e8c88deec9c7d4789-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":577,"real_height_2x":1154},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f25d607510084d2e8c88deec9c7d4789-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f25d607510084d2e8c88deec9c7d4789-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":577,"real_height_2x":1154}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"На этом уроке мы не будем отправлять контракты, а только потренируемся импортировать логины и пароли в код безопасным способом. Поэтому закомментируем последние строки файла <strong>send_email.py</strong>, которые непосредственно отвечают за отправку контрактов на почту, а вместо этого выведем две строки с print: просто распечатаем почту и пароль, чтобы убедиться, что они корректно передаются в программу. ","type":"p","className":""},{"data":{"id":2664,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f0b1eafa69f34d198ea44167b3d8bd5f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f0b1eafa69f34d198ea44167b3d8bd5f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":470,"real_height_2x":940},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f0b1eafa69f34d198ea44167b3d8bd5f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f0b1eafa69f34d198ea44167b3d8bd5f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":470,"real_height_2x":940}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Попробуем распечатать логи и пароль, запустив программу <strong>send_emial.py</strong> в терминале (не забудьте указать путь к папке, в которой она находится). Логин и пароль корректно передаются. ","type":"p","className":""},{"data":{"id":2665,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9a1eae082ea9409f902eea5f0705cb0e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9a1eae082ea9409f902eea5f0705cb0e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1046,"real_height_2x":2094},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9a1eae082ea9409f902eea5f0705cb0e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9a1eae082ea9409f902eea5f0705cb0e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1046,"real_height_2x":2094}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы переместили все переменные в один файл config, и теперь нам удобно их менять, чтобы изменения отображались во всех файлах. Но это по-прежнему код, который нам может потребоваться куда-то выложить и передать. И персональные данные принято передавать через <strong>переменные окружения</strong> (environment variables, их еще переводят как переменные среды). ","type":"p","className":""},{"data":"Когда любая программа запускается, то ей передаются некие переменные, которые описывают ее окружение: где она запущена, на какой операционной системе, из какой папки, при каких обстоятельствах и так далее. Эти переменные можно увидеть, если ввести в терминале команду env.","type":"p","className":""},{"data":{"id":2666,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a2a41bdcb2fb49a88f6abab016540b2e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a2a41bdcb2fb49a88f6abab016540b2e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":507,"real_height_2x":1014},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a2a41bdcb2fb49a88f6abab016540b2e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a2a41bdcb2fb49a88f6abab016540b2e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":507,"real_height_2x":1014}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"И к этим системным переменным окружения мы можем добавить свои, чтобы они тоже передавались нашей программе при запуске. В нашем случае мы можем прописать логин и пароль в качестве таких переменных окружения.&nbsp;","type":"p","className":""},{"data":"Для этого создаем файл <strong>.env</strong> и теперь туда записываем логин и пароль. Этот файл мы никому не будем передавать и будем его беречь от посторонних.","type":"p","className":""},{"data":{"id":2667,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/29255e854c2d4bdf8b7863d83442aefb-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/29255e854c2d4bdf8b7863d83442aefb-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":153,"real_height_2x":306},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/29255e854c2d4bdf8b7863d83442aefb-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/29255e854c2d4bdf8b7863d83442aefb-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":153,"real_height_2x":306}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Устанавливаем библиотеку <strong>python-dotenv</strong> командой pip3 install python-dotenv.","type":"p","className":""},{"data":{"id":2668,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f47e7be26d9e424281965db92259204d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f47e7be26d9e424281965db92259204d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":122,"real_height_2x":244},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f47e7be26d9e424281965db92259204d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f47e7be26d9e424281965db92259204d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":122,"real_height_2x":244}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь в файле config убираем свои логины пароли и меняем на следующие строки:","type":"p","className":""},{"data":{"id":2669,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c4c6c331884145edadf7aa69f2112bfd-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c4c6c331884145edadf7aa69f2112bfd-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":296,"real_height_2x":593},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/c4c6c331884145edadf7aa69f2112bfd-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/c4c6c331884145edadf7aa69f2112bfd-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":296,"real_height_2x":593}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Сохраняем все изменения в файлах config и .env. Теперь логин и пароль автоматически будут подтягиваться из файла .env через переменные окружения. Проверим, запустив программу send_email.py. Логин и пароль распечатались.","type":"p","className":""},{"data":{"id":2670,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/56c8c26b9ce849f0958796be9eb2b55d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/56c8c26b9ce849f0958796be9eb2b55d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":132,"real_height_2x":266},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/56c8c26b9ce849f0958796be9eb2b55d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/56c8c26b9ce849f0958796be9eb2b55d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":132,"real_height_2x":266}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь наша программа может отправлять контракты безопасным способом, и мы не рискуем потерять свои персональные данные. Если у вас остались вопросы, заходите в наш в <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">Telegram-чат</a>.","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/8b730bff976e46ef8fe9a633339572c6.pdf\" data-type=\"additional-fact\" target=\"_blank\">Sottel</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/399b574d95b945d8a07a24ecbf5c73c2.pdf\" data-type=\"additional-fact\" target=\"_blank\">Crampton</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/dd6ef65cbb20414ea5ed93297d10e914.pdf\" data-type=\"additional-fact\" target=\"_blank\">Sondale</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/6c261f52f7d246c7884880e8e896924c.pdf\" data-type=\"additional-fact\" target=\"_blank\">владели</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/2daccda026594e6bb71a044b8b0621a0.pdf\" data-type=\"additional-fact\" target=\"_blank\">сменились</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/b240b5d302a342a08143f2abc9ac966f.pdf\" data-type=\"additional-fact\" target=\"_blank\">принадлежало</a> ","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/e4a6992c5ad64a7caa1ed4ff9219b39a.pdf\" data-type=\"additional-fact\" target=\"_blank\">Sottel Services Ltd</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/b3aadadfccc6454b928c2a03e8acd94d.pdf\" data-type=\"additional-fact\" target=\"_blank\">Crampton Finance Ltd</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/705d6c9fa8e240fbb0cc7cc028598e5b.pdf\" data-type=\"additional-fact\" target=\"_blank\">Investment Advisors Ltd</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/d5d553a792da4694967e2afdc9e0cd83.pdf\" data-type=\"additional-fact\" target=\"_blank\">приобрела</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/7f873b85c8d641aeac5dfcab4ffc3d5c.pdf\" data-type=\"additional-fact\" target=\"_blank\">приобрела</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/6319630f10924ec5be445294ea750448.pdf\" data-type=\"additional-fact\" target=\"_blank\">передала</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/2ccc541ce651476b8cc1d30817d32b96.pdf\" data-type=\"additional-fact\" target=\"_blank\">продав</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/e03ec16586974e80b6a8938589d1fb30.jpeg\" data-type=\"additional-fact\" target=\"_blank\">компании</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/9c4e568a2bc84c60b44aeb0a2186a85f.pdf\" data-type=\"additional-fact\" target=\"_blank\">указал</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/408e5b42c6dc47108f68d171adc08e84.pdf\" data-type=\"additional-fact\" target=\"_blank\">China EC IX Ltd</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/65211633af45462aaeecc02cbf1c9700.pdf\" data-type=\"additional-fact\" target=\"_blank\">соцсетям</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/2381bf23d01947a3ac0ef60e031dcfc1.png\" data-type=\"additional-fact\" target=\"_blank\">показывают</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/fed112eae978439ea633f0778b3f40dc.png\" data-type=\"additional-fact\" target=\"_blank\">учредил</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/74b6bda489bf412096187b7612f893ec.png\" data-type=\"additional-fact\" target=\"_blank\">бенефициаром</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/71c28a8cbcdf4064b30c8cd160e5c7a0.png\" data-type=\"additional-fact\" target=\"_blank\">бенефициаром</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/9de2297cd9ad4b17b392ffad71af0942.png\" data-type=\"additional-fact\" target=\"_blank\">владельцем</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/c9e84958fb3343f388ab40a0a12fb3a2.png\" data-type=\"additional-fact\" target=\"_blank\">бенефициаром</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/92298d19f89d487c898e237acd4f6e41.png\" data-type=\"additional-fact\" target=\"_blank\">бенефициаром</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/39751db4c1e248d08c82a7309b748fde.png\" data-type=\"additional-fact\" target=\"_blank\">бенефициаром</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/d36ecb219e814973975b14f9ece3bd43.png\" data-type=\"additional-fact\" target=\"_blank\">бенефициаром</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/aa8fad67955d4d06bfc8d72ac1db3967.pdf\" data-type=\"additional-fact\" target=\"_blank\">через</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/9f871cf4b0d9416dbd4ed3c46f4c81dd.pdf\" data-type=\"additional-fact\" target=\"_blank\">приобрела</a>","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/fcf167d73f7d48cc91f368465848633f.csv\" data-type=\"additional-fact\" target=\"_blank\">планируют</a>","type":"p","className":""},{"data":"видео","type":"p","className":""},{"data":"<a href=\"https://static.istories.media/uploaded/documents/a19cd9749e4740eb9d5e10277de64ca0.png\" data-type=\"additional-fact\" target=\"_blank\">невзоров</a>","type":"p","className":""}]},{"id":288,"header":"Пишем своего робота на Python. Урок 11","_path":"/workshops/2021/07/09/pishem-svoego-robota-na-python-urok-11/","lead":"Отправляем письмо с подборкой госконтрактов при помощи модуля smtplib","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/73d062901c7e4722be110c68551ebe50-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-07-09","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Сегодня мы научим нашего робота по анализу госконтрактов отправлять письма.\n\n\nДля отправки писем в Python есть встроенный модуль smtplib. Импортируем модуль и дополнительные надгрузки в наш проект.\n\n\nНаш код уже умеет выгружать контракты с сайта «ГосЗатраты», формировать из них таблицу — теперь осталось только выслать эту таблицу пользователю. Запишем в переменную message то сообщение, которое мы будем высылать. Далее нам понадобится еще несколько переменных.\n\n\nПервым понадобится список email-адресов, куда мы хотим отправить письмо (email_list) — запишем туда свой адрес. Далее понадобится логин и пароль почты (SENDER_EMAIL и EMAIL_PASSWORD соответственно), с которой письмо будет рассылаться. Возможно, для этого стоит зарегистрировать отдельную почту. \n\nТакже будет лучше создать файл config, в котором будет храниться информация о логине и пароле, чтобы она не была доступна никому кроме вас. Теперь пишем функцию send_email_with_contracts (message, email_list) — на вход она получает сообщение, которое нужно отправить, и список получателей письма. \n\nСледом создадим переменную msg, которой зададим тип контента, который мы хотим высылать — в данном случае это alternative. Укажем также тему письма, адрес отправителя рассылки и адреса получателей. Список получателей мы формируем с помощью функции join через запятую. У нас получатель один, но их может быть сколько угодно.\n\n\nСоздаем непосредственно письмо. Передаем нашу переменную message и указываем html в качестве типа данных, потому что таблица, которую мы учились делать на прошлых уроках, как раз на HTML. Таблицу мы прикрепляем к письму.\n\n\nС помощью сервера Google и безопасного протокола мы заходим в почту-отправителя, передаем логин и пароль и командой send_message отправляем сообщение.\n\n\nЕсли вы следовали за нашими уроками, то после запуска всего кода на вашу почту должно прийти письмо с подборкой госконтрактов. В следующий раз научим наш код запускаться автоматически. Если у вас что-то не получилось — не стесняйтесь писать в наш чат в Telegram, постараемся помочь.","blocks":[{"data":"Сегодня мы научим нашего робота по анализу госконтрактов отправлять письма.","type":"p","className":""},{"data":{"id":2808,"data":{"url":"https://www.youtube.com/embed/2LCiYIrqSVw","text":"Съемка и монтаж: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=2LCiYIrqSVw","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Для отправки писем в Python есть встроенный модуль <strong>smtplib</strong>. Импортируем модуль и дополнительные надгрузки в наш проект.","type":"p","className":""},{"data":{"id":2588,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/620e7e41fef8473882fea34a212f64fe-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/620e7e41fef8473882fea34a212f64fe-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":634,"real_height_2x":1267},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/620e7e41fef8473882fea34a212f64fe-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/620e7e41fef8473882fea34a212f64fe-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":634,"real_height_2x":1267}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Наш код уже умеет выгружать контракты с сайта «ГосЗатраты», формировать из них таблицу — теперь осталось только выслать эту таблицу пользователю. Запишем в переменную <strong>message</strong> то сообщение, которое мы будем высылать. Далее нам понадобится еще несколько переменных.","type":"p","className":""},{"data":{"id":2589,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/969140b23dc440fcbfaee1cc663f98e9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/969140b23dc440fcbfaee1cc663f98e9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":575,"real_height_2x":1150},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/969140b23dc440fcbfaee1cc663f98e9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/969140b23dc440fcbfaee1cc663f98e9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":575,"real_height_2x":1150}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Первым понадобится список email-адресов, куда мы хотим отправить письмо (<strong>email_list</strong>) — запишем туда свой адрес. Далее понадобится логин и пароль почты (<strong>SENDER_EMAIL</strong> и <strong>EMAIL_PASSWORD</strong> соответственно), с которой письмо будет рассылаться. Возможно, для этого стоит зарегистрировать отдельную почту. ","type":"p","className":""},{"data":"Также будет лучше создать файл <strong>config</strong>, в котором будет храниться информация о логине и пароле, чтобы она не была доступна никому кроме вас.&nbsp;Теперь пишем функцию <strong>send_email_with_contracts (message, email_list)</strong> — на вход она получает сообщение, которое нужно отправить, и список получателей письма. ","type":"p","className":""},{"data":"Следом создадим переменную <strong>msg</strong>, которой зададим тип контента, который мы хотим высылать — в данном случае это <strong>alternative</strong>. Укажем также тему письма, адрес отправителя рассылки и адреса получателей. Список получателей мы формируем с помощью функции <strong>join</strong> через запятую. У нас получатель один, но их может быть сколько угодно.","type":"p","className":""},{"data":{"id":2590,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e2a15bebef7f47629db67bdde61441ac-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e2a15bebef7f47629db67bdde61441ac-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":579,"real_height_2x":1158},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e2a15bebef7f47629db67bdde61441ac-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e2a15bebef7f47629db67bdde61441ac-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":579,"real_height_2x":1158}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Создаем непосредственно письмо. Передаем нашу переменную <strong>message</strong> и указываем <strong>html</strong> в качестве типа данных, потому что таблица, которую мы учились делать на <a href=\"https://istories.media/workshops/2021/06/18/pishem-svoego-robota-na-python-urok-9/\" data-type=\"usual\" target=\"_blank\">прошлых уроках</a>, как раз на HTML. Таблицу мы прикрепляем к письму.","type":"p","className":""},{"data":{"id":2591,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/486f87fd001d4424a76dd330eae001c8-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/486f87fd001d4424a76dd330eae001c8-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":455,"real_height_2x":910},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/486f87fd001d4424a76dd330eae001c8-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/486f87fd001d4424a76dd330eae001c8-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":455,"real_height_2x":910}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"С помощью сервера Google и безопасного протокола мы заходим в почту-отправителя, передаем логин и пароль и командой <strong>send_message </strong>отправляем сообщение.","type":"p","className":""},{"data":{"id":2592,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e4ae3e77f57b415a90c9624e188fa9a7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e4ae3e77f57b415a90c9624e188fa9a7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":611,"real_height_2x":1222},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e4ae3e77f57b415a90c9624e188fa9a7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e4ae3e77f57b415a90c9624e188fa9a7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":611,"real_height_2x":1222}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если вы следовали за нашими уроками, то после запуска всего кода на вашу почту должно прийти письмо с подборкой госконтрактов. В следующий раз научим наш код запускаться автоматически. Если у вас что-то не получилось —&nbsp;не стесняйтесь писать в наш <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">чат</a> в Telegram, постараемся помочь.","type":"p","className":""}]},{"id":282,"header":"Пишем своего робота на Python. Урок 10","_path":"/workshops/2021/06/25/pishem-svoego-robota-na-python-urok-10/","lead":"Заполняем HTML-таблицу данными о госконтрактах с помощью Python-библиотеки Jinja2","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/edfe5e59b5774d47904984f375c739d2-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-06-25","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":9,"first_name":"Ирина","last_name":"Долинина","first_name_en":"Irina","last_name_en":"Dolinina","is_public":true,"_path":"irina-dolinina","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-896x504px_2x.webp","crop_zone":null,"for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-896x504px_2x.jpg","crop_zone":null,"for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-688x387px_2x.webp","crop_zone":null,"for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-688x387px_2x.jpg","crop_zone":null,"for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-416x234px_2x.webp","crop_zone":null,"for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-416x234px_2x.jpg","crop_zone":null,"for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-336x189px_2x.webp","crop_zone":null,"for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-336x189px_2x.jpg","crop_zone":null,"for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Журналистка «Важных историй»","lead_en":"IStories' investigative reporter","position":"Авторка","position_en":"Author","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"На прошлом уроке мы изучили основы языков для верстки сайтов HTML и CSS и создали с помощью них таблицу. А сегодня мы научим нашего робота автоматически собирать спарсенные данные о госконтрактах в эту таблицу. Для этого мы будем использовать Python-библиотеку Jinja2. \nJinja2 — это шаблонитизатор, с помощью которого можно подставлять переменные из Python на страницы в браузере. В нашем случае это будут спарсенные данные о госконтрактах, которые мы подставим в нашу таблицу. Принцип работы Jinja2 похож на метод f-строк. Только переменные заключаются в двойные фигурные скобки, а не одинарные. \n\nДавайте посмотрим, как это работает, на простом примере. Для начала установите бибилиотеку через команду в терминале pipenv install Jinja2. Затем нужно импортировать класс Template. Создааем шаблон приветствия: Hello и имя, которое будем в этот шаблон как раз подставлять. В переменную template кладем наш шаблон (получаем объект template, то есть экземпляр класса Template). Затем применяем к объекту template метод render(), который обрабатывает наш шаблон. Так Jinja2 подставляет значение аргумента name, которое мы указали — Harry — в указанное нами место в шаблоне. Получаем результат: Hello, Harry. А вот как бы мы записали это с помощью f-строки. \n\n\nМетод render() обрабатывает шаблон, используя именованные аргументы, которые ему передаются (как в примере с именем), или используя словарь. Для нашего случая нам нужен список со десятью словарями, где каждый словарь содержит данные о контракте из топа-10 крупнейших за неделю. Создадим такой список с помощью функции get_top_contracts(). Внутри нее нам пригодится наша рекурсивная функция, которую мы писали на предыдущих уроках. Также необходимо прописать условие для случаев, когда данных о поставщике контракта нет (к сожалению, на госзакупках это стало часто происходить). И возвращает наша функция первые 10 госконтрактов (словарей). \nПерейдем к нашу HTML-коду, который мы написали на прошлом уроке: его нужно обновить и подготовить для работы с Jinja2. Во-первых, добавим количество столбцов и правильно их переименуем. Во-вторых, пропишем выражения Jinja2 (как мы указывали name в двойных фигурных скобках в начале урока). Так как у нас довольно большой объем данных, нам нужно использовать цикл для их обработки. Открываем цикл Дзиндзя с помощью синтаксиса этой библиотеки, где items это наш список со словарями. Цикл будет ходить по каждому элементу словаря и заполнять наши строки в таблице (каждая строка в таблице это один словарь). В конце закрываем этот цикл тоже по правилу Jinja2. \nТеперь создадим папку templates в нашем проекте robot в Visual studio code и положим туда наш обновленный HTML-код. А в нашем основном документе — main.py — напишем функцию create_message() для того, чтобы отрендерить шаблон. Вверху кода, где у нас все импорты, добавим:\n\nfrom jinja2 import Template\nfrom jinja2 import Environment, FileSystemLoader, select_autoescape\n\nФункция create_message() на вход получает наш список со словарями. Теперь нужно дать понять Jinja2, где ей брать HTML-шаблон. FileSystemLoader находит нашу папку с шаблонами. В select_autoescape прописываем форматы. А в переменную template загружается шаблон из файла — table.html. Затем рендерим наш шаблон с помощью уже известного нам метода, указываем что items в коде HTML — это наш список со словарями (top_contracts). Теперь message — это переменная, в которой лежит таблица с собранными данными о госконтрактах. Запишем ее в новый HTML-файл, чтобы потом можно было посмотреть результат в браузере. Наша функция возвращает сообщение с информацией про контракты в табличном виде, чтобы в дальнейшем мы могли передать это сообщение  по почте. \nДобавим в наш итог (result) из документации API Clearspending сортировку по убыванию цены (sort='-price') и применим две сегодняшние функции. \nТеперь откроем файл с новой таблицей и посмотрим через расширение Live server на итоговую таблицу в браузере.\nК сожалению, как мы видим, данные о всех поставщиках скрыты с госзакупок. Такую картину по крупных контарктам мы наблюдаем уже несколько месяцев. Реестр становится все более закрытым.","blocks":[{"data":"На прошлом <a href=\"https://istories.media/workshops/2021/06/18/pishem-svoego-robota-na-python-urok-9/\" data-type=\"usual\" target=\"_blank\">уроке</a> мы изучили основы языков для верстки сайтов HTML и CSS и создали с помощью них таблицу. А сегодня мы научим нашего робота автоматически собирать спарсенные данные о госконтрактах в эту таблицу. Для этого мы будем использовать Python-библиотеку <strong>Jinja2</strong>. ","type":"p","className":""},{"data":{"id":2552,"data":{"url":"https://www.youtube.com/embed/8wr0Qy28a8Q","caption":"Видео: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=8wr0Qy28a8Q","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"<a href=\"http://jinja.pocoo.org/\" data-type=\"usual\" target=\"_blank\">Jinja2</a>&nbsp;— это шаблонитизатор, с помощью которого можно подставлять переменные из Python на страницы в браузере. В нашем случае это будут спарсенные данные о госконтрактах, которые мы подставим в нашу таблицу.&nbsp;Принцип работы Jinja2 похож на метод f-строк. Только переменные заключаются в двойные фигурные скобки, а не одинарные. ","type":"p","className":""},{"data":"Давайте посмотрим, как это работает, на простом примере. Для начала установите бибилиотеку через команду в терминале <strong>pipenv install Jinja2</strong>. Затем нужно импортировать класс Template. Создааем шаблон приветствия: Hello и имя, которое будем в этот шаблон как раз подставлять. В переменную <strong>template</strong> кладем наш шаблон (получаем объект template, то есть экземпляр класса <strong>Template</strong>). Затем применяем к объекту template метод <strong>render()</strong>, который обрабатывает наш шаблон. Так Jinja2 подставляет значение аргумента name, которое мы указали — Harry — в указанное нами место в шаблоне.&nbsp;Получаем результат: Hello, Harry. А вот как бы мы записали это с помощью f-строки. ","type":"p","className":""},{"data":{"id":2545,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9ac320fa48f74ad99db994f16084a407-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9ac320fa48f74ad99db994f16084a407-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":268,"real_height_2x":535},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9ac320fa48f74ad99db994f16084a407-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9ac320fa48f74ad99db994f16084a407-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":268,"real_height_2x":535}]},{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/eca4e017086a4e95ad347a4bd1b4ff4c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/eca4e017086a4e95ad347a4bd1b4ff4c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":332,"real_height_2x":665},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/eca4e017086a4e95ad347a4bd1b4ff4c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/eca4e017086a4e95ad347a4bd1b4ff4c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":332,"real_height_2x":665}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Метод render() обрабатывает шаблон, используя именованные аргументы, которые ему передаются (как в примере с именем), или используя словарь. Для нашего случая нам нужен список со десятью словарями, где каждый словарь содержит данные о контракте из топа-10 крупнейших за неделю. Создадим такой список с помощью функции <strong>get_top_contracts()</strong>. Внутри нее нам пригодится наша рекурсивная функция, которую мы <a href=\"https://istories.media/workshops/2021/05/01/pishem-svoego-robota-na-python-urok-4/\" data-type=\"usual\" target=\"_blank\">писали</a> на предыдущих уроках. Также необходимо прописать условие для случаев, когда данных о поставщике контракта нет (к сожалению, на госзакупках это стало часто происходить). И возвращает наша функция первые 10 госконтрактов (словарей).&nbsp;","type":"p","className":""},{"data":{"id":2539,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ee6c909d50c543d39aba53f7f285871b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ee6c909d50c543d39aba53f7f285871b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1156,"real_height_2x":2312},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ee6c909d50c543d39aba53f7f285871b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ee6c909d50c543d39aba53f7f285871b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1156,"real_height_2x":2312}]},{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a95fcd09ed3243c59314000c656f4423-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a95fcd09ed3243c59314000c656f4423-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":592,"real_height_2x":1183},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a95fcd09ed3243c59314000c656f4423-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a95fcd09ed3243c59314000c656f4423-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":592,"real_height_2x":1183}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Перейдем к нашу HTML-коду, который мы написали на прошлом уроке: его нужно обновить и подготовить для работы с Jinja2. Во-первых, добавим количество столбцов и правильно их переименуем. Во-вторых, пропишем выражения Jinja2 (как мы указывали name в двойных фигурных скобках в начале урока).&nbsp;Так как у нас довольно большой объем данных, нам нужно использовать цикл для их обработки. Открываем цикл Дзиндзя с помощью синтаксиса этой библиотеки, где items это наш список со словарями. Цикл будет ходить по каждому элементу словаря и заполнять наши строки в таблице (каждая строка в таблице это один словарь). В конце закрываем этот цикл тоже по правилу Jinja2.&nbsp;","type":"p","className":""},{"data":{"id":2536,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e3f89e69596549fc8226de4f719cbc0f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e3f89e69596549fc8226de4f719cbc0f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1263,"real_height_2x":2526},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e3f89e69596549fc8226de4f719cbc0f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e3f89e69596549fc8226de4f719cbc0f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1263,"real_height_2x":2526}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь создадим папку templates в нашем проекте robot в Visual studio code и положим туда наш обновленный HTML-код. А в нашем основном документе — main.py — напишем функцию <strong>create_message()</strong> для того, чтобы отрендерить шаблон. Вверху кода, где у нас все импорты, добавим:","type":"p","className":""},{"data":"<strong>from jinja2 import Template</strong>","type":"p","className":""},{"data":"<strong>from jinja2 import Environment, FileSystemLoader, select_autoescape</strong>","type":"p","className":""},{"data":"Функция create_message() на вход получает наш список со словарями. Теперь нужно дать понять Jinja2, где ей брать HTML-шаблон.&nbsp;FileSystemLoader находит нашу папку с шаблонами. В select_autoescape прописываем форматы. А в переменную template загружается шаблон из файла — table.html. Затем рендерим наш шаблон с помощью уже известного нам метода, указываем что items в коде HTML — это наш список со словарями (top_contracts). Теперь message&nbsp;— это переменная, в которой лежит таблица с собранными данными о госконтрактах. Запишем ее в новый HTML-файл, чтобы потом можно было посмотреть результат в браузере.&nbsp;Наша функция возвращает сообщение с информацией про контракты в табличном виде, чтобы в дальнейшем мы могли передать это сообщение  по почте.&nbsp;","type":"p","className":""},{"data":{"id":2540,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b0f361f9f8b34e78b71ec15a0dee3704-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b0f361f9f8b34e78b71ec15a0dee3704-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":563,"real_height_2x":1126},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b0f361f9f8b34e78b71ec15a0dee3704-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b0f361f9f8b34e78b71ec15a0dee3704-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":563,"real_height_2x":1126}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Добавим в наш итог (<strong>result</strong>) из <a href=\"https://github.com/datacoon/clearspending-examples/wiki/%D0%9E%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-API-%D0%9A%D0%BE%D0%BD%D1%82%D1%80%D0%B0%D0%BA%D1%82%D1%8B\" data-type=\"usual\" target=\"_blank\">документации</a> API Clearspending сортировку по убыванию цены (<strong>sort='-price'</strong>) и применим две сегодняшние функции. ","type":"p","className":""},{"data":{"id":2543,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a59d394e559742ff8fed7fc073402736-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a59d394e559742ff8fed7fc073402736-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":206,"real_height_2x":412},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a59d394e559742ff8fed7fc073402736-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a59d394e559742ff8fed7fc073402736-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":206,"real_height_2x":412}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь откроем файл с новой таблицей и посмотрим через расширение Live server на итоговую таблицу в браузере.","type":"p","className":""},{"data":{"id":2544,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/54873091e8f5457da67bbd6180def631-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/54873091e8f5457da67bbd6180def631-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":508,"real_height_2x":1016},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/54873091e8f5457da67bbd6180def631-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/54873091e8f5457da67bbd6180def631-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":508,"real_height_2x":1016}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"К сожалению, как мы видим, данные о всех поставщиках скрыты с госзакупок. Такую картину по крупных контарктам мы наблюдаем уже несколько месяцев. Реестр становится все более закрытым. ","type":"p","className":""}]},{"id":280,"header":"Пишем своего робота на Python. Урок 9","_path":"/workshops/2021/06/18/pishem-svoego-robota-na-python-urok-9/","lead":"Учимся верстать таблицы с помощью HTML и CSS ","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/c2d8e505eeed434a9582cc7315bc3664-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-06-18","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":9,"first_name":"Ирина","last_name":"Долинина","first_name_en":"Irina","last_name_en":"Dolinina","is_public":true,"_path":"irina-dolinina","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-896x504px_2x.webp","crop_zone":null,"for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-896x504px_2x.jpg","crop_zone":null,"for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-688x387px_2x.webp","crop_zone":null,"for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-688x387px_2x.jpg","crop_zone":null,"for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-416x234px_2x.webp","crop_zone":null,"for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-416x234px_2x.jpg","crop_zone":null,"for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-336x189px_2x.webp","crop_zone":null,"for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-336x189px_2x.jpg","crop_zone":null,"for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/1ce8f6c2725d44ee82748f09aa73e8a1-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Журналистка «Важных историй»","lead_en":"IStories' investigative reporter","position":"Авторка","position_en":"Author","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Наш робот, написанный на языке Python, уже умеет собирать крупнейшие госконтракты, заключенные в России. Нам осталось научить его упаковывать данные в удобную для чтения таблицу и затем отправлять ее на почту. На сегодняшнем уроке мы научимся основам языков для верстки сайтов HTML и CSS и создадим с помощью них таблицу.\nС помощью языка HTML создается каркас веб-страницы, которую вы видите в браузере. Любая страница сайта это HTML код: браузер его читает и отображает содержимое в удобном для пользователя виде. HTML код в свою очередь состоит из HTML-тегов (еще их можно называть элементы). Они создаются по принципу иерархии. Например, как в научных работах есть строгие правила оформления: название работы, название главы, параграфа и так далее. Разница только в том, что большинство тегов HTML открываются и закрываются. Давайте посмотрим, как это работает на примере верстки нашей первой таблицы.\n\nОткрываем Visual Studio Code, где мы работаем над нашим роботом. Для начала нужно установить расширение Live server, чтобы мы могли смотреть, как отображается наш HTML-код в браузере. Затем создаем новый документ в формате html.\nСначала мы пишем самый высший в иерархии тег <html> : в нем будет содержаться вся информация нашей веб-страницы. Имя тегов мы пишем в так называемых уголках меньше < чем и больше чем >. У закрывающего тега добавляется перед именем слэш </html>. Закрывающий тег одного элемента располагается либо на одном уровне с открывающим, либо, как мы увидим позже, может быть в конце текста. Теги HTML на одном уровне. \nТеперь спускаемся ниже в HTML-иерархии. Следующий градостроительный тег называется <head> и будет содержать метаинформацию о странице. Тегам можно задавать определенные характеристики с помощью их атрибутов. В теге <meta> с помощью атрибута charset задаем стандартную кодировку UTF-8. <meta> — это пример не закрывающегося тега. Затем в теге title пишем название нашей страницы: например, Моя таблица. Закрываем тег <title> на этой же строке.\nВторой основной блок внутри главного тега <html> после <head> — это тело HTML-документа, тег <body>. Сегодня мы хотим, чтобы информация на нашей странице была представлена в табличном виде. Для этого открываем тег <table>. Дальше создаем строки таблицы c помощью тега <tr>. В первой строке в ячейках у нас будут заголовки: их мы определяем тегами <th>. Сделаем пока несколько условных заголовков: Заказчик, Предмет контракта, Сумма контракта, Поставщик. \nДавайте посмотрим, что у нас уже получилось. Для этого сохраним изменения (file—save или комбинацией клавиш command+S). И нажмием в правом нижнем угле go live, чтобы с помощью расширения, которое мы установили, перейти к просмотру кода HTML через отображение в браузере. Чтобы видеть изменения в браузере, нужно каждый раз сохранять их в документе. Добавим тегу <table> атрибут с шириной таблицы (style=\"width:100%;\") и сделаем ее на все 100%. Это будет единственный элемент стиля, который мы добавим в сам HTML-код сегодня.\nСоздадим еще одну строку в таблице, но уже с простыми ячейками, не заголовками — их мы определяем тегом <td>. Я пропишу 5 таких строк с данными о крупнейших госконтрактах из одной из наших рассылок. Добавить заголовок с помощью тега <h2> перед тегом <table>, потому что это уже не часть таблицы (заголовочные теги — от <h1> до <h6>).\nТеперь поработаем над внешним видом таблицы. Мы уже задали один атрибут стиля таблице и отформатировали ее ширину прямо в коде html. Но для этих целей удобнее использовать язык описания внешнего вида HTML-документа — CSS. Если HTML структурирует документ, упорядочивает информацию, то CSS в свою очередь красиво оформляет этот документ.\n\nСтили или правила оформления нашей HTML-страницы удобно прописывать в отдельном файле: затем получившеюся таблицу стилей можно будет использовать для многих страниц. Но можно прописать стили и в самом коде HTML с помощью тегов <style>. Мы создадим отдельный файл в формате css.\n\nЧтобы наш HTML-код знал откуда брать стили для таблицы, нужно подключить к нему таблицу стилей. Для этого в метаинформации нашей страницы — теге head — мы добавляем тег link c атрибутом rel (relation — то есть так мы определяем отношение между кодом html и подключаемым файлом). В нашем случае это stylesheet, таблица стилей. В атрибуте href указываем название нашего файла.\nДавайте посмотрим на простейших правилах стиля, что умеет язык CSS. Правила в таблице стилей мы задаем с помощью фигурных скобок  {}. Перед открывающейся скобкой указываем, к какому HTML-элементу мы хотим применить эти правила. Изменим цвет (color): к заголовку таблицы и первой строке с названиями колонок поставим цвет потемнее, а сновной текст в таблице сделаем светлее. Поменяем шрифт (font-family), размер (font-size)  и выравнивание (text-align) текста. Добавим расстояния между границами ячеек в таблице (border-spacing) и еще дополнительное расстояние в ячейках с основной информацией (padding). \n\nПравил стиля очень много в CSS: их можно посмотреть, например, тут. Или можно скопировать понравившееся правило стиля из кода уже готовой таблицы. Например, давайте скопируем из этой таблицы правило, которое раскрашивает строки через одну. Вот такая у нас получилась таблица:\nНа следующем уроке мы научим нашего робота автоматически собирать спарсенные данные о госконтрактах в таблицу html.","blocks":[{"data":"Наш робот, написанный на языке Python, уже умеет собирать крупнейшие госконтракты, заключенные в России. Нам осталось научить его упаковывать данные в удобную для чтения таблицу и затем отправлять ее на почту. На сегодняшнем уроке мы научимся основам языков для верстки сайтов <strong>HTML</strong> и <strong>CSS</strong> и создадим с помощью них таблицу.","type":"p","className":""},{"data":{"id":2526,"data":{"url":"https://www.youtube.com/embed/9fxUKqKgeRA","caption":"Видео: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=9fxUKqKgeRA","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"С помощью языка HTML создается каркас веб-страницы, которую вы видите в браузере. Любая страница сайта это HTML код: браузер его читает и отображает содержимое в удобном для пользователя виде. HTML код в свою очередь состоит из HTML-тегов (еще их можно называть элементы). Они создаются по принципу иерархии. Например, как в научных работах есть строгие правила оформления: название работы, название главы, параграфа и так далее. Разница только в том, что большинство тегов HTML открываются и закрываются. Давайте посмотрим, как это работает на примере верстки нашей первой таблицы.","type":"p","className":""},{"data":"Открываем Visual Studio Code, где мы работаем над нашим роботом. Для начала нужно установить расширение Live server, чтобы мы могли смотреть, как отображается наш HTML-код в браузере. Затем создаем новый документ в формате html.","type":"p","className":""},{"data":{"id":2515,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/cb2c23cf5a1a460e84ec3215ece9d3c5-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/cb2c23cf5a1a460e84ec3215ece9d3c5-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":431,"real_height_2x":862},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/cb2c23cf5a1a460e84ec3215ece9d3c5-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/cb2c23cf5a1a460e84ec3215ece9d3c5-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":431,"real_height_2x":862}]},{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/eecac6ef504d40658ec3dd1baf09022c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/eecac6ef504d40658ec3dd1baf09022c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":454,"real_height_2x":910},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/eecac6ef504d40658ec3dd1baf09022c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/eecac6ef504d40658ec3dd1baf09022c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":454,"real_height_2x":910}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Сначала мы пишем самый высший в иерархии тег <strong>&lt;html&gt;</strong> : в нем будет содержаться вся информация нашей веб-страницы. Имя тегов мы пишем в так называемых уголках меньше <strong>&lt;</strong> чем и больше чем <strong>&gt;</strong>. У закрывающего тега добавляется перед именем слэш <strong>&lt;/html&gt;</strong>. Закрывающий тег одного элемента располагается либо на одном уровне с открывающим, либо, как мы увидим позже, может быть в конце текста. Теги HTML на одном уровне. ","type":"p","className":""},{"data":{"id":2517,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ff37702790a4418294b4ae7aee14f162-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ff37702790a4418294b4ae7aee14f162-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":285,"real_height_2x":570},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ff37702790a4418294b4ae7aee14f162-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ff37702790a4418294b4ae7aee14f162-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":285,"real_height_2x":570}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь спускаемся ниже в HTML-иерархии. Следующий градостроительный тег называется &lt;<strong>head&gt;</strong>&nbsp;и будет содержать метаинформацию о странице. Тегам можно задавать определенные характеристики с помощью их атрибутов. В теге &lt;<strong>meta&gt;</strong>&nbsp;с помощью атрибута <strong>charset</strong> задаем стандартную кодировку UTF-8. <strong>&lt;meta&gt;</strong> — это пример не закрывающегося тега. Затем в теге <strong>title</strong> пишем название нашей страницы: например, Моя таблица. Закрываем тег &lt;<strong>title&gt;</strong> на этой же строке.","type":"p","className":""},{"data":{"id":2518,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/df04777a300f42f299e79733582b5bda-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/df04777a300f42f299e79733582b5bda-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":320,"real_height_2x":639},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/df04777a300f42f299e79733582b5bda-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/df04777a300f42f299e79733582b5bda-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":320,"real_height_2x":639}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Второй основной блок внутри главного тега &lt;<strong>html&gt;</strong> после &lt;<strong>head&gt;</strong> — это тело HTML-документа, тег &lt;<strong>body&gt;</strong>. Сегодня мы хотим, чтобы информация на нашей странице была представлена в табличном виде. Для этого открываем тег &lt;<strong>table&gt;. </strong>Дальше создаем строки таблицы c помощью тега <strong>&lt;tr&gt;</strong>. В первой строке в ячейках у нас будут заголовки: их мы определяем тегами &lt;<strong>th&gt;</strong>. Сделаем пока несколько условных заголовков: Заказчик, Предмет контракта, Сумма контракта, Поставщик. ","type":"p","className":""},{"data":{"id":2519,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e812c4a8b7704d39b82aca1ad6537823-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e812c4a8b7704d39b82aca1ad6537823-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1166,"real_height_2x":2332},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e812c4a8b7704d39b82aca1ad6537823-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e812c4a8b7704d39b82aca1ad6537823-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1166,"real_height_2x":2332}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Давайте посмотрим, что у нас уже получилось. Для этого сохраним изменения (file—save или комбинацией клавиш command+S). И нажмием в правом нижнем угле go live, чтобы с помощью расширения, которое мы установили, перейти к просмотру кода HTML через отображение в браузере. Чтобы видеть изменения в браузере, нужно каждый раз сохранять их в документе. Добавим тегу &lt;<strong>table&gt;</strong> атрибут с шириной таблицы (<strong>style=\"width:100%;\"</strong>) и сделаем ее на все 100%. Это будет единственный элемент стиля, который мы добавим в сам HTML-код сегодня.","type":"p","className":""},{"data":{"id":2520,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/0ea8bebe4fd04293825192c46a12875f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/0ea8bebe4fd04293825192c46a12875f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":374,"real_height_2x":748},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/0ea8bebe4fd04293825192c46a12875f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/0ea8bebe4fd04293825192c46a12875f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":374,"real_height_2x":748}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Создадим еще одну строку в таблице, но уже с простыми ячейками, не заголовками — их мы определяем тегом &lt;<strong>td&gt;</strong>. Я пропишу 5 таких строк с данными о крупнейших госконтрактах из одной из наших рассылок. Добавить заголовок с помощью тега &lt;<strong>h2&gt;</strong> перед тегом &lt;<strong>table&gt;</strong>, потому что это уже не часть таблицы (заголовочные теги — от <strong>&lt;h1&gt;</strong> до <strong>&lt;h6&gt;</strong>).","type":"p","className":""},{"data":{"id":2522,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ed997d26993b4a65bf37b4668d587a8a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ed997d26993b4a65bf37b4668d587a8a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":664,"real_height_2x":1330},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ed997d26993b4a65bf37b4668d587a8a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ed997d26993b4a65bf37b4668d587a8a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":664,"real_height_2x":1330}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь поработаем над внешним видом таблицы. Мы уже задали один атрибут стиля таблице и отформатировали ее ширину прямо в коде html. Но для этих целей удобнее использовать язык описания внешнего вида HTML-документа — <strong>CSS</strong>. Если HTML структурирует документ, упорядочивает информацию, то CSS в свою очередь красиво оформляет этот документ.","type":"p","className":""},{"data":"Стили или правила оформления нашей HTML-страницы удобно прописывать в отдельном файле: затем получившеюся таблицу стилей можно будет использовать для многих страниц. Но можно прописать стили и в самом коде HTML с помощью тегов <strong>&lt;style&gt;</strong>. Мы создадим отдельный файл в формате css.","type":"p","className":""},{"data":"Чтобы наш HTML-код знал откуда брать стили для таблицы, нужно подключить к нему таблицу стилей. Для этого в метаинформации нашей страницы — теге <strong>head</strong> — мы добавляем тег <strong>link</strong> c атрибутом <strong>rel</strong> (relation — то есть так мы определяем отношение между кодом html и подключаемым файлом). В нашем случае это <strong>stylesheet</strong>, таблица стилей. В атрибуте <strong>href</strong> указываем название нашего файла.","type":"p","className":""},{"data":{"id":2523,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/16718f0c72ba4da49033b6436846b83a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/16718f0c72ba4da49033b6436846b83a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":416,"real_height_2x":833},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/16718f0c72ba4da49033b6436846b83a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/16718f0c72ba4da49033b6436846b83a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":416,"real_height_2x":833}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Давайте посмотрим на простейших правилах стиля, что умеет язык <strong>CSS</strong>. Правила в таблице стилей мы задаем с помощью фигурных скобок  {}. Перед открывающейся скобкой указываем, к какому HTML-элементу мы хотим применить эти правила. Изменим цвет (<strong>color</strong>): к заголовку таблицы и первой строке с названиями колонок поставим цвет потемнее, а сновной текст в таблице сделаем светлее. Поменяем шрифт (<strong>font-family</strong>), размер (<strong>font-size</strong>)  и выравнивание (<strong>text-align</strong>) текста. Добавим расстояния между границами ячеек в таблице (<strong>border-spacing</strong>) и еще дополнительное расстояние в ячейках с основной информацией (<strong>padding</strong>). ","type":"p","className":""},{"data":"Правил стиля очень много в CSS: их можно посмотреть, например, <a href=\"http://htmlbook.ru/css\" data-type=\"usual\" target=\"_blank\">тут</a>. Или можно скопировать понравившееся правило стиля из кода уже готовой таблицы. Например, давайте скопируем из <a href=\"https://www.w3schools.com/html/tryit.asp?filename=tryhtml_table_intro\" data-type=\"usual\" target=\"_blank\">этой</a> таблицы правило, которое раскрашивает строки через одну. Вот такая у нас получилась таблица:","type":"p","className":""},{"data":{"id":2525,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c619ec92074347a3b4777d278a3f5035-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c619ec92074347a3b4777d278a3f5035-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":548,"real_height_2x":1097},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/c619ec92074347a3b4777d278a3f5035-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/c619ec92074347a3b4777d278a3f5035-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":548,"real_height_2x":1097}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"На следующем уроке мы научим нашего робота автоматически собирать спарсенные данные о госконтрактах в таблицу html.","type":"p","className":""}]},{"id":277,"header":"Пишем своего робота на Python. Урок 8","_path":"/workshops/2021/06/11/pishem-svoego-robota-na-python-urok-/","lead":"Учимся записывать ход работы робота, чтобы отслеживать ошибки, возникающие в наше отсутствие","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/20fe06515bac4bf49b7e7822c3e0c72f-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-06-11","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":13,"first_name":"Соня","last_name":"Савина","first_name_en":"Sonya","last_name_en":"Savina","is_public":true,"_path":"sonya-savina","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-896x504px_2x.webp","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-896x504px_2x.jpg","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-688x387px_2x.webp","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-688x387px_2x.jpg","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-416x234px_2x.webp","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-416x234px_2x.jpg","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-336x189px_2x.webp","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/a0e1983f65dd43929246814147e02504-336x189px_2x.jpg","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Если вы хотите рассказать мне свою историю, пишите на почту sonya.savina@istories.media.","lead_en":"","position":"Авторка","position_en":"Author","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Мы продолжаем писать робота, который собирает госконтракты и отправляет выборку на почту. Из прошлого выпуска вы узнали, как на этапе написания программы получить сообщение о том, что что-то в нашем коде пошло не так. Но давайте представим ситуацию, когда наш робот уже дописан и каждую неделю присылает нам на почту письмо с собранными контрактами. И вдруг в положенный день письмо не приходит – что-то сломалось. При этом, мы не можем круглосуточно дежурить у компьютера и следить за тем, как выполняется код и в каком месте возникла ошибка. В таких случаях спасает логирование.  \nЛогирование похоже на запись хода выполнения программы в журнал. Информация из него будет полезна для понимания того, что происходило с программой, когда нас не было рядом, и исправления проблем. Сегодня мы создадим такой лог-файл для нашего робота, но для начала рассмотрим принцип работы логирования на простом примере. Для этого создам чистый файл – logs.py. Импортируем библиотеку logging. Потом создадим простую конструкцию: напишем, что мы хотим сохранить логи в файл, дадим ему название и установим уровень логирования. \nЕсть несколько уровней логирования, здесь они перечислены в порядке возрастания значимости. Обычно чем больше информации в логах, тем легче понять, что случилось, но когда ее слишком много, разобраться бывает сложно. Поэтому придуманы разные уровни логирования в зависимости от того, насколько значимую информацию мы хотим сохранять. По умолчанию этот уровень WARNING – то есть в логах будут отображаться все сообщения этого уровня и выше (WARNING, ERROR, CRITICAL). Но его можно поменять, указав нужный в параметре level – давайте установим DEBUG – тогда будет записываться информация всех уровней. \n\nDEBUG – подробное и детальное логирование всей системной информации для последующего использования в отладке;\nINFO – подтверждение, информация о событиях, не приводящих к ошибкам в работе модулей;\nWARNING – информация о событиях, которые могут привести к ошибкам в работе модулей;\nERROR – информация об ошибках, возникших в работе модулей;\nCRITICAL – информация о критических ошибках, возникших в работе модулей.\n\nПосле этого для примера напишем простой код с делением на 0: попробуй разделить 10 на 0, а если не получится, если возникнет какая-то ошибка, выведи нам в файл сообщение об этой ошибке. \nВыполним этот код, и теперь у нас на компьютере появился простой файл, в котором содержится следующая информация: уровень сообщения (ERROR) и суть этой ошибки (деление на 0).\nЕсли мы хотим увидеть подробности, можно вместо error написать exception. Вот как в этом случае изменится информация в лог-файле. \nРегистрировать можно не только ошибки, но и удачные сценарии. Давайте разделим 10 на 10 и попросим напечатать в лог-файл результат. В этом случае мы используем не error или exception, а info. Устанавливать эти уровни в коде важно, чтобы потом не запутаться, в каком случаем это была ошибка, в каком просто информация. \nПерейдем к коду, который создает робота. Мы снова импортируем библиотеку logging и создаем файл с логами. Дадим ему имя, установим уровень DEBUG и отформатируем сообщение, которое будет выведено в логах. В примере, который я показывала, мы видели в лог-файле минимум информации. Теперь мы хотим сделать эту информацию более читаемой. Это делается с помощью format. В нем мы прописываем параметры, которые хотим видеть в сообщении: например время, когда действие выполнилось, уровень сообщения, название функции, которая выполняется в этот момент, и наше сообщение. Весь список этих атрибутов можно увидеть в документации библиотеки logging. \nДальше мы должны подумать, в какой части кода могут возникнуть ошибки. Давайте оставим нетронутыми наши вспомогательные функции, в которых вряд ли возникнут какие-то ошибки и перейдем к месту, где в теории может что-то сломаться – это наша главная функция get_contracts. Пропишем внутри нее информационное сообщение о том, что выполнение этой функции началось, а в части try – except попросим вывести в случае ошибки сообщение об этой ошибке. При удачном сценарии в лог-файле мы увидим следующую информацию: \nДавайте проверим, что будет, если подключиться не удастся, например, в случае отключения интернета. Тогда в лог-файле мы увидим, какая конкретно ошибка возникла: \nПо такому же принципу добавим логирование и в остальные части кода. Какая информация отобразится в логах при удачных и неудачных сценариях в этих случаях – смотрите в видео-версии этого урока. \nТеперь вы знаете принцип логирования выполнения программы в файл, дальше вы можете настроить его под себя и свои потребности, упростить или усложнить. Подробнее про библиотеку logging читайте в официальной документации.","blocks":[{"data":"Мы продолжаем писать робота, который собирает госконтракты и отправляет выборку на почту. Из прошлого <a href=\"https://istories.media/workshops/2021/06/05/pishem-svoego-robota-na-python-urok-7/\" data-type=\"usual\" target=\"_blank\">выпуска</a> вы узнали, как на этапе написания программы получить сообщение о том, что что-то в нашем коде пошло не так. Но давайте представим ситуацию, когда наш робот уже дописан и каждую неделю присылает нам на почту письмо с собранными контрактами. И вдруг в положенный день письмо не приходит – что-то сломалось. При этом, мы не можем круглосуточно дежурить у компьютера и следить за тем, как выполняется код и в каком месте возникла ошибка. В таких случаях спасает логирование.  ","type":"p","className":""},{"data":{"id":2505,"data":{"url":"https://www.youtube.com/embed/RyLESN51L-0","text":"Видео: Глеб Лиманский","caption":"","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=RyLESN51L-0","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Логирование похоже на запись хода выполнения программы в журнал. Информация из него будет полезна для понимания того, что происходило с программой, когда нас не было рядом, и исправления проблем. Сегодня мы создадим такой лог-файл для нашего робота, но для начала рассмотрим принцип работы логирования на простом примере. Для этого создам чистый файл – logs.py. Импортируем библиотеку logging. Потом создадим простую конструкцию: напишем, что мы хотим сохранить логи в файл, дадим ему название и установим уровень логирования. ","type":"p","className":""},{"data":{"id":2496,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e37d2fe2d26f46d198e10918051c9fb7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e37d2fe2d26f46d198e10918051c9fb7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":125,"real_height_2x":250},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e37d2fe2d26f46d198e10918051c9fb7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e37d2fe2d26f46d198e10918051c9fb7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":125,"real_height_2x":250}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Есть несколько уровней логирования, здесь они перечислены в порядке возрастания значимости. Обычно чем больше информации в логах, тем легче понять, что случилось, но когда ее слишком много, разобраться бывает сложно. Поэтому придуманы разные уровни логирования в зависимости от того, насколько значимую информацию мы хотим сохранять. По умолчанию этот уровень WARNING – то есть в логах будут отображаться все сообщения этого уровня и выше (WARNING, ERROR, CRITICAL).&nbsp;Но его можно поменять, указав нужный в параметре level –&nbsp;давайте установим DEBUG –&nbsp;тогда будет записываться информация всех уровней.&nbsp;","type":"p","className":""},{"data":"<li><strong>DEBUG </strong>–&nbsp;подробное и детальное логирование всей системной информации для последующего использования в отладке;</li><li><strong>INFO</strong> – подтверждение, информация о событиях, не приводящих к ошибкам в работе модулей;</li><li><strong>WARNING</strong> – информация о событиях, которые могут привести к ошибкам в работе модулей;</li><li><strong>ERROR</strong> – информация об ошибках, возникших в работе модулей;</li><li><strong>CRITICAL </strong>– информация о критических ошибках, возникших в работе модулей.</li>","type":"ul","className":""},{"data":"После этого для примера напишем простой код с делением на 0: попробуй разделить 10 на 0, а если не получится, если возникнет какая-то ошибка, выведи нам в файл сообщение об этой ошибке. ","type":"p","className":""},{"data":{"id":2497,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7cb7a5f4dc4346d1b028a9981cb3a3bd-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7cb7a5f4dc4346d1b028a9981cb3a3bd-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":222,"real_height_2x":444},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7cb7a5f4dc4346d1b028a9981cb3a3bd-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7cb7a5f4dc4346d1b028a9981cb3a3bd-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":222,"real_height_2x":444}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Выполним этот код, и теперь у нас на компьютере появился простой файл, в котором содержится следующая информация: уровень сообщения (ERROR) и суть этой ошибки (деление на 0).","type":"p","className":""},{"data":{"id":2498,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b07cc41297f7412a8597a660ed3c2107-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b07cc41297f7412a8597a660ed3c2107-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":204,"real_height_2x":408},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b07cc41297f7412a8597a660ed3c2107-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b07cc41297f7412a8597a660ed3c2107-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":204,"real_height_2x":408}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если мы хотим увидеть подробности, можно вместо error написать exception. Вот как в этом случае изменится информация в лог-файле. ","type":"p","className":""},{"data":{"id":2499,"data":{"images":[{"caption":"Код","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/14deb8ea18a843d08c4445f7e6bcdb9d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/14deb8ea18a843d08c4445f7e6bcdb9d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":220,"real_height_2x":440},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/14deb8ea18a843d08c4445f7e6bcdb9d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/14deb8ea18a843d08c4445f7e6bcdb9d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":220,"real_height_2x":440}]},{"caption":"Лог-файл","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/520925220a024dc9be32be04365b1a98-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/520925220a024dc9be32be04365b1a98-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":214,"real_height_2x":427},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/520925220a024dc9be32be04365b1a98-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/520925220a024dc9be32be04365b1a98-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":214,"real_height_2x":427}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Регистрировать можно не только ошибки, но и удачные сценарии. Давайте разделим 10 на 10 и попросим напечатать в лог-файл результат. В этом случае мы используем не error или exception, а info. Устанавливать эти уровни в коде важно, чтобы потом не запутаться, в каком случаем это была ошибка, в каком просто информация. ","type":"p","className":""},{"data":{"id":2500,"data":{"images":[{"caption":"Код","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/78adec493efd4b79b7ca7eb8031bddba-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/78adec493efd4b79b7ca7eb8031bddba-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":282,"real_height_2x":564},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/78adec493efd4b79b7ca7eb8031bddba-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/78adec493efd4b79b7ca7eb8031bddba-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":282,"real_height_2x":564}]},{"caption":"Лог-файл","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/41745a15568b48d9a7fa7595a1584e9d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/41745a15568b48d9a7fa7595a1584e9d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":150,"real_height_2x":300},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/41745a15568b48d9a7fa7595a1584e9d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/41745a15568b48d9a7fa7595a1584e9d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":150,"real_height_2x":300}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Перейдем к коду, который создает робота. Мы снова импортируем библиотеку logging и создаем файл с логами. Дадим ему имя, установим уровень DEBUG и отформатируем сообщение, которое будет выведено в логах. В примере, который я показывала, мы видели в лог-файле минимум информации. Теперь мы хотим сделать эту информацию более читаемой. Это делается с помощью format. В нем мы прописываем параметры, которые хотим видеть в сообщении: например время, когда действие выполнилось, уровень сообщения, название функции, которая выполняется в этот момент, и наше сообщение. Весь список этих атрибутов можно увидеть в <a href=\"https://docs.python.org/3/library/logging.html \" data-type=\"usual\" target=\"_blank\">документации</a> библиотеки logging. ","type":"p","className":""},{"data":{"id":2501,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2d8b5541ff9446119c92d808c27c5c6f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2d8b5541ff9446119c92d808c27c5c6f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":62,"real_height_2x":125},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2d8b5541ff9446119c92d808c27c5c6f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/2d8b5541ff9446119c92d808c27c5c6f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":62,"real_height_2x":125}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Дальше мы должны подумать, в какой части кода могут возникнуть ошибки. Давайте оставим нетронутыми наши вспомогательные функции, в которых вряд ли возникнут какие-то ошибки и перейдем к месту, где в теории может что-то сломаться –&nbsp;это наша главная функция get_contracts. Пропишем внутри нее информационное сообщение о том, что выполнение этой функции началось, а в части try – except попросим вывести в случае ошибки сообщение об этой ошибке. При удачном сценарии в лог-файле мы увидим следующую информацию: ","type":"p","className":""},{"data":{"id":2502,"data":{"images":[{"caption":"Код","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9bb7c62087b34a38990b08ac4ee4bb5b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9bb7c62087b34a38990b08ac4ee4bb5b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":424,"real_height_2x":848},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9bb7c62087b34a38990b08ac4ee4bb5b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9bb7c62087b34a38990b08ac4ee4bb5b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":424,"real_height_2x":848}]},{"caption":"Лог-файл","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d15e1e0890464b82b60a5669945ff74d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d15e1e0890464b82b60a5669945ff74d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":135,"real_height_2x":270},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/d15e1e0890464b82b60a5669945ff74d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/d15e1e0890464b82b60a5669945ff74d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":135,"real_height_2x":270}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Давайте проверим, что будет, если подключиться не удастся, например, в случае отключения интернета. Тогда в лог-файле мы увидим, какая конкретно ошибка возникла:&nbsp;","type":"p","className":""},{"data":{"id":2503,"data":{"images":[{"caption":"Отрывок информации из лог-файла в случае проблем с соединением","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4ff52418e87e49c690e77f3e6236876a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4ff52418e87e49c690e77f3e6236876a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":328,"real_height_2x":657},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4ff52418e87e49c690e77f3e6236876a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4ff52418e87e49c690e77f3e6236876a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":328,"real_height_2x":657}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"По такому же принципу добавим логирование и в остальные части кода. Какая информация отобразится в логах при удачных и неудачных сценариях в этих случаях – смотрите в видео-версии этого урока. ","type":"p","className":""},{"data":{"id":2504,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/0e64d06c297a4fa599a3c8334f3b79b5-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/0e64d06c297a4fa599a3c8334f3b79b5-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":806,"real_height_2x":1612},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/0e64d06c297a4fa599a3c8334f3b79b5-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/0e64d06c297a4fa599a3c8334f3b79b5-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":806,"real_height_2x":1612}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь вы знаете принцип логирования выполнения программы в файл, дальше вы можете настроить его под себя и свои потребности, упростить или усложнить. Подробнее про библиотеку logging читайте в официальной <a href=\"https://docs.python.org/3/library/logging.html\" data-type=\"usual\" target=\"_blank\">документации</a>.&nbsp;","type":"p","className":""}]},{"id":273,"header":"Пишем своего робота на Python. Урок 7","_path":"/workshops/2021/06/05/pishem-svoego-robota-na-python-urok-7/","lead":"Боремся с ошибками, которые могут сломать выполнение нашей функции","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/2dccd2549d9d4c698c9b2d4064fd5663-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-06-05","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Двигаемся дальше в разработке нашего робота по поиску госконтрактов. Тема сегодняшнего урока — ошибки. \n\n\nЕсли в нашем запросе будут указаны параметры, по которым ничего не находится, или сервис «ГосЗатрат» перестанет отвечать на запросы, мы получим ошибку — и тогда наш скрипт сломается. Чтобы этого избегать, мы будем применять синтаксис try-except. Давайте попробуем для начала воспроизвести ошибку.\n\n\nРазберемся, как не получать такие ошибки. С помощью нового условия как бы скажем нашей функции: попробуй сделать запрос (try), а если не получается (except), сделай что-то другое. Что именно? Например, можем вывести некоторое сообщение: «Что-то пошло не так!».\n\n\nС помощью этого синтаксиса можно прописывать конкретно, какой ошибки мы хотим избежать. Сейчас в нашем коде вне зависимости от ошибки мы получим сообщение «Что-то пошло не так!». Та ошибка, когда мы сами ввели неподходящее значение параметра, называется JSONDecodeError. \n\n\nЕсли мы добавим ее название в условие, а вылетит какая-то другая — наша функция снова сломается. В этот раз мы оставим уточнение, чтобы в дальнейшем иметь возможность отследить другие ошибки и решить, как с ними поступить.","blocks":[{"data":"Двигаемся дальше в разработке нашего робота по поиску госконтрактов. Тема сегодняшнего урока — ошибки. ","type":"p","className":""},{"data":{"id":2462,"data":{"url":"https://www.youtube.com/embed/xlbZyRdg62Y","text":"Видео: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=xlbZyRdg62Y","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Если в нашем запросе будут указаны параметры, по которым ничего не находится, или сервис «ГосЗатрат»&nbsp;перестанет отвечать на запросы, мы получим ошибку — и тогда наш скрипт сломается. Чтобы этого избегать, мы будем применять синтаксис <strong>try-except</strong>. Давайте попробуем для начала воспроизвести ошибку.","type":"p","className":""},{"data":{"id":2459,"data":{"images":[{"credit":"Меняем год в запросе на еще не наступивший 2022...","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1ce8bb350fa84fc99bfa3c83970bc81d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1ce8bb350fa84fc99bfa3c83970bc81d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":296,"real_height_2x":592},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1ce8bb350fa84fc99bfa3c83970bc81d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1ce8bb350fa84fc99bfa3c83970bc81d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":296,"real_height_2x":592}]},{"credit":"...и код ломается","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2d7eb0765d8a4b319cf348e07eb8ebf7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2d7eb0765d8a4b319cf348e07eb8ebf7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":340,"real_height_2x":680},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2d7eb0765d8a4b319cf348e07eb8ebf7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/2d7eb0765d8a4b319cf348e07eb8ebf7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":340,"real_height_2x":680}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Разберемся, как не получать такие ошибки. С помощью нового условия как бы скажем нашей функции: попробуй сделать запрос (<strong>try</strong>), а если не получается (<strong>except</strong>), сделай что-то другое. Что именно? Например, можем вывести некоторое сообщение: «Что-то пошло не так!».","type":"p","className":""},{"data":{"id":2460,"data":{"images":[{"credit":"Теперь, если наше условие будет выполняться без ошибок, мы получим нужный результат... ","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/664724f3953247bdb1f57904edafde87-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/664724f3953247bdb1f57904edafde87-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":427,"real_height_2x":854},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/664724f3953247bdb1f57904edafde87-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/664724f3953247bdb1f57904edafde87-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":427,"real_height_2x":854}]},{"credit":"...а если не будет — получим сообщение об ошибке","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ee13b5a97f0a417896619b6feea826fe-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ee13b5a97f0a417896619b6feea826fe-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":355,"real_height_2x":710},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ee13b5a97f0a417896619b6feea826fe-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ee13b5a97f0a417896619b6feea826fe-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":355,"real_height_2x":710}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"С помощью этого синтаксиса можно прописывать конкретно, какой ошибки мы хотим избежать. Сейчас в нашем коде вне зависимости от ошибки мы получим сообщение «Что-то пошло не так!». Та ошибка, когда мы сами ввели неподходящее значение параметра, называется <strong>JSONDecodeError</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2461,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f94af2e028034070ad00eb8e6a1ec387-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f94af2e028034070ad00eb8e6a1ec387-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":402,"real_height_2x":804},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f94af2e028034070ad00eb8e6a1ec387-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f94af2e028034070ad00eb8e6a1ec387-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":402,"real_height_2x":804}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если мы добавим ее название в условие, а вылетит какая-то другая — наша функция снова сломается. В этот раз мы оставим уточнение, чтобы в дальнейшем иметь возможность отследить другие ошибки и решить, как с ними поступить. ","type":"p","className":""}]},{"id":269,"header":"Пишем своего робота на Python. Урок 6","_path":"/workshops/2021/05/28/pishem-svoego-robota-na-python-urok-6/","lead":"Получаем контракты за конкретный промежуток времени с помощью библиотеки datetime","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/9d8f05816dd94912b4880523c8610f83-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-05-28","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Продолжаем писать робота, который собирает интересующие нас госконтракты и отправляет их на почту. Сегодня мы поговорим о важной библиотеке datetime. По ее названию понятно, что она предназначена для работы с временем и датами. \n\n\nОна пригодится нам, чтобы мы могли передавать в нашу функцию такой аргумент как daterange. С его помощью мы сможем выделять определенный промежуток времени, за который хотим получить контракты. Сегодня напишем функцию, которая будет возвращать нам промежуток в виде недели — либо автоматически от сегодняшнего числа, либо от того, которое вам необходимо.\n\nДля начала импортируем библиотеку datetime, введя from datetime import timedelta, date и на время закомментируем нашу функцию с помощью \"\"\".\n\n\nНазовем новую функцию get_week. Это будет функция с необязательным аргументом: если мы хотим выбрать конкретную дату и отсчитать от нее неделю назад, мы можем вписать дату; если же просто хотим получить отсчет на неделю назад от сегодняшнего числа, дату писать не нужно. Для этого укажем необязательный аргумент day, который по умолчанию будет None.\n\n\nДальше пропишем условие, чтобы разобраться с датой отсчета — мы хотим получить сегодняшнее число автоматически, если day будет равен None. Поэтому start_date зададим как раз с помощью библиотеки datetime.\n\nЧтобы мы могли указать какую-то дату на входе нашей функции, нам нужно перевести ее в формат библиотеки datetime, то есть, сделать дату объектом библиотеки. Для этого используем функцию strptime, которая на вход получает число, распознает его формат и делает его понятным для библиотеки. В нашем случае формат будет ДД.ММ.ГГ.\n\n\nТеперь, когда у нас есть точка отсчета, нам нужно отсчитать от нее ровно неделю. Для этого применим функцию timedelta. Создаем переменную end_date и вычитаем из start_date неделю, указывая промежуток weeks=1 в функции timedelta. Могут быть указаны и минуты, и годы, если это необходимо для какой-то задачи.\n\n\nМы получили конечную дату и можем посмотреть в документации к API «ГосЗатрат», как должна выглядеть строчка с датами, которую мы должны передать нашей главной функции (той, что мы закомментировали в начале урока). \n\n\nСделаем по образцу. Назовем переменную date_range и воспользуемся методом f-строк, чтобы поместить внутрь фигурных скобок любые параметры, которые нам нужны. Сегодня это будут start_date и end_date, разделенные дефисом. \n\nЗапустим get_week и посмотрим, что она вернет нам. В примере не будем указывать число — то есть, отсчет будет от дня записи этого урока.\n\n\nКак видите, даты нам вернулись, но не в том формате, который просит API «ГосЗатрат» — нужно поменять местами дни, месяцы и годы. Для этого воспользуемся еще одной функцией библиотеки datetime — strftime — и добавим нужный формат в f-строку. Попробуем запустить функцию еще раз.\n\n\nПолучилось, наша функция вернула даты в нужном формате. Теперь можем раскомментировать нашу основную функцию get_contracts_by_region. Пора бы ее переименовать в просто get_contracts, ведь мы уже знаем, что можем получать контракты по любым поисковым параметрам. Перенесем сегодняшнюю функцию get_week наверх и продолжим.\n\n\nВместо supplierinn в запросе get_contracts укажем date_range и добавим значение из функции get_week. И поменяем еще кое-что — поскольку мы отсчитываем неделю назад, в f-строке функции get_week нужно поменять местами start_date и end_date. \n\n\nПора проверить, как отработает наша функция. Передадим в функцию get_contracts временной промежуток в виде недели от дня записи урока и увидим в терминале, что параметр signDate вписывается в указанный нами временной промежуток.\n\n\nИ напоследок узнаем, как отработает функция, если указать ей конкретную дату, от которой нужно отсчитать неделю — пусть это будет 1 мая 2021 года. Если вы все сделали по инструкции, то параметр signDate впишется в неделю до 1 мая.\n\n\nСегодня мы научились брать даты в виде строчки, делать их объектом библиотеки, отсчитывать временные шаги вперед или назад и использовать эти знания для нашего будущего робота (представляете, мы уже почти дописали его!). Как всегда, ждем ваши вопросы в нашем чате в Telegram.","blocks":[{"data":"Продолжаем писать робота, который собирает интересующие нас госконтракты и отправляет их на почту. Сегодня мы поговорим о важной библиотеке <strong>datetime</strong>. По ее названию понятно, что она предназначена для работы с временем и датами.&nbsp;","type":"p","className":""},{"data":{"id":2463,"data":{"url":"https://www.youtube.com/embed/mcs57WnCF84","text":"Видео: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=mcs57WnCF84&t=8s","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Она пригодится нам, чтобы мы могли передавать в нашу функцию такой аргумент как <strong>daterange</strong>. С его помощью мы сможем выделять определенный промежуток времени, за который хотим получить контракты. Сегодня напишем функцию, которая будет возвращать нам промежуток в виде недели — либо автоматически от сегодняшнего числа, либо от того, которое вам необходимо.","type":"p","className":""},{"data":"Для начала импортируем библиотеку <strong>datetime</strong>, введя <strong>from datetime import timedelta, date</strong> и на время закомментируем нашу функцию с помощью <strong>\"\"\"</strong>.","type":"p","className":""},{"data":{"id":2420,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/64da19e4dcd74496b389a05e9357c6a5-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/64da19e4dcd74496b389a05e9357c6a5-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":738,"real_height_2x":1477},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/64da19e4dcd74496b389a05e9357c6a5-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/64da19e4dcd74496b389a05e9357c6a5-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":738,"real_height_2x":1477}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Назовем новую функцию <strong>get_week</strong>. Это будет функция с необязательным аргументом: если мы хотим выбрать конкретную дату и отсчитать от нее неделю назад, мы можем вписать дату; если же просто хотим получить отсчет на неделю назад от сегодняшнего числа, дату писать не нужно. Для этого укажем необязательный аргумент <strong>day</strong>, который по умолчанию будет <strong>None</strong>.","type":"p","className":""},{"data":{"id":2421,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4a18598b09e646aba5a44813c8ef9c55-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4a18598b09e646aba5a44813c8ef9c55-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":819,"real_height_2x":1638},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4a18598b09e646aba5a44813c8ef9c55-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4a18598b09e646aba5a44813c8ef9c55-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":819,"real_height_2x":1638}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Дальше пропишем условие, чтобы разобраться с датой отсчета — мы хотим получить сегодняшнее число автоматически, если <strong>day</strong> будет равен <strong>None</strong>. Поэтому <strong>start_date</strong> зададим как раз с помощью библиотеки <strong>datetime</strong>.","type":"p","className":""},{"data":"Чтобы мы могли указать какую-то дату на входе нашей функции, нам нужно перевести ее в формат библиотеки <strong>datetime</strong>, то есть, сделать дату объектом библиотеки. Для этого используем функцию <strong>strptime</strong>, которая на вход получает число, распознает его формат и делает его понятным для библиотеки. В нашем случае формат будет ДД.ММ.ГГ.","type":"p","className":""},{"data":{"id":2422,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/89c36ae246c843d29f0a95f7fd12eaec-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/89c36ae246c843d29f0a95f7fd12eaec-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":274,"real_height_2x":549},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/89c36ae246c843d29f0a95f7fd12eaec-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/89c36ae246c843d29f0a95f7fd12eaec-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":274,"real_height_2x":549}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь, когда у нас есть точка отсчета, нам нужно отсчитать от нее ровно неделю. Для этого применим функцию <strong>timedelta</strong>. Создаем переменную <strong>end_date</strong> и вычитаем из <strong>start_date</strong> неделю, указывая промежуток <strong>weeks=1</strong> в функции <strong>timedelta</strong>. Могут быть указаны и минуты, и годы, если это необходимо для какой-то задачи.","type":"p","className":""},{"data":{"id":2423,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a55246472ab842738b32b16a00d7dab8-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a55246472ab842738b32b16a00d7dab8-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":463,"real_height_2x":926},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a55246472ab842738b32b16a00d7dab8-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a55246472ab842738b32b16a00d7dab8-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":463,"real_height_2x":926}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы получили конечную дату и можем посмотреть в <a href=\"https://github.com/clearspending/clearspending-examples/wiki\" data-type=\"usual\" target=\"_blank\">документации</a> к API «ГосЗатрат», как должна выглядеть строчка с датами, которую мы должны передать нашей главной функции (той, что мы закомментировали в начале урока).&nbsp;","type":"p","className":""},{"data":{"id":2424,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c7e8ea39d66446d383dcad807eb573d6-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c7e8ea39d66446d383dcad807eb573d6-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":576,"real_height_2x":1152},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/c7e8ea39d66446d383dcad807eb573d6-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/c7e8ea39d66446d383dcad807eb573d6-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":576,"real_height_2x":1152}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Сделаем по образцу. Назовем переменную <strong>date_range</strong> и воспользуемся <a href=\"https://istories.media/workshops/2020/11/18/vvedenie-v-python-chast-3/\" data-type=\"usual\" target=\"_blank\">методом f-строк</a>, чтобы поместить внутрь фигурных скобок любые параметры, которые нам нужны. Сегодня это будут <strong>start_date</strong> и <strong>end_date</strong>, разделенные дефисом.&nbsp;","type":"p","className":""},{"data":"Запустим <strong>get_week</strong> и посмотрим, что она вернет нам. В примере не будем указывать число — то есть, отсчет будет от дня записи этого урока.","type":"p","className":""},{"data":{"id":2425,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ac35735971324dc5939959ca7e448551-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ac35735971324dc5939959ca7e448551-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":555,"real_height_2x":1110},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ac35735971324dc5939959ca7e448551-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ac35735971324dc5939959ca7e448551-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":555,"real_height_2x":1110}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Как видите, даты нам вернулись, но не в том формате, который просит API «ГосЗатрат» — нужно поменять местами дни, месяцы и годы. Для этого воспользуемся еще одной функцией библиотеки <strong>datetime</strong> —&nbsp;<strong>strftime</strong> —&nbsp;и добавим нужный формат в <strong>f</strong>-строку. Попробуем запустить функцию еще раз.","type":"p","className":""},{"data":{"id":2426,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f61474cb5b7a4008893ff7312b67df4c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f61474cb5b7a4008893ff7312b67df4c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":564,"real_height_2x":1130},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f61474cb5b7a4008893ff7312b67df4c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f61474cb5b7a4008893ff7312b67df4c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":564,"real_height_2x":1130}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Получилось, наша функция вернула даты в нужном формате. Теперь можем раскомментировать нашу основную функцию <strong>get_contracts_by_region</strong>. Пора бы ее переименовать в просто <strong>get_contracts</strong>, ведь мы уже знаем, что можем получать контракты по любым поисковым параметрам. Перенесем сегодняшнюю функцию <strong>get_week</strong> наверх и продолжим.","type":"p","className":""},{"data":{"id":2427,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/22c965de127144b8be04d0ff077bd96d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/22c965de127144b8be04d0ff077bd96d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":502,"real_height_2x":1003},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/22c965de127144b8be04d0ff077bd96d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/22c965de127144b8be04d0ff077bd96d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":502,"real_height_2x":1003}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Вместо <strong>supplierinn</strong> в запросе <strong>get_contracts</strong> укажем <strong>date_range</strong> и добавим значение из функции <strong>get_week</strong>. И поменяем еще кое-что — поскольку мы отсчитываем неделю назад, в <strong>f</strong>-строке функции <strong>get_week</strong> нужно поменять местами <strong>start_date</strong> и <strong>end_date</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2428,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3bc9e0e56fc947edba313f6d3f9fbfb1-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3bc9e0e56fc947edba313f6d3f9fbfb1-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":398,"real_height_2x":797},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3bc9e0e56fc947edba313f6d3f9fbfb1-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3bc9e0e56fc947edba313f6d3f9fbfb1-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":398,"real_height_2x":797}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Пора проверить, как отработает наша функция. Передадим в функцию <strong>get_contracts</strong> временной промежуток в виде недели от дня записи урока и увидим в терминале, что параметр signDate вписывается в указанный нами временной промежуток.","type":"p","className":""},{"data":{"id":2429,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b6ca3535045442faacf9a58738387617-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b6ca3535045442faacf9a58738387617-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":536,"real_height_2x":1072},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b6ca3535045442faacf9a58738387617-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b6ca3535045442faacf9a58738387617-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":536,"real_height_2x":1072}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"И напоследок узнаем, как отработает функция, если указать ей конкретную дату, от которой нужно отсчитать неделю — пусть это будет 1 мая 2021 года. Если вы все сделали по инструкции, то параметр signDate впишется в неделю до 1 мая.","type":"p","className":""},{"data":{"id":2430,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9d77552d4c364815aef277c3e08d5557-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9d77552d4c364815aef277c3e08d5557-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":537,"real_height_2x":1074},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9d77552d4c364815aef277c3e08d5557-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9d77552d4c364815aef277c3e08d5557-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":537,"real_height_2x":1074}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Сегодня мы научились брать даты в виде строчки, делать их объектом библиотеки, отсчитывать временные шаги вперед или назад и использовать эти знания для нашего будущего робота (представляете, мы уже почти дописали его!). Как всегда, ждем ваши вопросы в нашем <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">чате</a> в Telegram.","type":"p","className":""}]},{"id":266,"header":"Пишем своего робота на Python. Урок 5","_path":"/workshops/2021/05/21/pishem-svoego-robota-na-python-urok-5/","lead":"Улучшаем функцию, которая делает запросы к API","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/7a2584790d254c62997eca95d0bbfcd8-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-05-21","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Продолжаем писать робота, который будет присылать нам на почту подборку госконтрактов. Сегодня мы будем совершенствовать функцию, которая делает запрос к API сервиса «ГосЗатраты». Как всегда, начинаем с открытия проект и запуска виртуального окружения с помощью pipenv shell. \nСейчас наша функция получения данных устроена таким образом, что принимает на вход код региона заказчика, подставляет его в запрос, и мы получаем выдачу госконтрактов. Но если мы посмотрим в документацию к API, то увидим, что опций, которые можно использовать для запроса, гораздо больше. Предугадать эти опции в нашей функции невозможно, поэтому мы будем использовать именованные аргументы, сокращенно kwargs. С их помощью мы сможем передавать любой из этих параметров в нашу функцию, по ним будет составляться запрос и формироваться наша выдача.\n\nПерепишем функцию: удалим из строчки url запрос customerregion, а region_code заменим на именованные аргументы, используя двойную звездочку ** и слово kwargs. Когда мы будем вызывать эту функцию, вместо kwargs будем указывать нужные аргументы, которые хотим добавить в url, .\n\n\nС помощью этого синтаксиса мы можем передавать в нашу функцию переменное количество аргументов. Чтобы использовать их, введем переменную params, где распакуем наши именованные аргументы. Теперь, когда мы будем отправлять запрос к серверу «ГосЗатрат», мы должны указать в data не только url, но и params.\n\n\nПроверим, как это работает. Например, мы хотим получить все исполненные контракты, где поставщиком выступала компания Игоря Ротенберга. Таким образом, у нас есть два параметра: supplierinn и currentstage с выбранным правильным значением.\n\n\nДобавляем в result желаемый supplierinn и currentstage, после чего запускаем функцию — и получаем в терминале ровно то, что нам было нужно. \n\n\nТеперь наша функция выглядит универсально — мы можем подавать ей на вход любые доступные параметры поиска. Появятся вопросы — не стесняйтесь задавать их в нашем чате в Telegram.","blocks":[{"data":"Продолжаем писать робота, который будет присылать нам на почту подборку госконтрактов. Сегодня мы будем совершенствовать функцию, которая делает запрос к API сервиса «ГосЗатраты». Как всегда, начинаем с открытия проект и запуска виртуального окружения с помощью <strong>pipenv shell</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2464,"data":{"url":"https://www.youtube.com/embed/yYpYzQD1bJo","text":"Видео: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=yYpYzQD1bJo","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Сейчас наша функция получения данных устроена таким образом, что принимает на вход код региона заказчика, подставляет его в запрос, и мы получаем выдачу госконтрактов. Но если мы посмотрим в <a href=\"https://github.com/clearspending/clearspending-examples/wiki\" data-type=\"usual\" target=\"_blank\">документацию к API</a>, то увидим, что опций, которые можно использовать для запроса, гораздо больше. Предугадать эти опции в нашей функции невозможно, поэтому мы будем использовать именованные аргументы, сокращенно kwargs. С их помощью мы сможем передавать любой из этих параметров в нашу функцию, по ним будет составляться запрос и формироваться наша выдача.","type":"p","className":""},{"data":"Перепишем функцию: удалим из строчки <strong>url</strong> запрос <strong>customerregion</strong>, а <strong>region_code</strong> заменим на именованные аргументы, используя двойную звездочку <strong>**</strong> и слово <strong>kwargs</strong>. Когда мы будем вызывать эту функцию, вместо <strong>kwargs</strong> будем указывать нужные аргументы, которые хотим добавить в <strong>url</strong>, .","type":"p","className":""},{"data":{"id":2394,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/282db72c44fc4ca89dae7a4f4215eb07-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/282db72c44fc4ca89dae7a4f4215eb07-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":579,"real_height_2x":1158},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/282db72c44fc4ca89dae7a4f4215eb07-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/282db72c44fc4ca89dae7a4f4215eb07-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":579,"real_height_2x":1158}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"С помощью этого синтаксиса мы можем передавать в нашу функцию переменное количество аргументов. Чтобы использовать их, введем переменную <strong>params</strong>, где распакуем наши именованные аргументы. Теперь, когда мы будем отправлять запрос к серверу «ГосЗатрат», мы должны указать в <strong>data</strong> не только <strong>url</strong>, но и <strong>params</strong>.","type":"p","className":""},{"data":{"id":2395,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/316245c73eb1471eaee7503cfd3401c2-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/316245c73eb1471eaee7503cfd3401c2-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":434,"real_height_2x":868},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/316245c73eb1471eaee7503cfd3401c2-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/316245c73eb1471eaee7503cfd3401c2-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":434,"real_height_2x":868}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Проверим, как это работает. Например, мы хотим получить все исполненные контракты, где поставщиком выступала компания Игоря Ротенберга. Таким образом, у нас есть два параметра: <strong>supplierinn</strong> и <strong>currentstage</strong> с выбранным правильным значением.","type":"p","className":""},{"data":{"id":2393,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/03a03794954c45a288e9fe1a99a5c084-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/03a03794954c45a288e9fe1a99a5c084-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1396,"real_height_2x":2791},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/03a03794954c45a288e9fe1a99a5c084-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/03a03794954c45a288e9fe1a99a5c084-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":1396,"real_height_2x":2791}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Добавляем в <strong>result</strong> желаемый <strong>supplierinn</strong> и <strong>currentstage</strong>, после чего запускаем функцию —&nbsp;и получаем в терминале ровно то, что нам было нужно.&nbsp;","type":"p","className":""},{"data":{"id":2396,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/98a784ff07fa47bea028b3eae0c88a99-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/98a784ff07fa47bea028b3eae0c88a99-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":690,"real_height_2x":1381},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/98a784ff07fa47bea028b3eae0c88a99-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/98a784ff07fa47bea028b3eae0c88a99-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":690,"real_height_2x":1381}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь наша функция выглядит универсально — мы можем подавать ей на вход любые доступные параметры поиска. Появятся вопросы — не стесняйтесь задавать их в нашем <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">чате</a> в Telegram.","type":"p","className":""}]},{"id":263,"header":"Расчет расстояния между геокоординатами","_path":"/workshops/2021/05/14/raschet-rasstoyaniya-mezhdu-geokoordinatami/","lead":"Вычисляем расстояния между объектами по координатам по прямой. Считаем дистанцию от населенных пунктов до школ и выбираем ближайшую школу","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/8d03205ba2db401aaadd648864915eb4-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"Фото: Goya60 / Flickr (CC BY-NC-ND 2.0)","created_at_date":"2021-05-14","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":2517,"last_name":"","first_name":"Редакция","last_name_en":"","first_name_en":"Editors","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"У «Важных историй» вышел текст о том, как в 2021 году минимум 100 тысяч российских детей с трудом добираются до школ. Для части этого небольшого исследования мы считали радиусы доступности, то есть сколько километров от каждого населенного пункта России до ближайшей школы. \nВ этом уроке расскажем, как посчитать расстояния между объектами по прямой и затем выбирать ближайшие. \n\nВажно, что расстояния в этом уроке считаются без учета дорог и естественных преград в виде гор, рек, болот и пр., поэтому дают общее представление о дальности объектов. Чтобы точно рассчитать дистанцию и время в пути по дорогам, можно воспользоваться API матрицы расстояний Яндекс.Карт (платно, либо можно попробовать попросить бесплатно в исследовательских и научных целях по индивидуальному запросу) или OSRM — Open Source Routing Machine (бесплатно).\n\nJupyter ноутбук с уроком доступен на странице Мастерской на GitHub.\n1. Скачивание данных\nНам нужно два набора данных — с населенными пунктами и со школами. \n1. Данные по населенным пунктам скачиваем на сайте ИНИД (Инфраструктура научно-исследовательских данных).\n2. Данные по школам — с помощью парсинга с сайта https://schoolotzyv.ru/schools/9-russia/ (скачанные данные доступны в формате json по ссылке). По некоторым регионам на сайте есть не все школы. Можно дополнить данными с сайтов https://arhangelsk.fulledu.ru/, https://russiaedu.ru/, набора открытых данных с лицензиями Рособрнадзора (требуется парсинг xml) и других источников.\n2. Загрузка библиотек\nЗагружаем 4 библиотеки: pandas для работы с датафреймами — данными в табличном виде, numpy и scikit-learn для математических операций, json для работы с файлами в формате json.\n3. Загрузка и подготовка данных\nДатасет со школами в формате json. Загружаем его в Pandas. В нем более 50 тысяч строк.\nВ файле есть геокоординаты (широта, долгота), ссылка на школу и ее название. Наименований регионов нет, а нам желательно для примера выбрать только один регион, иначе, если оставить всю Россию, это будет очень долго считаться. Регион можно узнать из ссылки. Например, в строке с индексом 1 школа из Камчатского края: в ссылке есть фрагмент «131-kamchatskij». \nВыберем, например, Нижегородскую область. В ссылках она помечена как «146-nizhegorodskaya». С помощью метода contains («содержит»), выберем только те ссылки, в которых есть эта запись. Так у нас останутся только школы Нижегородской области. Подробнее о том, как фильтровать датафреймы — в первом уроке по Pandas. \nПоскольку мы выбрали только некоторые строки, индексы датафрейма сбились и теперь идут не сначала: \nЧтобы индексы сбросились и снова начинались с нуля, обновим их методом reset_index(). Drop = True означает, что старые индексы нам не нужны.\nДалее загружаем файл с населенными пунктами. В нем есть регион, район, название, численность населения, сколько в них детей, координаты, код ОКТМО (Общероссийского классификатора территорий муниципальных образований).\nВыберем тоже только Нижегородскую область, а чтобы все еще быстрее считалось, возьмем только один район, например, Воскресенский.\nСнова обновляем индексы, чтобы шли с нуля. \n4. Создание словарей\nПрежде чем считать расстояния, нам понадобится создать два словаря — с населенными пунктами и со школами. Это нужно, чтобы в дальнейшем мы могли сопоставить разные датафреймы по какому-то уникальному параметру, доставать и добавлять нужные нам данные. Нам это пригодится на последних этапах. \n\nДля населенных пунктов таким уникальным параметром, по которому можно будет объединять разные датафреймы, станет код ОКТМО (Общероссийского классификатора территорий муниципальных образований).\n\nПеред этим нам нужно убедиться, что: \n1) Во всех нужных нам столбцах указан правильный тип данных.\n2) Удалены дубликаты в тех столбцах, которые будут уникальным ключом для словаря (для населенных пунктов это поле oktmo, для школ — url), поскольку ключи словаря не должны дублироваться.\n\nСмотрим методом dtype, какой тип данных в столбце oktmo. Это float, число с плавающей точкой. \nУдобнее будет в качестве уникального кода работать со строками, а не числами, поэтому поменяем тип данных сначала на integer, затем на string.\nСмотрим, есть ли в столбце oktmo дубликаты. \nУдаляем дубликаты и обновляем индексы.\nCобираем датафрейм с населенными пунктами в словарь, где ключом будет код ОКТМО, а значением — строка с информацией о соответствующем населенном пункте. Сначала мы создаем пустой словарь. Затем переменной i проходимся по всем индексам от 0 до последнего в нашем датафрейме. В переменную el записываем строку, которую получаем методом loc. \nПереходим к датафрейму со школами. Сначала меняем тип данных в столбцах с широтой и долгой, потому что сейчас там строки, а нам для расчетов нужны числа (float).\nУдаляем дубликаты и обновляем индексы.\nИ теперь для школ собираем такой же словарь, как и для населенных пунктов. Ключом будет url.\n5. Расчет матрицы расстояний\nПереходим к расчету расстояний между каждым населенным пунктом и каждой школой (матрица расстояний). За основу взят туториал Dana Lindquist.\nСначала переводим координаты из градусов в радианы, потому что математические формулы обычно требуют значения координат в радианах, а не в градусах. Делаем это с помощью библиотеки numpy.\nДалее считаем расстояния с помощью формулы из библиотеки scikit-learn. Эта формула вычисляет гаверсинусное расстояние, то есть представляет форму Земли как идеальную сферу (а не геоид, как на самом деле) и за счет этого обеспечивает быстрые вычисления. Если требуется измерение в километрах, то  в конце формулы нужно умоножать 6371, если в милях — на 3959. Мы получим расстояния от каждого населенного пункта до каждой школы в километрах.\nСтроим матрицу расстояний — таблицу, в которой индексами будут url школ, колонками - ОКТМО населенных пунктов, а в ячейках будет расстояние.\nНо нам нужно расстояние от населенных пунктов до школ, а не наоборот, поэтому транспонируем таблицу — поменяем индексы и колонки местами.\n6. Выбор ближайшего объекта\nВыбираем ближайшую школу к каждому населенному пункту. Для этого сравниваем каждое значение в строке с предыдущим, чтобы проверить, больше оно или меньше. Меньшее записываем в переменную. Так проходим циклом по каждой строке, выбирая самое меньшее значение. И создаем словарь, в котором ключ — код ОКТМО населенного пункта, значения — url ближайшей школы и расстояние до нее.\nДалее добавляем колонки с минимальным расстоянием и url школы в датафрейм places_voskresensk (с населенными пунктами). Для этого берем из созданного выше словаря schools_and_min_value_by_oktmo ссылку (url) и расстояние до школы (distns). Добавляем их в словари school_url_column и min_distance_column в том порядке, в каком соответствующие им коды ОКТМО расположены в датафрейме places_voskresensk. И добавляем соответствующие новые колонки к датафрейму.\nТочно так же из словаря со школами достаем название школ и добавляем их к датафрейму.\nВ конце появились 3 новые колонки — url ближайшей школы, сколько до нее километров по прямой, название школы. \nСохраним полученный результат в csv. \n7. Анализ данных\nДальше мы можем анализировать данные. Например, выбрать 15 наиболее удаленных от школ населенных пунктов методом nlarest. Подробнее об nlargest и nsmallest — в 3 уроке по Pandas. \nПолучили топ самых удаленных населенных пунктов. Или можем посчитать, сколько детей в Воскресенском районе Нижегородской области живут дальше 5 км от школы.\nИли среднее расстояние от населенного пункта до школы.\nГотово!","blocks":[{"data":"У «Важных историй» вышел <a href=\"https://istories.media/reportages/2021/05/15/esli-nikto-iz-vzroslikh-ne-protoptal-deti-idut-po-sugrobam-v-shkolu/\" data-type=\"usual\" target=\"_blank\">текст</a> о том, как в 2021 году минимум 100 тысяч российских детей с трудом добираются до школ. Для части этого небольшого исследования мы считали радиусы доступности, то есть сколько километров от каждого населенного пункта России до ближайшей школы. ","type":"p","className":""},{"data":"В этом уроке расскажем, как посчитать расстояния между объектами по прямой и затем выбирать ближайшие. ","type":"p","className":""},{"data":"Важно, что расстояния в этом уроке считаются без учета дорог и естественных преград в виде гор, рек, болот и пр., поэтому дают общее представление о дальности объектов. Чтобы точно рассчитать дистанцию и время в пути по дорогам, можно воспользоваться API матрицы расстояний Яндекс.Карт (платно, либо можно попробовать попросить бесплатно в исследовательских и научных целях по индивидуальному запросу) или OSRM — Open Source Routing Machine (бесплатно).","type":"p","className":""},{"data":"Jupyter ноутбук с уроком доступен на <a href=\"https://github.com/iStoriesMedia/python_lessons\" data-type=\"usual\" target=\"_blank\">странице</a> Мастерской на GitHub.","type":"p","className":""},{"data":{"id":2361,"data":{"url":"https://www.youtube.com/embed/PNL8hdy3TIM","text":"Видео: Глеб Лиманский","caption":"","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=PNL8hdy3TIM","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"1. Скачивание данных","type":"h2","className":""},{"data":"Нам нужно два набора данных — с населенными пунктами и со школами. ","type":"p","className":""},{"data":"1. Данные по населенным пунктам скачиваем на сайте <a href=\"https://www.data-in.ru/data-catalog/datasets/160/\" data-type=\"usual\" target=\"_blank\">ИНИД</a> (Инфраструктура научно-исследовательских данных).","type":"p","className":""},{"data":"2. Данные по школам — с помощью парсинга с сайта&nbsp;<a href=\"https://schoolotzyv.ru/schools/9-russia/\" data-type=\"usual\" target=\"_blank\">https://schoolotzyv.ru/schools/9-russia/</a>&nbsp;(скачанные данные доступны в формате json по <a href=\"https://drive.google.com/file/d/18PQTD4upgjS-zfcPgKWEj1_zWJz7RL64/view?usp=sharing\" data-type=\"usual\" target=\"_blank\">ссылке</a>). По некоторым регионам на сайте есть не все школы. Можно дополнить данными с сайтов&nbsp;<a href=\"https://arhangelsk.fulledu.ru/\" data-type=\"usual\" target=\"_blank\">https://arhangelsk.fulledu.ru/</a>,&nbsp;<a href=\"https://russiaedu.ru/\" data-type=\"usual\" target=\"_blank\">https://russiaedu.ru/</a>, набора открытых данных с лицензиями <a href=\"http://obrnadzor.gov.ru/otkrytoe-pravitelstvo/opendata/7701537808-fbdrl/\" data-type=\"usual\" target=\"_blank\">Рособрнадзора</a> (требуется парсинг xml)&nbsp;и других источников.","type":"p","className":""},{"data":"2. Загрузка библиотек","type":"h2","className":""},{"data":"Загружаем 4 библиотеки: pandas для работы с датафреймами — данными в табличном виде, numpy и scikit-learn для математических операций, json для работы с файлами в формате json.","type":"p","className":""},{"data":{"id":2320,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/76a1f989cd724c419980175f24601c25-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/76a1f989cd724c419980175f24601c25-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":114,"real_height_2x":229},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/76a1f989cd724c419980175f24601c25-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/76a1f989cd724c419980175f24601c25-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":114,"real_height_2x":229}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"3. Загрузка и подготовка данных","type":"h2","className":""},{"data":"Датасет со школами в формате json. Загружаем его в Pandas. В нем более 50 тысяч строк.","type":"p","className":""},{"data":{"id":2362,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7f446eb3f7824921a70c33893e830770-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7f446eb3f7824921a70c33893e830770-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":342,"real_height_2x":684},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7f446eb3f7824921a70c33893e830770-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7f446eb3f7824921a70c33893e830770-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":342,"real_height_2x":684}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В файле есть геокоординаты (широта, долгота), ссылка на школу и ее название. Наименований регионов нет, а нам желательно для примера выбрать только один регион, иначе, если оставить всю Россию, это будет очень долго считаться. Регион можно узнать из ссылки. Например, в строке с индексом 1 школа из Камчатского края: в ссылке есть фрагмент «131-kamchatskij». ","type":"p","className":""},{"data":{"id":2323,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8279628990ad448087368e5a8ff4c610-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8279628990ad448087368e5a8ff4c610-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":92,"real_height_2x":184},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8279628990ad448087368e5a8ff4c610-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/8279628990ad448087368e5a8ff4c610-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":92,"real_height_2x":184}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Выберем, например, Нижегородскую область. В ссылках она помечена как «146-nizhegorodskaya». С помощью метода contains («содержит»), выберем только те ссылки, в которых есть эта запись. Так у нас останутся только школы Нижегородской области. Подробнее о том, как фильтровать датафреймы — в <a href=\"https://istories.media/workshops/2021/03/05/python-biblioteka-pandas-chast-1/\" data-type=\"usual\" target=\"_blank\">первом</a> уроке по Pandas. ","type":"p","className":""},{"data":{"id":2325,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ce1e4a60e783445c860877ea93eea717-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ce1e4a60e783445c860877ea93eea717-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":105,"real_height_2x":210},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ce1e4a60e783445c860877ea93eea717-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ce1e4a60e783445c860877ea93eea717-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":105,"real_height_2x":210}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Поскольку мы выбрали только некоторые строки, индексы датафрейма сбились и теперь идут не сначала: ","type":"p","className":""},{"data":{"id":2327,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/77ac290e9a1d48488e19b110d66fdc51-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/77ac290e9a1d48488e19b110d66fdc51-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":280,"real_height_2x":559},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/77ac290e9a1d48488e19b110d66fdc51-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/77ac290e9a1d48488e19b110d66fdc51-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":280,"real_height_2x":559}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы индексы сбросились и снова начинались с нуля, обновим их методом reset_index(). Drop = True означает, что старые индексы нам не нужны.","type":"p","className":""},{"data":{"id":2328,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3c043b20532741fa800aeba2a6ee6046-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3c043b20532741fa800aeba2a6ee6046-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":53,"real_height_2x":106},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3c043b20532741fa800aeba2a6ee6046-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3c043b20532741fa800aeba2a6ee6046-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":53,"real_height_2x":106}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Далее загружаем файл с населенными пунктами. В нем есть регион, район, название, численность населения, сколько в них детей, координаты, код ОКТМО (Общероссийского классификатора территорий муниципальных образований).","type":"p","className":""},{"data":{"id":2363,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3f8dbdfa4a82419aa4897fbc72a4446a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3f8dbdfa4a82419aa4897fbc72a4446a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":342,"real_height_2x":684},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3f8dbdfa4a82419aa4897fbc72a4446a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3f8dbdfa4a82419aa4897fbc72a4446a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":342,"real_height_2x":684}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Выберем тоже только Нижегородскую область, а чтобы все еще быстрее считалось, возьмем только один район, например, Воскресенский.","type":"p","className":""},{"data":{"id":2331,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bbf1d63a56ae46b4a065bc4ea49bca8a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bbf1d63a56ae46b4a065bc4ea49bca8a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":137,"real_height_2x":274},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bbf1d63a56ae46b4a065bc4ea49bca8a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/bbf1d63a56ae46b4a065bc4ea49bca8a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":137,"real_height_2x":274}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Снова обновляем индексы, чтобы шли с нуля. ","type":"p","className":""},{"data":{"id":2332,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/97b6fd0e1e2145dfb21ce565cba0ffbd-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/97b6fd0e1e2145dfb21ce565cba0ffbd-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":44,"real_height_2x":88},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/97b6fd0e1e2145dfb21ce565cba0ffbd-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/97b6fd0e1e2145dfb21ce565cba0ffbd-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":44,"real_height_2x":88}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"4. Создание словарей","type":"h2","className":""},{"data":"Прежде чем считать расстояния, нам понадобится создать два словаря — с населенными пунктами и со школами. Это нужно, чтобы в дальнейшем мы могли сопоставить разные датафреймы по какому-то уникальному параметру, доставать и добавлять нужные нам данные. Нам это пригодится на последних этапах. ","type":"p","className":""},{"data":"Для населенных пунктов таким уникальным параметром, по которому можно будет объединять разные датафреймы, станет код ОКТМО (Общероссийского классификатора территорий муниципальных образований).","type":"p","className":""},{"data":"Перед этим нам нужно убедиться, что: ","type":"p","className":""},{"data":"1) Во всех нужных нам столбцах указан правильный тип данных.","type":"p","className":""},{"data":"2) Удалены дубликаты в тех столбцах, которые будут уникальным ключом для словаря (для населенных пунктов это поле oktmo, для школ —&nbsp;url), поскольку ключи словаря не должны дублироваться.","type":"p","className":""},{"data":"Смотрим методом dtype, какой тип данных в столбце oktmo. Это float, число с плавающей точкой. ","type":"p","className":""},{"data":{"id":2333,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/010f1ce0d94d41c2972ceeed7a7efc45-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/010f1ce0d94d41c2972ceeed7a7efc45-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":88,"real_height_2x":176},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/010f1ce0d94d41c2972ceeed7a7efc45-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/010f1ce0d94d41c2972ceeed7a7efc45-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":88,"real_height_2x":176}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Удобнее будет в качестве уникального кода работать со строками, а не числами, поэтому поменяем тип данных сначала на integer, затем на string.","type":"p","className":""},{"data":{"id":2334,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/528aefc197d54e7d97cf9d199ff86815-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/528aefc197d54e7d97cf9d199ff86815-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":109,"real_height_2x":218},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/528aefc197d54e7d97cf9d199ff86815-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/528aefc197d54e7d97cf9d199ff86815-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":109,"real_height_2x":218}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Смотрим, есть ли в столбце oktmo дубликаты. ","type":"p","className":""},{"data":{"id":2364,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/46990accde75415989209326cb4fc56d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/46990accde75415989209326cb4fc56d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":384,"real_height_2x":770},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/46990accde75415989209326cb4fc56d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/46990accde75415989209326cb4fc56d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":384,"real_height_2x":770}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Удаляем дубликаты и обновляем индексы.","type":"p","className":""},{"data":{"id":2337,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b0ed6682e1c3404db7f5ada6f7348f93-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b0ed6682e1c3404db7f5ada6f7348f93-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":77,"real_height_2x":154},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b0ed6682e1c3404db7f5ada6f7348f93-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b0ed6682e1c3404db7f5ada6f7348f93-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":77,"real_height_2x":154}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Cобираем датафрейм с населенными пунктами в словарь, где ключом будет код ОКТМО, а значением — строка с информацией о соответствующем населенном пункте. Сначала мы создаем пустой словарь. Затем переменной i проходимся по всем индексам от 0 до последнего в нашем датафрейме. В переменную el записываем строку, которую получаем методом loc. ","type":"p","className":""},{"data":{"id":2338,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b4a10ec4fa1c42afa8ec17a5930717fe-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b4a10ec4fa1c42afa8ec17a5930717fe-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":217,"real_height_2x":434},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b4a10ec4fa1c42afa8ec17a5930717fe-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b4a10ec4fa1c42afa8ec17a5930717fe-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":217,"real_height_2x":434}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Переходим к датафрейму со школами. Сначала меняем тип данных в столбцах с широтой и долгой, потому что сейчас там строки, а нам для расчетов нужны числа (float).","type":"p","className":""},{"data":{"id":2365,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/28e44f4a82e44023a8ce208aba79ee88-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/28e44f4a82e44023a8ce208aba79ee88-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":266,"real_height_2x":534},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/28e44f4a82e44023a8ce208aba79ee88-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/28e44f4a82e44023a8ce208aba79ee88-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":266,"real_height_2x":534}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Удаляем дубликаты и обновляем индексы.","type":"p","className":""},{"data":{"id":2342,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/d1f31cbcb5e44dbe99e9c284f901ccb7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/d1f31cbcb5e44dbe99e9c284f901ccb7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":80,"real_height_2x":160},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/d1f31cbcb5e44dbe99e9c284f901ccb7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/d1f31cbcb5e44dbe99e9c284f901ccb7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":80,"real_height_2x":160}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"И теперь для школ собираем такой же словарь, как и для населенных пунктов. Ключом будет url.","type":"p","className":""},{"data":{"id":2343,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/6c6416463ebf4b5caf23bcc4e2028415-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/6c6416463ebf4b5caf23bcc4e2028415-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":176,"real_height_2x":352},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/6c6416463ebf4b5caf23bcc4e2028415-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/6c6416463ebf4b5caf23bcc4e2028415-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":176,"real_height_2x":352}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"5. Расчет матрицы расстояний","type":"h2","className":""},{"data":"Переходим к расчету расстояний между каждым населенным пунктом и каждой школой (матрица расстояний). За основу взят <a href=\"https://medium.com/@danalindquist/finding-the-distance-between-two-lists-of-geographic-coordinates-9ace7e43bb2f\" data-type=\"usual\" target=\"_blank\">туториал</a> Dana Lindquist.","type":"p","className":""},{"data":"Сначала переводим координаты из градусов в радианы, потому что математические формулы обычно требуют значения координат в радианах, а не в градусах. Делаем это с помощью библиотеки numpy.","type":"p","className":""},{"data":{"id":2344,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e42a1c720b564b20ac4aff85aba5e5cc-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e42a1c720b564b20ac4aff85aba5e5cc-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":164,"real_height_2x":328},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e42a1c720b564b20ac4aff85aba5e5cc-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e42a1c720b564b20ac4aff85aba5e5cc-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":164,"real_height_2x":328}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Далее считаем расстояния с помощью формулы из библиотеки scikit-learn. Эта формула вычисляет гаверсинусное расстояние, то есть представляет форму Земли как идеальную сферу (а не геоид, как на самом деле) и за счет этого обеспечивает быстрые вычисления. Если требуется измерение в километрах, то  в конце формулы нужно умоножать 6371, если в милях — на 3959. Мы получим расстояния от каждого населенного пункта до каждой школы в километрах.","type":"p","className":""},{"data":{"id":2345,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b2e56725a88b41fc8c434ee038d7003f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b2e56725a88b41fc8c434ee038d7003f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":133,"real_height_2x":266},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b2e56725a88b41fc8c434ee038d7003f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b2e56725a88b41fc8c434ee038d7003f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":133,"real_height_2x":266}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Строим матрицу расстояний — таблицу, в которой индексами будут url школ, колонками - ОКТМО населенных пунктов, а в ячейках будет расстояние.","type":"p","className":""},{"data":{"id":2348,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7b07132766624989b0e500d1d3de517e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7b07132766624989b0e500d1d3de517e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":119,"real_height_2x":238},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7b07132766624989b0e500d1d3de517e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7b07132766624989b0e500d1d3de517e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":119,"real_height_2x":238}]}]},"category":"image-embed"},"type":"image-embed"},{"data":{"id":2347,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3ac5d98e1e52438d9b0386595885b0c7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3ac5d98e1e52438d9b0386595885b0c7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":444,"real_height_2x":890},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3ac5d98e1e52438d9b0386595885b0c7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3ac5d98e1e52438d9b0386595885b0c7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":444,"real_height_2x":890}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Но нам нужно расстояние от населенных пунктов до школ, а не наоборот, поэтому транспонируем таблицу — поменяем индексы и колонки местами.","type":"p","className":""},{"data":{"id":2349,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/cb729beab40145cf86ae66c06bcc2fca-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/cb729beab40145cf86ae66c06bcc2fca-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":452,"real_height_2x":903},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/cb729beab40145cf86ae66c06bcc2fca-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/cb729beab40145cf86ae66c06bcc2fca-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":452,"real_height_2x":903}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"6. Выбор ближайшего объекта","type":"h2","className":""},{"data":"Выбираем ближайшую школу к каждому населенному пункту. Для этого сравниваем каждое значение в строке с предыдущим, чтобы проверить, больше оно или меньше. Меньшее записываем в переменную. Так проходим циклом по каждой строке, выбирая самое меньшее значение. И создаем словарь, в котором ключ — код ОКТМО населенного пункта, значения —&nbsp;url ближайшей школы и расстояние до нее.","type":"p","className":""},{"data":{"id":2351,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd4928bf5dc24993a34b45243eab20d4-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd4928bf5dc24993a34b45243eab20d4-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":443,"real_height_2x":886},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bd4928bf5dc24993a34b45243eab20d4-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/bd4928bf5dc24993a34b45243eab20d4-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":443,"real_height_2x":886}]}]},"category":"image-embed"},"type":"image-embed"},{"data":{"id":2352,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b7283a3e23664ddb9400d72f3c762787-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b7283a3e23664ddb9400d72f3c762787-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":119,"real_height_2x":238},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b7283a3e23664ddb9400d72f3c762787-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b7283a3e23664ddb9400d72f3c762787-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":119,"real_height_2x":238}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Далее добавляем колонки с минимальным расстоянием и url школы в датафрейм places_voskresensk (с населенными пунктами). Для этого берем из созданного выше словаря schools_and_min_value_by_oktmo ссылку (url) и расстояние до школы (distns). Добавляем их в словари school_url_column и min_distance_column в том порядке, в каком соответствующие им коды ОКТМО расположены в датафрейме places_voskresensk. И добавляем соответствующие новые колонки к датафрейму.","type":"p","className":""},{"data":{"id":2366,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/56cf8a0a72ca42d1b18afef4c1cf5f1f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/56cf8a0a72ca42d1b18afef4c1cf5f1f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":362,"real_height_2x":724},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/56cf8a0a72ca42d1b18afef4c1cf5f1f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/56cf8a0a72ca42d1b18afef4c1cf5f1f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":362,"real_height_2x":724}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Точно так же из словаря со школами достаем название школ и добавляем их к датафрейму.","type":"p","className":""},{"data":{"id":2355,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9de19ebc2b594c0fbe5ea1961a97d712-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9de19ebc2b594c0fbe5ea1961a97d712-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":122,"real_height_2x":246},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9de19ebc2b594c0fbe5ea1961a97d712-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9de19ebc2b594c0fbe5ea1961a97d712-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":122,"real_height_2x":246}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В конце появились 3 новые колонки — url ближайшей школы, сколько до нее километров по прямой, название школы. ","type":"p","className":""},{"data":{"id":2356,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/66308dcca6d34e9e9680de6d33d8c632-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/66308dcca6d34e9e9680de6d33d8c632-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":298,"real_height_2x":597},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/66308dcca6d34e9e9680de6d33d8c632-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/66308dcca6d34e9e9680de6d33d8c632-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":298,"real_height_2x":597}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Сохраним полученный результат в csv. ","type":"p","className":""},{"data":{"id":2357,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/6c7665c2bf4c4945ac3a00ea65641c85-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/6c7665c2bf4c4945ac3a00ea65641c85-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":35,"real_height_2x":70},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/6c7665c2bf4c4945ac3a00ea65641c85-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/6c7665c2bf4c4945ac3a00ea65641c85-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":35,"real_height_2x":70}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"7. Анализ данных","type":"h2","className":""},{"data":"Дальше мы можем анализировать данные. Например, выбрать 15 наиболее удаленных от школ населенных пунктов методом nlarest. Подробнее об nlargest и nsmallest — в 3 <a href=\"https://istories.media/workshops/2021/03/19/python-biblioteka-pandas-chast-3/\" data-type=\"usual\" target=\"_blank\">уроке</a> по Pandas. ","type":"p","className":""},{"data":{"id":2358,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/0849a0a50b554abdbd8aa7489fcd96ce-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/0849a0a50b554abdbd8aa7489fcd96ce-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":401,"real_height_2x":802},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/0849a0a50b554abdbd8aa7489fcd96ce-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/0849a0a50b554abdbd8aa7489fcd96ce-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":401,"real_height_2x":802}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Получили топ самых удаленных населенных пунктов. Или можем посчитать, сколько детей в Воскресенском районе Нижегородской области живут дальше 5 км от школы.","type":"p","className":""},{"data":{"id":2359,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ea191ffc19ff490088e880e29c08b37c-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ea191ffc19ff490088e880e29c08b37c-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":110,"real_height_2x":221},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ea191ffc19ff490088e880e29c08b37c-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ea191ffc19ff490088e880e29c08b37c-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":110,"real_height_2x":221}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Или среднее расстояние от населенного пункта до школы.","type":"p","className":""},{"data":{"id":2360,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a1bd7f42bd514c45a8dc2014dfe4b8db-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a1bd7f42bd514c45a8dc2014dfe4b8db-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":66,"real_height_2x":132},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a1bd7f42bd514c45a8dc2014dfe4b8db-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a1bd7f42bd514c45a8dc2014dfe4b8db-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":66,"real_height_2x":132}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Готово!","type":"p","className":""}]},{"id":265,"header":"Пишем своего робота на Python. Урок 4","_path":"/workshops/2021/05/01/pishem-svoego-robota-na-python-urok-4/","lead":"Узнаем, какие именно данные мы можем получить из API проекта «ГосЗатраты» и как правильно запрашивать их","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/2fb5170799b24d3ebd6d8dc10f75f8ec-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-05-01","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":8,"first_name":"Алеся","last_name":"Мароховская","first_name_en":"Alesya","last_name_en":"Marokhovskaya","is_public":true,"_path":"alesya-marokhovskaya","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.webp","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-896x504px_2x.jpg","for_width":896,"for_height":504,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.webp","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-688x387px_2x.jpg","for_width":688,"for_height":387,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.webp","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-416x234px_2x.jpg","for_width":416,"for_height":234,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.webp","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-336x189px_2x.jpg","for_width":336,"for_height":189,"original_url":"https://static.istories.media/uploaded/images/12285015ded6416c9ce475e3a939d7f7-original.jpg","real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Главная редакторка «Важных историй»","lead_en":"Editor-in-chief","position":"Редакторка","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Мы продолжаем знакомиться с возможностями API проекта «ГосЗатраты» в рамках нашего мини-курса, где мы пишем робота, который собирает данные о контрактах, анализирует их и присылает результаты нам на почту. Сегодня мы разберемся, на какие именно данные от «ГосЗатрат» мы можем рассчитывать.\nОткроем наш проект в редакторе Visual Studio Code и в терминале запустим виртуальное окружение командой pipenv shell, которое мы создавали в одном из прошлых выпусков. В этом проекте у нас уже есть функция, которая на входе получает номер региона, а возвращает контракты, которые были заключены в этом регионе. Давайте используем эту функцию, а возвращенный результат запишем в JSON-файл. Так нам сегодня будет удобнее работать, потому что каждый раз, когда мы запускаем код, где есть строчка request.get, мы отправляем новый запрос к серверу API «ГосЗатрат». Мы не хотим злоупотреблять и зря расходовать их ресурсы. Поэтому запустим код один раз и запишем результат в JSON-файл, с которым дальше будем работать. Давайте закомментируем print(result) с помощью символа # в начале строки.\n\nЧтобы сохранить JSON-файл, нам потребуется одноименная библиотека json. Импортируем ее с помощью import json. Затем запишем данные которые лежат в переменной result в файл под названием result.json и запустим наш код.\n\n\nМожем проверить папку с проектом и увидеть, что файл создался. Перед тем, как начать с ним работать, давайте посмотрим, что лежит внутри этого файла — откроем его в браузере. В Firefox он открывается в удобном виде. Наш файл — это как бы словарь, в котором хранятся списки и другие словари. Главный ключ это contracts, сами контракты лежат в ключе data, они пронумерованы. Раскроем первый контракт и посмотрим, какие поля в нем есть и какие нам было бы интересно собрать. \n\n\nНам интересны: ссылка на сам контракт (ведет на официальный портал госзакупок), дата подписания контракта, цена заключенного контракта, заказчик и данные о нем, поставщики и данные о них, данные о предметах контракта. Попробуем достать эти сущности из нашего файла.\n\nЧтобы работать с файлом result.json, создадим в нашем проекте еще один, чтобы наша функция для получения контрактов осталась целой и невредимой — в следующих уроках мы будем ее дорабатывать. Создаем проект через терминал с помощью touch sandbox.py (sandbox это название нового проекта).\n\n\nКак и в главном проекте main.py нам понадобится библиотека для работы с JSON, поэтому вводим в окне нового проекта import json. После этого откроем файл result.json.\n\n\nКак мы уже говорили, JSON-файл состоит из списков и словарей, поэтому обращаться к нему мы будем соответственно — начнем с главного ключа contracts, затем в data, опускаясь вглубь до нужных нам полей. Назовем переменную data и посмотрим, что там лежит.\n\n\nВ терминале мы видим все наши контракты. Теперь перебирая циклом for contract in data каждый элемент в data мы можем обращаться к каждому контракту и доставать нужные нам поля. Например, попробуем достать URL с помощью print (contract[‘ContractUrl’]). Таким способом мы можем получать данные из любого ключа в файле. Дописываем ключи price и regionCode — получаем цены контрактов и регион заключения (в нашем случае он один и тот же).\n\n\nДля распаковки таких словарей и списков мы можем использовать функцию, которую изучали в уроке про рекурсию. Эта функция принимает на вход два аргумента, один из них — ключ, по которому нужно найти значение, а второй — объект, в котором мы будем искать этот ключ и значение. Если объект будет равен None, функция вернет None. \n\n\nПерепишем наш код с использованием этой функции. В contract_url введем recurs_find_key (‘ContractUrl’, contract) и далее по образцу.\n\n\nНа пунктах customer, supplier и products (заказчик, поставщики и предметы контракта соответственно) остановимся отдельно. Если мы посмотрим в файл, то увидим, что внутри, например, заказчика есть еще словарь. Там лежит ИНН и название организации. \n\n\nЕсли мы распечатаем данные как есть, то увидим, что нам возвращаются словари, и с этим не очень удобно работать — нам нужны название и ИНН отдельно. Перепишем функцию так, чтобы она обращалась непосредственно к ключу customer по каждой из нужных нам деталей.\n\n\nС supplier и products немного другая история. Поставщиков и продуктов по контракту может быть больше, чем один. Поэтому в suppliers в JSON-файле лежит список. Чтобы предусмотреть этот нюанс, нужно перебрать каждого поставщика и достать из него название и ИНН. Для этого сделаем словарь suppliers_dict и для каждого поставщика в списке создадим функцию, которая будет выводить ИНН и название организации. Дальше добавим это в наш словарь, где ключом будет ИНН, а значением — название. \n\n\nС products та же самая история. Сначала нам нужно получить имя каждой закупки. Снова воспользуемся нашей рекурсивной функцией, передадим ей список словарей, из которого будем доставать name. А дальше воспользуемся уже известными нам генераторами списков, чтобы получить список всех наименований, и превратим его в строчку функцией join, разделяя названия точкой с запятой. Назовем эту переменную subjects.\n\n\nСегодня мы достали все необходимые значения, с которыми можем что-то делать, а в следующий раз усовершенствуем нашу функцию получения данных из API «ГосЗатрат». Если у вас возникли вопросы — как всегда, пишите в наш чат в Telegram.","blocks":[{"data":"Мы продолжаем знакомиться с возможностями API проекта&nbsp;«ГосЗатраты» в рамках нашего мини-курса, где мы пишем робота, который собирает данные о контрактах, анализирует их и присылает результаты нам на почту. Сегодня мы разберемся, на какие именно данные от «ГосЗатрат» мы можем рассчитывать.","type":"p","className":""},{"data":{"id":2465,"data":{"url":"https://www.youtube.com/embed/dXUtq7ZLmWA","text":"Видео: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=dXUtq7ZLmWA&t=39s","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Откроем наш проект в редакторе Visual Studio Code и в терминале запустим виртуальное окружение командой <strong>pipenv shell</strong>, которое мы создавали в <a href=\"https://istories.media/workshops/2021/04/16/pishem-svoego-robota-na-python-urok-2/\" data-type=\"usual\" target=\"_blank\">одном из прошлых выпусков</a>.&nbsp;В этом проекте у нас уже есть функция, которая на входе получает номер региона, а возвращает контракты, которые были заключены в этом регионе. Давайте используем эту функцию, а возвращенный результат запишем в JSON-файл.&nbsp;Так нам сегодня будет удобнее работать, потому что каждый раз, когда мы запускаем код, где есть строчка <strong>request.get</strong>, мы отправляем новый запрос к серверу API «ГосЗатрат». Мы не хотим злоупотреблять и зря расходовать их ресурсы. Поэтому запустим код один раз и запишем результат в JSON-файл, с которым дальше будем работать. Давайте закомментируем <strong>print(result)</strong> с помощью символа <strong># </strong>в начале строки.","type":"p","className":""},{"data":"Чтобы сохранить JSON-файл, нам потребуется одноименная библиотека <strong>json</strong>. Импортируем ее с помощью <strong>import json</strong>. Затем запишем данные которые лежат в переменной <strong>result</strong> в файл под названием<strong> result.json</strong> и запустим наш код.","type":"p","className":""},{"data":{"id":2380,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b019f9aa95f04cc1903ea1ff4dba4153-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b019f9aa95f04cc1903ea1ff4dba4153-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":530,"real_height_2x":1059},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b019f9aa95f04cc1903ea1ff4dba4153-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b019f9aa95f04cc1903ea1ff4dba4153-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":530,"real_height_2x":1059}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Можем проверить папку с проектом и увидеть, что файл создался. Перед тем, как начать с ним работать, давайте посмотрим, что лежит внутри этого файла — откроем его в браузере. В Firefox он открывается в удобном виде. Наш файл — это как бы словарь, в котором хранятся списки и другие словари. Главный ключ это <strong>contracts</strong>, сами контракты лежат в ключе <strong>data</strong>, они пронумерованы. Раскроем первый контракт и посмотрим, какие поля в нем есть и какие нам было бы интересно собрать.&nbsp;","type":"p","className":""},{"data":{"id":2381,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/75e009597a474b4e8b008bd3b26f214f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/75e009597a474b4e8b008bd3b26f214f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":679,"real_height_2x":1358},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/75e009597a474b4e8b008bd3b26f214f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/75e009597a474b4e8b008bd3b26f214f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":679,"real_height_2x":1358}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Нам интересны: ссылка на сам контракт (ведет на официальный портал госзакупок), дата подписания контракта, цена заключенного контракта, заказчик и данные о нем, поставщики и данные о них, данные о предметах контракта. Попробуем достать эти сущности из нашего файла.","type":"p","className":""},{"data":"Чтобы работать с файлом <strong>result.json</strong>, создадим в нашем проекте еще один, чтобы наша функция для получения контрактов осталась целой и невредимой — в следующих уроках мы будем ее дорабатывать. Создаем проект через терминал с помощью <strong>touch sandbox.py</strong> (<strong>sandbox</strong> это название нового проекта).","type":"p","className":""},{"data":{"id":2382,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/fa0e809f92a148589ef0161660f9984f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/fa0e809f92a148589ef0161660f9984f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":119,"real_height_2x":238},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/fa0e809f92a148589ef0161660f9984f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/fa0e809f92a148589ef0161660f9984f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":119,"real_height_2x":238}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Как и в главном проекте <strong>main.py</strong> нам понадобится библиотека для работы с JSON, поэтому вводим в окне нового проекта<strong> import json</strong>. После этого откроем файл <strong>result.json</strong>.","type":"p","className":""},{"data":{"id":2383,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5efbf94de7f5418083b5e98b6491b63e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5efbf94de7f5418083b5e98b6491b63e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":522,"real_height_2x":1044},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5efbf94de7f5418083b5e98b6491b63e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5efbf94de7f5418083b5e98b6491b63e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":522,"real_height_2x":1044}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Как мы уже говорили, JSON-файл состоит из списков и словарей, поэтому обращаться к нему мы будем соответственно — начнем с главного ключа <strong>contracts</strong>, затем в <strong>data</strong>, опускаясь вглубь до нужных нам полей. Назовем переменную <strong>data</strong> и посмотрим, что там лежит.","type":"p","className":""},{"data":{"id":2384,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7e18f81dfa984de98b50039f1565c4f4-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7e18f81dfa984de98b50039f1565c4f4-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":459,"real_height_2x":918},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7e18f81dfa984de98b50039f1565c4f4-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7e18f81dfa984de98b50039f1565c4f4-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":459,"real_height_2x":918}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В терминале мы видим все наши контракты. Теперь перебирая циклом <strong>for contract in data</strong> каждый элемент в <strong>data</strong> мы можем обращаться к каждому контракту и доставать нужные нам поля. Например, попробуем достать URL с помощью <strong>print (contract[‘ContractUrl’])</strong>. Таким способом мы можем получать данные из любого ключа в файле. Дописываем ключи <strong>price</strong> и <strong>regionCode</strong> —&nbsp;получаем цены контрактов и регион заключения (в нашем случае он один и тот же).","type":"p","className":""},{"data":{"id":2385,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/13e93072f9a24805bc4b730049579948-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/13e93072f9a24805bc4b730049579948-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":558,"real_height_2x":1116},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/13e93072f9a24805bc4b730049579948-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/13e93072f9a24805bc4b730049579948-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":558,"real_height_2x":1116}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Для распаковки таких словарей и списков мы можем использовать функцию, которую изучали в <a href=\"https://istories.media/workshops/2021/02/11/vvedenie-v-python-chast-12-rekursiya/\" data-type=\"usual\" target=\"_blank\">уроке про рекурсию</a>. Эта функция принимает на вход два аргумента, один из них —&nbsp;ключ, по которому нужно найти значение, а второй —&nbsp;объект, в котором мы будем искать этот ключ и значение. Если объект будет равен <strong>None</strong>, функция вернет <strong>None</strong>.&nbsp;","type":"p","className":""},{"data":{"id":2386,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/93357964349d431297c95276e4924404-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/93357964349d431297c95276e4924404-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":702,"real_height_2x":1404},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/93357964349d431297c95276e4924404-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/93357964349d431297c95276e4924404-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":702,"real_height_2x":1404}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Перепишем наш код с использованием этой функции. В<strong> contract_url </strong>введем <strong>recurs_find_key (‘ContractUrl’, contract)</strong> и далее по образцу.","type":"p","className":""},{"data":{"id":2387,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/ea226a11825c4f0386fd6691139ec0c4-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/ea226a11825c4f0386fd6691139ec0c4-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":502,"real_height_2x":1004},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/ea226a11825c4f0386fd6691139ec0c4-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/ea226a11825c4f0386fd6691139ec0c4-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":502,"real_height_2x":1004}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"На пунктах <strong>customer</strong>, <strong>supplier</strong> и <strong>products</strong> (заказчик, поставщики и предметы контракта соответственно) остановимся отдельно. Если мы посмотрим в файл, то увидим, что внутри, например, заказчика есть еще <a href=\"https://istories.media/workshops/2020/12/09/vvedenie-v-python-chast-6-slovari/\" data-type=\"usual\" target=\"_blank\">словарь</a>. Там лежит ИНН и название организации.&nbsp;","type":"p","className":""},{"data":{"id":2388,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8d19915767214637a649539797531cfb-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8d19915767214637a649539797531cfb-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":443,"real_height_2x":886},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8d19915767214637a649539797531cfb-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/8d19915767214637a649539797531cfb-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":443,"real_height_2x":886}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если мы распечатаем данные как есть, то увидим, что нам возвращаются словари, и с этим не очень удобно работать — нам нужны название и ИНН отдельно. Перепишем функцию так, чтобы она обращалась непосредственно к ключу <strong>customer</strong> по каждой из нужных нам деталей.","type":"p","className":""},{"data":{"id":2389,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/f1364e2dc61248a4a6ee8914db4fa18b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/f1364e2dc61248a4a6ee8914db4fa18b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":776,"real_height_2x":1551},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/f1364e2dc61248a4a6ee8914db4fa18b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/f1364e2dc61248a4a6ee8914db4fa18b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":776,"real_height_2x":1551}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"С <strong>supplier</strong> и <strong>products</strong> немного другая история. Поставщиков и продуктов по контракту может быть больше, чем один. Поэтому в <strong>suppliers</strong> в JSON-файле лежит список. Чтобы предусмотреть этот нюанс, нужно перебрать каждого поставщика и достать из него название и ИНН. Для этого сделаем словарь <strong>suppliers_dict </strong>и для каждого поставщика в списке создадим функцию, которая будет выводить ИНН и название организации. Дальше добавим это в наш словарь, где ключом будет ИНН, а значением —&nbsp;название.&nbsp;","type":"p","className":""},{"data":{"id":2390,"data":{"images":[{"imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/fa89d50f012b4d58bdd283f8dafa46f7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/fa89d50f012b4d58bdd283f8dafa46f7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":511,"real_height_2x":1022},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/fa89d50f012b4d58bdd283f8dafa46f7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/fa89d50f012b4d58bdd283f8dafa46f7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":511,"real_height_2x":1022}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"С <strong>products</strong> та же самая история. Сначала нам нужно получить имя каждой закупки. Снова воспользуемся нашей рекурсивной функцией, передадим ей список словарей, из которого будем доставать <strong>name</strong>. А дальше воспользуемся уже известными нам <a href=\"https://istories.media/workshops/2021/01/22/vvedenie-v-python-chast-10-generatori-spiskov/\" data-type=\"usual\" target=\"_blank\">генераторами списков</a>, чтобы получить список всех наименований, и превратим его в строчку функцией <strong>join</strong>, разделяя названия точкой с запятой. Назовем эту переменную <strong>subjects</strong>.","type":"p","className":""},{"data":{"id":2392,"data":{"images":[{"credit":"Используем recurs_find_key, чтобы достать ИНН и название","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/4526e8e3665d4fe6a7321ecbecfe7f2a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/4526e8e3665d4fe6a7321ecbecfe7f2a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":516,"real_height_2x":1032},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/4526e8e3665d4fe6a7321ecbecfe7f2a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/4526e8e3665d4fe6a7321ecbecfe7f2a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":516,"real_height_2x":1032}]},{"credit":"Там, где предметов больше одного, они перечислены через точку с запятой","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/c04d568e236a41268516d613d8f421b8-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/c04d568e236a41268516d613d8f421b8-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":336,"real_height_2x":672},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/c04d568e236a41268516d613d8f421b8-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/c04d568e236a41268516d613d8f421b8-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":336,"real_height_2x":672}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Сегодня мы достали все необходимые значения, с которыми можем что-то делать, а в следующий раз усовершенствуем нашу функцию получения данных из API «ГосЗатрат». Если у вас возникли вопросы — как всегда, пишите в наш <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">чат</a> в Telegram.","type":"p","className":""}]},{"id":254,"header":"Пишем своего робота на Python. Урок 3","_path":"/workshops/2021/04/23/pishem-svoego-robota-na-python-urok-3/","lead":"Учимся получать данные из сети, использовать библиотеку Requests и API сторонних сервисов","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-1920x960px_1x.png","url_2x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-1920x960px_2x.png","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-1272x636px_1x.png","url_2x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-1272x636px_2x.png","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-912x456px_1x.png","url_2x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-912x456px_2x.png","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-600x400px_1x.png","url_2x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-600x400px_2x.png","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-360x360px_1x.png","url_2x":"https://static.istories.media/uploaded/images/bd1f05ace7c441cbacb7179bf4b79c2d-360x360px_2x.png","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-04-23","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":5,"first_name":"Роман","last_name":"Анин","first_name_en":"Roman","last_name_en":"Anin","is_public":true,"_path":"roman-anin","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-896x504px_2x.webp","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-896x504px_2x.jpg","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-688x387px_2x.webp","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-688x387px_2x.jpg","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-416x234px_2x.webp","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-416x234px_2x.jpg","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-336x189px_2x.webp","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-336x189px_2x.jpg","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Редактор «Важных историй»","lead_en":"","position":"Редактор","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Продолжаем наш цикл уроков, где мы пишем робота на Python, который будет собирать данные крупнейших госконтрактов в России и присылать их вам на почту. Сегодня мы поработаем с библиотекой Requests, научимся получать данные из сети и разберемся, что такое API. \nОткроем наш проект в редакторе Visual Studio Code, очистим терминал уже известной нам командой clear, чтобы было удобнее работать, и активируем виртуальное окружение командой pipenv shell.\nВ прошлый раз мы установили библиотеку Requests — она позволяет нам делать запросы (те самые requests) и получать данные из интернета. Для примера возьмем одну из статей «Важных историй» и попробуем проанализировать ее текст. \n\nДелаем первый запрос\nЧтобы начать пользоваться библиотекой Requests, ее нужно импортировать в наш файл. Для этого в текстовой области нашего файла main.py пишем import requests и выполняем команду. \nДалее нужно задать адрес страницы, содержимое которой мы хотим получить и проанализировать. В нашем примере это будет статья «Чудесная вилла на острове миллионеров». Скопируем ее адрес и создадим в нашем файле новую переменную url = ‘адрес нужной страницы’. Обратите внимание, что адрес мы записываем обязательно в кавычках, чтобы он не переносился на новую строку.\nТеперь, чтобы получить данные, нам нужна всего одна строчка кода. Создадим новую переменную data с использованием библиотеки Requests и метода get, который мы направляем на нашу статью, то есть url: data = requests.get(url).\nРаспечатаем полученные данные и посмотрим, что вышло: print(data).\nМы видим, что в терминале нам вернулся Response [200] — это значит, что наш запрос был успешно отправлен, и сервер нам ответил. Чтобы посмотреть, что именно ответил сервер, нужно добавить опцию text — тогда команда примет вид print(data.text). Посмотрим, что теперь отобразится в терминале.\nКак видите, мы получили сырые данные — HTML-код всей страницы, доступной по заданному нами адресу. В этих данных есть множество ненужных нам элементов. Текст можно проанализировать даже в таком виде, но для этого нам бы пришлось установить еще несколько библиотек. В будущем мы расскажем о таких библиотеках. Но все-таки лучше получать данные в нормальном виде, и в этом нам помогут API. \n\nAPI — это аббревиатура от английского application programming interface, то есть, это интерфейс приложения со своим набором функций. API используются буквально везде: в платежных системах, в онлайн-бронировании, в социальных сетях. Давайте посмотрим, как это работает на примере.\n\nПробуем работать с госконтрактами вручную\nДля работы с госконтрактами мы будем использовать сервис «ГосЗатраты». Под капотом у сервиса — данные с официального портала госконтрактов. Попробуем для начала поискать что-нибудь в «ГосЗатратах» с помощью поисковой строки на сайте — так, как это делают обычные пользователи. \nВыбираем раздел «Контракты», нажимаем на «Расширенный поиск». Теперь попробуем получить все госконтракты из Ярославской области — в списке «Регион госзаказчика» выбираем нужную область и нажимаем кнопку «Найти».\nУ нас появился список госконтрактов. Теперь отфильтруем контракты по дате заключения. Вернемся к параметрам расширенного поиска и в пункте «Дата заключения контракта» выберем, например, период с 1 по 7 апреля и снова нажмем «Найти».\nМы получили 57 контрактов из Ярославской области, заключенных с 1 по 7 апреля. Теперь их можно отсортировать от самых крупных к самым мелким, нажав на кнопку «по сумме контракта».\nС одной стороны, мы уже получили очень интересные данные для анализа. С другой стороны, мы ограничены в дальнейшем анализе этих данных — например, мы не можем быстро посчитать сумму всех заключенных за неделю контрактов, для этого нам придется скачивать их, вручную открывать каждый в Excel и только затем считать. Для автоматизации таких задач и существует API.\n\nДавайте внимательно посмотрим на адресную строку страницы с нашими госконтрактами.\nВ строке перечислены различные параметры: в productsearch пусто, в других тоже, а вот в datarange есть значения — они совпадают с теми датами, которые задавали при поиске. Если мы прямо в адресной строке изменим эти значения — соответственно изменится и поисковая выдача. Например, заменим 7 апреля на 1 апреля, чтобы отобразились госконтракты только за 1 апреля, и нажмем Enter, чтобы перезагрузить страницу с обновленным адресом.\nПопробуем сделать то же самое с регионом. У нас есть параметр customerregion и его значение 76, которое соответствует коду Ярославской области. Поменяем его на 77 (Москва) и еще раз нажмем Enter.\nТолько что вы сделали первые запросы к API какого-то сервиса, в данном случае «ГосЗатрат». Но, конечно, API придумывалось не для того, чтобы вручную менять какие-то данные в адресной строке. \n\nТестируем работу API в браузере\nЧтобы разобраться, как работает API «ГосЗатрат», нужно почитать документацию и изучить, какие есть методы и как лучше с ними работать. В документации мы видим базовый URL, а ниже перечислены параметры поиска, которые можно использовать. Некоторые из них мы уже встречали — например, datarange и customerregion.\nПопробуем воспользоваться знаниями из документации и настроить поиск в адресной строке браузера с нуля. Скопируем базовый URL и перейдем по нему. Мы увидим надпись «Invalid request», потому что не задали никаких параметров поиска. Добавим параметр, который покажет контракты только по Ярославской области. Добавляем к базовому URL вопросительный знак, название параметра (в нашем случае customerregion), знак равенства и номер региона (в нашем случае 76).\nНажмем Enter и увидим JSON-объект с контрактами. JSON это формат данных, который похож на словари в Python. У нас есть список data, и каждый элемент в этом списке это словарь, у которого есть ключи и их значения: номер контракта, дата подписания, цена заключения и так далее.\nРаботаем с госконтрактами через API и Python\nНаконец, попробуем получить такие же данные с помощью программирования. В текстовой области нашего файла main.py апишем небольшую функцию: def get_contracts_by_region():. Пока она ничего не будет делать, поэтому внизу напишем pass — это ключевое слово будет временной «заглушкой». \nТеперь скопируем URL из браузера, который мы использовали для поиска госконтрактов по Ярославской области через API, создадим в проекте переменную url вместо pass и вставим туда наш адрес (не забывайте про кавычки).\nДалее используем нашу библиотеку Requests: на следующей строке дописываем data = requests.get(url), как делали в начале урока, и добавляем формат получаемых данных json (а не text, как до этого). Эти данные нам нужно вернуть с помощью return data.\nТеперь проверим результат: присвоим нашей функции get_contracts_by_region() значение result и с помощью print посмотрим, что у нас получилось.\nКак видите, сейчас в терминале мы получили тот же список контрактов, который до этого видели в браузере, но подготовленный для анализа программными методами. \n\nНачинаем улучшать функцию\nТеперь сделаем так, чтобы наша функция возвращала данные не только из Ярославской области, но и из любого другого региона. Для этого зададим функции get_contracts_by_region() параметр region_code — этот параметр должен встать в следующую строку на место кода Ярославской области. \n\nВ одном из уроков по введению в Python мы проходили форматирование строк, где рассказывали, что можно поставить букву f перед открывающими строку кавычками и далее внутрь кавычек вводить любые параметры в фигурных скобках {}. Сейчас это нам пригодится — вместо 76 мы вставим {region_code}.\nПопробуем снова вызвать нашу функцию, но уже с другим регионом 78 (Санкт-Петербург). Для этого в строку result get_contracts_by_region() добавим в скобки номер региона и запустим print еще раз.\nВ следующих уроках мы продолжим улучшать функцию, добавляя ей новые возможности — чтобы она возвращала данные не только по регионам, но и по дате подписания, цене и другим параметрам, которые мы видели в документации к API портала «ГосЗатраты». Если у вас возникли вопросы по уроку — не стесняйтесь задавать их в нашем чате в Telegram.","blocks":[{"data":"Продолжаем наш цикл уроков, где мы пишем робота на Python, который будет собирать данные крупнейших госконтрактов в России и присылать их вам на почту.&nbsp;Сегодня мы поработаем с библиотекой Requests, научимся получать данные из сети и разберемся, что такое API.&nbsp;","type":"p","className":""},{"data":{"data":{"url":"https://www.youtube.com/embed/ziE7VceZZ1M","text":"Видео: Глеб Лиманский","provider":"youtube","rawInput":"https://www.youtube.com/watch?v=ziE7VceZZ1M","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Откроем наш проект в редакторе Visual Studio Code, очистим терминал уже известной нам командой <strong>clear</strong>, чтобы было удобнее работать, и активируем виртуальное окружение командой <strong>pipenv shell</strong>.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5536ca37cf164f0d9998f1ab5476ada9-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5536ca37cf164f0d9998f1ab5476ada9-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":202,"real_height_2x":406},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5536ca37cf164f0d9998f1ab5476ada9-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5536ca37cf164f0d9998f1ab5476ada9-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":202,"real_height_2x":406}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"<a href=\"https://istories.media/workshops/2021/04/16/pishem-svoego-robota-na-python-urok-2/\" data-type=\"usual\" target=\"_blank\">В прошлый раз</a> мы установили библиотеку Requests —&nbsp;она позволяет нам делать запросы (те самые requests) и получать данные из интернета. Для примера возьмем одну из статей «Важных историй» и попробуем проанализировать ее текст. ","type":"p","className":""},{"data":"Делаем первый запрос","type":"h2","className":""},{"data":"Чтобы начать пользоваться библиотекой Requests, ее нужно импортировать в наш файл. Для этого в текстовой области нашего файла main.py пишем <strong>import requests</strong> и выполняем команду.&nbsp;","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/90f2118a2f1e4f6688893ee9783e6637-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/90f2118a2f1e4f6688893ee9783e6637-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":405,"real_height_2x":810},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/90f2118a2f1e4f6688893ee9783e6637-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/90f2118a2f1e4f6688893ee9783e6637-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":405,"real_height_2x":810}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Далее нужно задать адрес страницы, содержимое которой мы хотим получить и проанализировать. В нашем примере это будет <a href=\"https://istories.media/investigations/2021/04/07/chudesnaya-villa-na-ostrove-millionerov/\" data-type=\"usual\" target=\"_blank\">статья «Чудесная вилла на острове миллионеров»</a>. Скопируем ее адрес и создадим в нашем файле новую переменную <strong>url = ‘адрес нужной страницы’</strong>. Обратите внимание, что адрес мы записываем обязательно в кавычках, чтобы он не переносился на новую строку.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/87383e13bb824b4e9123dac24fd6fc78-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/87383e13bb824b4e9123dac24fd6fc78-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":231,"real_height_2x":462},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/87383e13bb824b4e9123dac24fd6fc78-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/87383e13bb824b4e9123dac24fd6fc78-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":231,"real_height_2x":462}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь, чтобы получить данные, нам нужна всего одна строчка кода. Создадим новую переменную <strong>data</strong> с использованием библиотеки Requests и метода <strong>get</strong>, который мы направляем на нашу статью, то есть <strong>url</strong>: <strong>data = requests.get(url)</strong>.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5a8f7bd5a7bd42f9b5103ef824989b5b-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5a8f7bd5a7bd42f9b5103ef824989b5b-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":233,"real_height_2x":466},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5a8f7bd5a7bd42f9b5103ef824989b5b-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5a8f7bd5a7bd42f9b5103ef824989b5b-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":233,"real_height_2x":466}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Распечатаем полученные данные и посмотрим, что вышло: <strong>print(data)</strong>.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e1a9efec4ec440fb9e6f823b92a54400-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e1a9efec4ec440fb9e6f823b92a54400-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":606,"real_height_2x":1212},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e1a9efec4ec440fb9e6f823b92a54400-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e1a9efec4ec440fb9e6f823b92a54400-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":606,"real_height_2x":1212}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы видим, что в терминале нам вернулся Response [200] — это значит, что наш запрос был успешно отправлен, и сервер нам ответил. Чтобы посмотреть, что именно ответил сервер, нужно добавить опцию <strong>text </strong>— тогда команда примет вид <strong>print(data.text)</strong>. Посмотрим, что теперь отобразится в терминале.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/02db509b6eed4f3f97ef77a1b0995d6a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/02db509b6eed4f3f97ef77a1b0995d6a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":252,"real_height_2x":503},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/02db509b6eed4f3f97ef77a1b0995d6a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/02db509b6eed4f3f97ef77a1b0995d6a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":252,"real_height_2x":503}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Как видите, мы получили сырые данные — HTML-код всей страницы, доступной по заданному нами адресу. В этих данных есть множество ненужных нам элементов. Текст можно проанализировать даже в таком виде, но для этого нам бы пришлось установить еще несколько библиотек. В будущем мы расскажем о таких библиотеках. Но все-таки лучше получать данные в нормальном виде, и в этом нам помогут API.&nbsp;","type":"p","className":""},{"data":"<strong>API</strong> — это аббревиатура от английского application programming interface, то есть, это интерфейс приложения со своим набором функций. API используются буквально везде: в платежных системах, в онлайн-бронировании, в социальных сетях. Давайте посмотрим, как это работает на примере.","type":"p","className":""},{"data":"Пробуем работать с госконтрактами вручную","type":"h2","className":""},{"data":"Для работы с госконтрактами мы будем использовать <a href=\"https://clearspending.ru/\" data-type=\"usual\" target=\"_blank\">сервис «ГосЗатраты»</a>. Под капотом у сервиса — данные с&nbsp;<a href=\"https://zakupki.gov.ru/\" data-type=\"usual\" target=\"_blank\">официального портала госконтрактов</a>. Попробуем для начала поискать что-нибудь в «ГосЗатратах» с помощью поисковой строки на сайте — так, как это делают обычные пользователи.&nbsp;","type":"p","className":""},{"data":{"data":{"images":[{"credit":"Сервис «ГосЗатраты»: clearspending.ru","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/024851c055a64989b94372fc9969c331-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/024851c055a64989b94372fc9969c331-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":296,"real_height_2x":592},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/024851c055a64989b94372fc9969c331-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/024851c055a64989b94372fc9969c331-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":296,"real_height_2x":592}]},{"credit":"Расширенный поиск","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e8b82d4b218c4b28ba91d2d0a747635d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e8b82d4b218c4b28ba91d2d0a747635d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":422,"real_height_2x":844},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e8b82d4b218c4b28ba91d2d0a747635d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e8b82d4b218c4b28ba91d2d0a747635d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":422,"real_height_2x":844}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Выбираем раздел «Контракты», нажимаем на «Расширенный поиск». Теперь попробуем получить все госконтракты из Ярославской области —&nbsp;в списке «Регион госзаказчика» выбираем нужную область и нажимаем кнопку «Найти».","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a5d7be4a485a4ae6979dcb9346f56493-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a5d7be4a485a4ae6979dcb9346f56493-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":502,"real_height_2x":1006},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a5d7be4a485a4ae6979dcb9346f56493-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a5d7be4a485a4ae6979dcb9346f56493-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":502,"real_height_2x":1006}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"У нас появился список госконтрактов. Теперь отфильтруем контракты по дате заключения. Вернемся к параметрам расширенного поиска и в пункте «Дата заключения контракта» выберем, например, период с 1 по 7 апреля и снова нажмем «Найти».","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/8079b21daab14892ba0e5dd879902790-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/8079b21daab14892ba0e5dd879902790-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":458,"real_height_2x":915},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/8079b21daab14892ba0e5dd879902790-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/8079b21daab14892ba0e5dd879902790-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":458,"real_height_2x":915}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Мы получили 57 контрактов из Ярославской области, заключенных с 1 по 7 апреля. Теперь их можно отсортировать от самых крупных к самым мелким, нажав на кнопку «по сумме контракта».","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3fe2dde4d0174c178dcc74b4bfb2d487-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3fe2dde4d0174c178dcc74b4bfb2d487-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":463,"real_height_2x":926},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3fe2dde4d0174c178dcc74b4bfb2d487-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3fe2dde4d0174c178dcc74b4bfb2d487-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":463,"real_height_2x":926}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"С одной стороны, мы уже получили очень интересные данные для анализа. С другой стороны, мы ограничены в дальнейшем анализе этих данных —&nbsp;например, мы не можем быстро посчитать сумму всех заключенных за неделю контрактов, для этого нам придется скачивать их, вручную открывать каждый в Excel и только затем считать. Для автоматизации таких задач и существует API.","type":"p","className":""},{"data":"Давайте внимательно посмотрим на адресную строку страницы с нашими госконтрактами.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/54e8ac6a049048f89919ae6b4b69afce-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/54e8ac6a049048f89919ae6b4b69afce-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":264,"real_height_2x":528},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/54e8ac6a049048f89919ae6b4b69afce-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/54e8ac6a049048f89919ae6b4b69afce-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":264,"real_height_2x":528}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В строке перечислены различные параметры: в <strong>productsearch</strong> пусто, в других тоже, а вот в <strong>datarange</strong> есть значения — они совпадают с теми датами, которые задавали при поиске. Если мы прямо в адресной строке изменим эти значения — соответственно изменится и поисковая выдача. Например, заменим 7 апреля на 1 апреля, чтобы отобразились госконтракты только за 1 апреля, и нажмем Enter, чтобы перезагрузить страницу с обновленным адресом.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"Меняем дату на 1 апреля","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5690d3a18f8643f799feecc4d75eedd2-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5690d3a18f8643f799feecc4d75eedd2-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":394,"real_height_2x":790},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5690d3a18f8643f799feecc4d75eedd2-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5690d3a18f8643f799feecc4d75eedd2-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":394,"real_height_2x":790}]},{"credit":"Мы получили контракты только за 1 апреля — их 28","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1dd047fc16a9490996ad3381cf7f7a07-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1dd047fc16a9490996ad3381cf7f7a07-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":442,"real_height_2x":884},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1dd047fc16a9490996ad3381cf7f7a07-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1dd047fc16a9490996ad3381cf7f7a07-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":442,"real_height_2x":884}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Попробуем сделать то же самое с регионом. У нас есть параметр <strong>customerregion</strong> и его значение 76, которое соответствует коду Ярославской области. Поменяем его на 77 (Москва) и еще раз нажмем Enter.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"Меняем регион на 77","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1acc063f80e64ed1a3e8c4f10d55f80d-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1acc063f80e64ed1a3e8c4f10d55f80d-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":378,"real_height_2x":756},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/1acc063f80e64ed1a3e8c4f10d55f80d-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/1acc063f80e64ed1a3e8c4f10d55f80d-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":378,"real_height_2x":756}]},{"credit":"Мы получили контракты из Москвы за 1 апреля","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5765adfbe1d34377a7e7e38c8b981dbf-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5765adfbe1d34377a7e7e38c8b981dbf-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":412,"real_height_2x":824},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5765adfbe1d34377a7e7e38c8b981dbf-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5765adfbe1d34377a7e7e38c8b981dbf-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":412,"real_height_2x":824}]}]},"category":"two-images-embed"},"type":"two-images-embed"},{"data":"Только что вы сделали первые запросы к API какого-то сервиса, в данном случае «ГосЗатрат». Но, конечно, API придумывалось не для того, чтобы вручную менять какие-то данные в адресной строке.&nbsp;","type":"p","className":""},{"data":"Тестируем работу API в браузере","type":"h2","className":""},{"data":"Чтобы разобраться, как работает API «ГосЗатрат», нужно почитать <a href=\"https://github.com/clearspending/clearspending-examples/wiki\" data-type=\"usual\" target=\"_blank\">документацию</a> и изучить, какие есть методы и как лучше с ними работать. В документации мы видим базовый URL, а ниже перечислены параметры поиска, которые можно использовать. Некоторые из них мы уже встречали —&nbsp;например, <strong>datarange</strong> и <strong>customerregion</strong>.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/36ef9cfe659f4959b1c779dfa0985a40-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/36ef9cfe659f4959b1c779dfa0985a40-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":794,"real_height_2x":1589},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/36ef9cfe659f4959b1c779dfa0985a40-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/36ef9cfe659f4959b1c779dfa0985a40-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":794,"real_height_2x":1589}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Попробуем воспользоваться знаниями из документации и настроить поиск в адресной строке браузера с нуля. Скопируем базовый URL и перейдем по нему. Мы увидим надпись «Invalid request», потому что не задали никаких параметров поиска. Добавим параметр, который покажет контракты только по Ярославской области. Добавляем к базовому URL вопросительный знак, название параметра (в нашем случае <strong>customerregion</strong>), знак равенства и номер региона (в нашем случае <strong>76</strong>).","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/e14ad3ed16ce4d4f9f718410abaaba38-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/e14ad3ed16ce4d4f9f718410abaaba38-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":268,"real_height_2x":535},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/e14ad3ed16ce4d4f9f718410abaaba38-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/e14ad3ed16ce4d4f9f718410abaaba38-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":268,"real_height_2x":535}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Нажмем Enter и увидим JSON-объект с контрактами. JSON это формат данных, который похож на <a href=\"https://istories.media/workshops/2020/12/09/vvedenie-v-python-chast-6-slovari/\" data-type=\"usual\" target=\"_blank\">словари</a> в Python. У нас есть список <strong>data</strong>, и каждый элемент в этом списке это словарь, у которого есть ключи и их значения: номер контракта, дата подписания, цена заключения и так далее.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/9faeb13ae1414f31b9c2460c779a9747-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/9faeb13ae1414f31b9c2460c779a9747-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":660,"real_height_2x":1320},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/9faeb13ae1414f31b9c2460c779a9747-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/9faeb13ae1414f31b9c2460c779a9747-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":660,"real_height_2x":1320}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Работаем с госконтрактами через API и Python","type":"h2","className":""},{"data":"Наконец, попробуем получить такие же данные с помощью программирования. В текстовой области нашего файла main.py апишем небольшую функцию: <strong>def get_contracts_by_region():</strong>. Пока она ничего не будет делать, поэтому внизу напишем <strong>pass</strong> — это ключевое слово будет временной «заглушкой».&nbsp;","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/caa57a308c9b485db9013a43cfced825-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/caa57a308c9b485db9013a43cfced825-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":320,"real_height_2x":640},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/caa57a308c9b485db9013a43cfced825-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/caa57a308c9b485db9013a43cfced825-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":320,"real_height_2x":640}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь скопируем URL из браузера, который мы использовали для поиска госконтрактов по Ярославской области через API, создадим в проекте переменную <strong>url</strong> вместо <strong>pass</strong> и вставим туда наш адрес (не забывайте про кавычки).","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/17cb7c972c214717b446d9738b3fb29f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/17cb7c972c214717b446d9738b3fb29f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":228,"real_height_2x":457},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/17cb7c972c214717b446d9738b3fb29f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/17cb7c972c214717b446d9738b3fb29f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":228,"real_height_2x":457}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Далее используем нашу библиотеку Requests: на следующей строке дописываем data = requests.get(url), как делали в начале урока, и добавляем формат получаемых данных <strong>json</strong> (а не <strong>text</strong>, как до этого). Эти данные нам нужно вернуть с помощью <strong>return data</strong>.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/42a77cf49d0745b4a01e36c42c388e46-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/42a77cf49d0745b4a01e36c42c388e46-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":229,"real_height_2x":458},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/42a77cf49d0745b4a01e36c42c388e46-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/42a77cf49d0745b4a01e36c42c388e46-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":229,"real_height_2x":458}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Теперь проверим результат: присвоим нашей функции <strong>get_contracts_by_region()</strong> значение <strong>result</strong> и с помощью <strong>print</strong> посмотрим, что у нас получилось.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/7c69770cf0744f9dbbf6ef40a5ee4a07-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/7c69770cf0744f9dbbf6ef40a5ee4a07-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":662,"real_height_2x":1324},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/7c69770cf0744f9dbbf6ef40a5ee4a07-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/7c69770cf0744f9dbbf6ef40a5ee4a07-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":662,"real_height_2x":1324}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Как видите, сейчас в терминале мы получили тот же список контрактов, который до этого видели в браузере, но подготовленный для анализа программными методами.&nbsp;","type":"p","className":""},{"data":"Начинаем улучшать функцию","type":"h2","className":""},{"data":"Теперь сделаем так, чтобы наша функция возвращала данные не только из Ярославской области, но и из любого другого региона. Для этого зададим функции <strong>get_contracts_by_region()</strong> параметр <strong>region_code</strong> — этот параметр должен встать в следующую строку на место кода Ярославской области.&nbsp;","type":"p","className":""},{"data":"В <a href=\"https://istories.media/workshops/2020/11/18/vvedenie-v-python-chast-3/\" data-type=\"usual\" target=\"_blank\">одном из уроков</a> по введению в Python мы проходили форматирование строк, где рассказывали, что можно поставить букву <strong>f</strong> перед открывающими строку кавычками и далее внутрь кавычек вводить любые параметры в фигурных скобках <strong>{}</strong>. Сейчас это нам пригодится — вместо 76 мы вставим <strong>{region_code}</strong>.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2d2bce8ba5864e9b9639359be8577747-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2d2bce8ba5864e9b9639359be8577747-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":338,"real_height_2x":676},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2d2bce8ba5864e9b9639359be8577747-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/2d2bce8ba5864e9b9639359be8577747-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":338,"real_height_2x":676}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Попробуем снова вызвать нашу функцию, но уже с другим регионом 78 (Санкт-Петербург). Для этого в строку <strong>result get_contracts_by_region()</strong> добавим в скобки номер региона и запустим <strong>print</strong> еще раз.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"В терминале мы получили все контракты из Санкт-Петербурга","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/a30e2550a4bb4857a72642fcece5be00-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/a30e2550a4bb4857a72642fcece5be00-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":695,"real_height_2x":1390},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/a30e2550a4bb4857a72642fcece5be00-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/a30e2550a4bb4857a72642fcece5be00-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":695,"real_height_2x":1390}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В следующих уроках мы продолжим улучшать функцию, добавляя ей новые возможности —&nbsp;чтобы она возвращала данные не только по регионам, но и по дате подписания, цене и другим параметрам, которые мы видели в документации к API портала «ГосЗатраты». Если у вас возникли вопросы по уроку — не стесняйтесь задавать их в нашем <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">чате</a> в Telegram.","type":"p","className":""}]},{"id":252,"header":"Пишем своего робота на Python. Урок 2","_path":"/workshops/2021/04/16/pishem-svoego-robota-na-python-urok-2/","lead":"Создаем виртуальное окружение и устанавливаем сторонние библиотеки","entry_image":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-1920x960px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-1920x960px_2x.webp","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-1920x960px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-1920x960px_2x.jpg","for_width":1920,"for_height":960,"real_width_1x":1920,"real_width_2x":3840,"real_height_1x":960,"real_height_2x":1920},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-1272x636px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-1272x636px_2x.webp","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-1272x636px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-1272x636px_2x.jpg","for_width":1272,"for_height":636,"real_width_1x":1272,"real_width_2x":2544,"real_height_1x":636,"real_height_2x":1272},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-912x456px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-912x456px_2x.webp","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-912x456px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-912x456px_2x.jpg","for_width":912,"for_height":456,"real_width_1x":912,"real_width_2x":1824,"real_height_1x":456,"real_height_2x":912},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-600x400px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-600x400px_2x.webp","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-600x400px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-600x400px_2x.jpg","for_width":600,"for_height":400,"real_width_1x":600,"real_width_2x":1200,"real_height_1x":400,"real_height_2x":800},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-360x360px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-360x360px_2x.webp","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-360x360px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/76cd8d4e069547e4ac217b01d33c7da5-360x360px_2x.jpg","for_width":360,"for_height":360,"real_width_1x":360,"real_width_2x":720,"real_height_1x":360,"real_height_2x":720}],"entry_image_credit":"","created_at_date":"2021-04-16","created_at_date_time":null,"updated_at_date":null,"updated_at_date_time":null,"is_exclusive":false,"is_urgent":false,"spec_project":null,"has_visualization_without_fallback":false,"has_additional_facts":false,"category":"workshops","locale":"ru","authors_list":[{"id":5,"first_name":"Роман","last_name":"Анин","first_name_en":"Roman","last_name_en":"Anin","is_public":true,"_path":"roman-anin","avatar":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-896x504px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-896x504px_2x.webp","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-896x504px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-896x504px_2x.jpg","for_width":896,"for_height":504,"real_width_1x":896,"real_width_2x":1792,"real_height_1x":504,"real_height_2x":1008},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-688x387px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-688x387px_2x.webp","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-688x387px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-688x387px_2x.jpg","for_width":688,"for_height":387,"real_width_1x":688,"real_width_2x":1376,"real_height_1x":387,"real_height_2x":774},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-416x234px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-416x234px_2x.webp","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-416x234px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-416x234px_2x.jpg","for_width":416,"for_height":234,"real_width_1x":416,"real_width_2x":832,"real_height_1x":234,"real_height_2x":468},{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-336x189px_1x.webp","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-336x189px_2x.webp","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378},{"format":"jpg","url_1x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-336x189px_1x.jpg","url_2x":"https://static.istories.media/uploaded/images/1435d3e9c5384ab4902bab6b024b8c38-336x189px_2x.jpg","for_width":336,"for_height":189,"real_width_1x":336,"real_width_2x":672,"real_height_1x":188,"real_height_2x":378}],"lead":"Редактор «Важных историй»","lead_en":"","position":"Редактор","position_en":"Editor","ordering":null}],"external_authors_list":[],"editors_list":[],"external_editors_list":[],"participants_list":[],"external_participants_list":[],"case":null,"topics":[],"body_preview":"Продолжаем наш журналистский проект, в котором мы на практике будем применять наши журналистские знания — мы напишем робота на Python, который еженедельно (или ежедневно, как захотите) будет собирать крупнейшие госконтракты в России, упаковывать их в удобную для анализа форму и отправлять нам на почту.\n\nВ первом уроке мы установили редактор Visual Studio Code и изучили базовые команды терминала. Сегодня мы поговорим о виртуальном окружении проекта и установим некоторые необходимые библиотеки. \n\nДля чего нужно виртуальное окружение\n\nКогда вы пишите что-то на языке Python, вы почти всегда будете использовать сторонние библиотеки. У этих библиотек есть различные версии. Разные приложения могут использовать одни и те же библиотеки, но разных версий, и если версия библиотеки не будет совпадать с требуемой приложением, могут возникнуть сбои. Как раз для того, чтобы избежать таких ошибок, нужно создавать виртуальное окружение. \n\nСоздаем виртуальное окружение\n\nОткрываем наш проект main.py в Visual Studio Code и проверяем, в какой версии Python мы сейчас работаем. Для этого в терминале печатаем type python3. У меня 3.7 — это основная версия Python, установленная на моем компьютере. У вас путь к локации может отличаться, если вы устанавливали Python с помощью Anaconda. \nВ Python несколько способов создания виртуального окружения. Мы будем использовать инструмент Pipenv — для начала нам нужно его установить. Пишем в терминале команду pip install pipenv и нажимаем «Enter». pip это менеджер пакетов, который позволяет устанавливать сторонние библиотеки, install это команда установки, а pipenv, соответственно — название библиотеки.\nБиблиотека установлена, теперь создаем виртуальное окружение — печатаем pipenv shell и выполняем команду. У нас должно появиться сообщение, что виртуальное окружение успешно создано.\nСнова проверим нашу версию Python — вводим type python3. Теперь у нас другая версия, изолированная в своем виртуальном окружении. \n\nЧтобы убедиться, что мы работаем именно с этой версией Python, нажимаем Command (Ctrl для Windows) + Shift + P — сверху появляется строка панели управления. Там мы ищем опцию «Select Interpreter». Нам нужно выбрать именно тот интерпретатор, который мы установили в виртуальном окружении. У нас его название начинается с «robot», поэтому печатаем «robot» в той же строке и кликаем на появившееся полное название.\n\nЕсли в этом списке нет пути к нужной версии Python, то можно «убить» терминал — нажмите на иконку корзины в окне терминала, снова Command/Ctrl + Shift + P и повторите операцию с «Select Interpreter». Если даже это не помогло, попробуйте закрыть и снова открыть приложение Visual Studio Code. \n\nТак мы настроили виртуальное окружение. Теперь каждый раз, когда мы будем открывать наш проект, нам нужно будет всего лишь активировать его — для этого нужно ввести в терминале уже знакомую нам команду pipenv shell.\n\nПосле создания виртуального окружения в папке приложения появился файл с названием «Pipfile». В нем перечислены требования и необходимые пакеты для нашего проекта. Пока в нашем проекте нет сторонних библиотек, поэтому единственное требование там пока — Python версии 3.7. \n\nУстанавливаем первую библиотеку\n\nПервая библиотека, которая понадобится для нашего проекта — Requests, с ее помощью мы будем делать запросы и получать данные из интернета. Для установки печатаем в терминале pipenv install requests и нажимаем «Enter».\n\nЕсли мы откроем наш Pipfile, то увидим, что библиотека Requests появилась в списке требований.  Кроме того, в папке проекта появился еще один новый файл — «Pipfile.lock». \nЗдесь находятся расширенные сведения о наших пакетах — например, точная версия библиотеки Request, которую мы установили. \n\nНа сегодня это все. А в следующем уроке мы наконец-то начнем писать код и работать с реальными данными. Появились вопросы? Пишите в наш чат в Telegram, постараемся ответить.","blocks":[{"data":"Продолжаем наш журналистский проект, в котором мы на практике будем применять наши журналистские знания — мы напишем робота на Python, который еженедельно (или ежедневно, как захотите) будет собирать крупнейшие госконтракты в России, упаковывать их в удобную для анализа форму и отправлять нам на почту.","type":"p","className":""},{"data":"В первом уроке мы установили редактор Visual Studio Code и изучили базовые команды терминала. Сегодня мы поговорим о виртуальном окружении проекта и установим некоторые необходимые библиотеки.&nbsp;","type":"p","className":""},{"data":{"id":3060,"data":{"url":"https://www.youtube.com/embed/H94Aicz-Hyc","text":"Видео: Глеб Лиманский","provider":"youtube","rawInput":"https://youtu.be/H94Aicz-Hyc","ratio_mobile":"16:9","ratio_desktop":"16:9"},"category":"video-embed"},"type":"video-embed"},{"data":"Для чего нужно виртуальное окружение","type":"h2","className":""},{"data":"Когда вы пишите что-то на языке Python, вы почти всегда будете использовать сторонние библиотеки. У этих библиотек есть различные версии. Разные приложения могут использовать одни и те же библиотеки, но разных версий, и если версия библиотеки не будет совпадать с требуемой приложением, могут возникнуть сбои. Как раз для того, чтобы избежать таких ошибок, нужно создавать виртуальное окружение.&nbsp;","type":"p","className":""},{"data":"Создаем виртуальное окружение","type":"h2","className":""},{"data":"Открываем наш проект main.py в Visual Studio Code и проверяем, в какой версии Python мы сейчас работаем. Для этого в терминале печатаем<strong> type python3</strong>. У меня 3.7 — это основная версия Python, установленная на моем компьютере. У вас путь к локации может отличаться, если вы устанавливали Python с помощью Anaconda.&nbsp;","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/2ce5ce6ec7fa40adb585e7324b2c959f-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/2ce5ce6ec7fa40adb585e7324b2c959f-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":750,"real_height_2x":1500},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/2ce5ce6ec7fa40adb585e7324b2c959f-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/2ce5ce6ec7fa40adb585e7324b2c959f-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":750,"real_height_2x":1500}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"В Python несколько способов создания виртуального окружения. Мы будем использовать инструмент Pipenv — для начала нам нужно его установить. Пишем в терминале команду<strong> pip install pipenv</strong> и нажимаем «Enter». <strong>pip</strong> это менеджер пакетов, который позволяет устанавливать сторонние библиотеки, <strong>install</strong> это команда установки, а <strong>pipenv</strong>, соответственно&nbsp;—&nbsp;название библиотеки.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/5888debc02534c9fbe4270a924ada467-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/5888debc02534c9fbe4270a924ada467-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":750,"real_height_2x":1500},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/5888debc02534c9fbe4270a924ada467-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/5888debc02534c9fbe4270a924ada467-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":750,"real_height_2x":1500}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Библиотека установлена, теперь создаем виртуальное окружение — печатаем <strong>pipenv shell </strong>и выполняем команду. У нас должно появиться сообщение, что виртуальное окружение успешно создано.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/269804d6d2214c2aba15a450061392e7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/269804d6d2214c2aba15a450061392e7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":750,"real_height_2x":1500},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/269804d6d2214c2aba15a450061392e7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/269804d6d2214c2aba15a450061392e7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":750,"real_height_2x":1500}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Снова проверим нашу версию Python — вводим <strong>type python3</strong>. Теперь у нас другая версия, изолированная в своем виртуальном окружении. ","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/b7222243b51f4fc5897f706532a928c7-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/b7222243b51f4fc5897f706532a928c7-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":750,"real_height_2x":1500},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/b7222243b51f4fc5897f706532a928c7-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/b7222243b51f4fc5897f706532a928c7-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":750,"real_height_2x":1500}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Чтобы убедиться, что мы работаем именно с этой версией Python, нажимаем <strong>Command</strong> (<strong>Ctrl</strong> для Windows) <strong>+ Shift + P</strong> — сверху появляется строка панели управления.&nbsp;Там мы ищем опцию «Select Interpreter». Нам нужно выбрать именно тот интерпретатор, который мы установили в виртуальном окружении. У нас его название начинается с «robot», поэтому печатаем «robot» в той же строке и кликаем на появившееся полное название.","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/73082542e6e944a7b4c53ca0e897cb2e-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/73082542e6e944a7b4c53ca0e897cb2e-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":750,"real_height_2x":1500},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/73082542e6e944a7b4c53ca0e897cb2e-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/73082542e6e944a7b4c53ca0e897cb2e-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":750,"real_height_2x":1500}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если в этом списке нет пути к нужной версии Python, то можно «убить»&nbsp;терминал — нажмите на иконку корзины в окне терминала, снова <strong>Command/Ctrl + Shift + P</strong> и повторите операцию с «Select Interpreter». Если даже это не помогло, попробуйте закрыть и снова открыть приложение Visual Studio Code.&nbsp;","type":"p","className":""},{"data":"Так мы настроили виртуальное окружение. Теперь каждый раз, когда мы будем открывать наш проект, нам нужно будет всего лишь активировать его — для этого нужно ввести в терминале уже знакомую нам команду <strong>pipenv shell</strong>.","type":"p","className":""},{"data":"После создания виртуального окружения в папке приложения появился файл с названием «Pipfile». В нем перечислены требования и необходимые пакеты для нашего проекта. Пока в нашем проекте нет сторонних библиотек, поэтому единственное требование там пока — Python версии 3.7.&nbsp;","type":"p","className":""},{"data":"Устанавливаем первую библиотеку","type":"h2","className":""},{"data":"Первая библиотека, которая понадобится для нашего проекта —&nbsp;Requests, с ее помощью мы будем делать запросы и получать данные из интернета. Для установки печатаем в терминале <strong>pipenv install requests</strong> и нажимаем «Enter».","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/40267b19f159497a9e4fba0e6f4c3ade-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/40267b19f159497a9e4fba0e6f4c3ade-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":685,"real_height_2x":1370},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/40267b19f159497a9e4fba0e6f4c3ade-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/40267b19f159497a9e4fba0e6f4c3ade-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":685,"real_height_2x":1370}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Если мы откроем наш Pipfile, то увидим, что библиотека Requests появилась в списке требований.&nbsp; Кроме того, в папке проекта появился еще один новый файл — «Pipfile.lock». ","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/efd65cb8b507458db6114020914fb93a-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/efd65cb8b507458db6114020914fb93a-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":750,"real_height_2x":1500},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/efd65cb8b507458db6114020914fb93a-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/efd65cb8b507458db6114020914fb93a-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":750,"real_height_2x":1500}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"Здесь находятся расширенные сведения о наших пакетах — например, точная версия библиотеки Request, которую мы установили.&nbsp;","type":"p","className":""},{"data":{"data":{"images":[{"credit":"","caption":"","imagesList":[{"format":"webp","url_1x":"https://static.istories.media/uploaded/images/3bc9c709325240fdb3dfc8ec24cc63e4-1200xautopx_1x.webp","url_2x":"https://static.istories.media/uploaded/images/3bc9c709325240fdb3dfc8ec24cc63e4-1200xautopx_2x.webp","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":678,"real_height_2x":1356},{"format":"png","url_1x":"https://static.istories.media/uploaded/images/3bc9c709325240fdb3dfc8ec24cc63e4-1200xautopx_1x.png","url_2x":"https://static.istories.media/uploaded/images/3bc9c709325240fdb3dfc8ec24cc63e4-1200xautopx_2x.png","for_width":1200,"for_height":"auto","real_width_1x":1200,"real_width_2x":2400,"real_height_1x":678,"real_height_2x":1356}]}]},"category":"image-embed"},"type":"image-embed"},{"data":"На сегодня это все. А в следующем уроке мы наконец-то начнем писать код и работать с реальными данными. Появились вопросы? Пишите в наш <a href=\"https://t.me/istories_helloworld\" data-type=\"usual\" target=\"_blank\">чат</a> в Telegram, постараемся ответить.","type":"p","className":""}]}],"more":true,"limit":30,"category":"workshops","locale":"ru"}},"staticQueryHashes":["764694655"],"slicesMap":{}}