Как взаимодействовать с сайтом программно?
Пишу программу для домашнего использования.
Голосовой помощник на Python. Через VK API, реализовал отправку сообщений, также есть функции выключения ПК, озвучивания даты, времени и дня недели и некоторые другие.
Хочу реализовать переключение музыки в ВК, но никак не получается.
В исходном коде ВК нашел JS-функции, отвещающие за переключение музыки, можно ли их как-нибудь программно забить в консоль Google Chrome?
Также есть еще идея с запуском Google Chrome сниппетов с JS-функцией, но информации по их программному запуску тоже не нашел.
Хотелось бы разобраться с программным взаимодействием с сайтами.
- Вопрос задан более двух лет назад
- 349 просмотров
Комментировать
Решения вопроса 0
Ответы на вопрос 3
Тебе нужно чётче сформулировать задачу.
Если ты хочешь отправить запрос на простой сайт (имитировать открытие ссылки), то это одна задача. Достаточно будет использовать библиотеку типа requests.
Если ты хочешь работать с сайтом, который обвешан javascript (как ВК), то это уже другое дело. Тут requests будет недостаточно, или его использование будет затруднительно из-за необходимости расковыривать устройство сайта. Нужно использовать безголовый браузер типа selenium. Но результаты работы с сайтом будут «заперты» в скрипте, т.е. вещи типа прослушивания музыки с сайта уже будут проблематичны.
Впрочем, селениум вроде умеет работать с обычным окном браузера, почитай доки по нему. Если это так, то под твою задачу должно подойти.
Наконец, если ничто другое не помогает, pywinauto или pyautogui позволяют имитировать клики мышью и нажатия клавиш в окнах других приложений. pywinauto менее популярен, но pyautogui требует, чтобы приложение находилось на переднем плане.
Ответ написан более двух лет назад
De4oult @De4oult Автор вопроса
Как раз взаимодействие с элементами сайта на JS, а не с банальным переходом по ссылкам с помощью requests.
На кнопки переключения музыки ВК назначены эти JS-функции:
getAudioPlayer().playPrev()
getAudioPlayer().playNext()
Мне нужно их как-то реализовать на самом сайте
Взаимодействие с сайтами
Здравствуйте, заинтересовала тема написания всевозможных ботов, хочу начать изучать методы реализации, но пока даже смутно понимаю как правильно составить запрос в гугле))
Интересует взаимодействие с всевозможными сайтами типа букмекеров/казино или биржи на которой отсутствует апи, со всеми вытекающими. То есть сбор информации, переход по страницам, ввод данных в окна, ставки и тд. Не знаю как все это правильно уместить в короткую фразу.
Подскажите куда копать или какие то ресурсы где можно наковырять подобную информацию, спасибо.
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Взаимодействие с сайтами
Всем привет. Задался вопросом, а как мне залезть на какой-нибудь сайт и что-то там сделать.
Взаимодействие с сайтами и JS
Помогите разобраться, как передавать параметры( и получать) от скрипта, который на сайтике. То есть.
Взаимодействие с сайтами
Подскажите пожалуйста, где можно найти нужную литературу для достижения следующей задачи. Мне.
Взаимодействие с другими сайтами
Здравствуйте. Только начинаю осваивать asp и даже не представляю, что именно мне нужно искать).
Взаимодействие PHP с другими сайтами
Нужны функции PHP, с помощью которых можно взаимодействовать с другими сайтами. Например, переход.
150 / 85 / 35
Регистрация: 05.08.2017
Сообщений: 257
Сообщение от Banka11
Здравствуйте, заинтересовала тема написания всевозможных ботов, хочу начать изучать методы реализации, но пока даже смутно понимаю как правильно составить запрос в гугле))
Интересует взаимодействие с всевозможными сайтами типа букмекеров/казино или биржи на которой отсутствует апи, со всеми вытекающими. То есть сбор информации, переход по страницам, ввод данных в окна, ставки и тд. Не знаю как все это правильно уместить в короткую фразу.
Подскажите куда копать или какие то ресурсы где можно наковырять подобную информацию, спасибо.
Тут зависит от конкретного сайта, на некоторых сайтах информация подгружается через ajax запросы, соответственно можно делать запрос к API(хотя сам сайт может его и не афишировать), это самый легкий путь. Найти ajax запрос можно через просмотр кода->Network->XHR(это Google Chrome, погугли парсинг ajax), в основном данные передаются в виде JSON(в таком случае можно обойтись библиотекой requests и модулем json). Если не нашел нужный ajax запрос, то тогда делаешь http запрос на саму страницу и парсишь библиотекой beautifulsoup4. Для имитации браузера можно воспользоваться selenium web driver. А реализацию ставок и т.д. я бы предпочел делать в виде расширения на javascript для того же google chrome
Скрапинг веб-сайтов на Python — пошаговое руководство
Научитесь парсить веб-страницы с помощью Python, чтобы быстро собирать данные с нескольких сайтов с экономией времени и усилий.
3 min read
Antonello Zanini
Узнайте, как выполнять веб-скрапинг с помощью Python, чтобы быстро собирать данные с различных сайтов, экономя время и силы.
Веб-скрапинг — извлечение данных с сайтов в интернете. В частности, парсер —инструмент, позволяющий осуществлять веб-скрапинг. Python является одним из самых простых языков программирования и содержит большое количество библиотек для веб-скрапинга. Это делает его идеальным вариантом для парсинга сайтов. Скрипт для веб-скрапинга на Python требует относительно небольшого количества кода!
В этом пошаговом руководстве вы узнаете, как создать простой парсер на языке Python. Это приложение будет обходить весь сайт, извлекать данные с каждой его страницы и экспортировать их в CSV-файл. Данное руководство поможет вам понять, какие библиотеки для сбора данных на языке Python являются лучшими, какие из них следует взять на вооружение и как именно их использовать. Следуйте этому пошаговому руководству и узнайте, как создать Python-скрипт для веб-скрапинга.
Требования
Чтобы создать парсер Python, вам необходимы:
Обратите внимание, что pip по умолчанию включен в состав Python версии 3.4 и выше. Поэтому устанавливать его вручную не требуется. Если на вашем компьютере нет Python, следуйте приведенному ниже руководству для вашей операционной системы
macOS
Раньше компьютеры Mac поставлялись с предустановленным Python 2.7, но теперь это уже не так, поскольку эта версия устарела.
Если вам нужна последняя версия Python, ее необходимо установить вручную. Для этого загрузите программу установки, дважды щелкните по ней, чтобы запустить, и следуйте указаниям мастера установки.
Windows
Загрузите программу установки Python и запустите ее. Во время работы мастера установки убедитесь, что отмечен флажок «Добавить python.exe в PATH», как показано ниже:
Таким образом, Windows будет автоматически распознавать команды python и pip в терминале. Напомним, что pip — менеджер пакетов для Python.
Linux
В большинстве дистрибутивов Linux Python уже предустановлен, однако речь может идти не о самой последней версии. Команда для установки или обновления Python в Linux зависит от менеджера пакетов. В дистрибутивах Linux на базе Debian выполните команду:
sudo apt-get install python3
Независимо от используемой ОС, откройте терминал и убедитесь, что Python успешно установлен:
python --version
В результате должно получиться что-то вроде этого:
Python 3.11.0
Теперь все готово для создания вашего первого парсера Python. Но сначала вам нужна библиотека веб-скрапинга Python!
Лучшие библиотеки веб-скрапинга Python
Можно создать скрипт веб-парсера с нуля с помощью ванильного Python, но это не идеальное решение. В конце концов, Python известен своим обширным выбором пакетов и, в частности, есть масса библиотек для веб-скрапинга. Пришло время рассмотреть наиболее важные из них!
Requests
Библиотека Requests позволяет выполнять HTTP-запросы на языке Python. Она упрощает отправку HTTP-запросов, особенно по сравнению со стандартной библиотекой Python HTTP. Requests играет ключевую роль в проекте для веб-скрапинга на Python. Это связано с тем, что для сбора данных, содержащихся на странице, необходимо сначала получить их с помощью HTTP-запроса GET. Кроме того, возможно, придется выполнить и другие HTTP-запросы к серверу целевого сайта.
Установить Requests можно с помощью следующей команды pip:
pip install requests
Beautiful Soup
Python-библиотека Beautiful Soup упрощает сбор информации со страниц. В частности, Beautiful Soup работает с любым HTML- или XML-парсером и предоставляет все необходимое для итерации, поиска и модификации абстрактного синтаксического дерева. Обратите внимание, что Beautiful Soup можно использовать вместе с html.parser — парсером, входящим в стандартную библиотеку Python и позволяющим парсить текстовые HTM-файлы. В частности, Beautiful Soup помогает обходить DOM и извлекать из него нужные данные.
Установить Beautiful Soup с помощью программы pip можно следующим образом:
pip install beautifulsoup4
Selenium
Selenium — современная система автоматизированного тестирования с открытым исходным кодом, позволяющая выполнять операции на странице в браузере. Другими словами, с его помощью можно поручить браузеру выполнение определенных задач. Обратите внимание, что Selenium также можно использовать в качестве библиотеки для веб-скрапинга благодаря его возможностям «безголового» браузера. Если вы не знакомы с этим понятием, то речь идет о веб-браузере, работающем без графического интерфейса пользователя (GUI). Если Selenium настроен в безголовом режиме, он будет запускать управляемый браузер, образно говоря «закулисно».
Интернет-страницы, посещаемые в Selenium, отображаются в реальном браузере. Таким образом, Selenium поддерживает веб-парсинг страниц, которые используют JavaScript для рендеринга или получения данных. Selenium предоставляет все необходимое для создания парсера, не требуя использования других библиотек. Установить его можно с помощью следующей команды pip:
pip install selenium
Создание парсера на Python
Теперь давайте узнаем, как создать веб-парсер на языке Python. Вот как выглядит целевой сайт:
Это сайт Quotes to Scrape — «песочница» для веб-скрапинга, содержащая постраничный список цитат.
Цель этого урока — научиться извлекать из него данные: текст, автора и список тегов для каждой цитаты. Затем полученная информация будет преобразована в CSV-формат.
Как видите, Quotes to Scrape — это не что иное, как песочница для парсинга веб-страниц. Сайт содержит разбитый на страницы список цитат. Парсер Python, который вы собираетесь создать, извлечет все цитаты на каждой странице, и предоставит их в виде данных CSV.
Шаг 1: Выбор правильных библиотек для веб-скрапинга на языке Python
Прежде всего, необходимо понять, какие библиотеки для веб-скрапинга на языке Python лучше всего подходят для достижения поставленной цели. Для этого посетите целевой сайт в браузере. Щелкните правой кнопкой мыши по странице и выберите «Просмотреть код». Откроется окно браузера DevTools. Перейдите на вкладку «Сеть» и перезагрузите страницу.
Как вы заметили, целевой сайт не выполняет никаких Fetch/XHR-запросов.
Это означает, что Quotes to Scrape не использует JavaScript для динамического извлечения данных. Другими словами, страницы, возвращаемые сервером, уже содержат интересующие данные. Именно так происходит на сайтах со статическим контентом.
Поскольку целевой сайт не использует JavaScript для вывода страницы или получения данных, Selenium для его сканирования не нужен. Вы можете использовать его, но это не обязательно. Причина в том, что Selenium открывает страницы в браузере. Поскольку это требует времени и ресурсов, Selenium снижает производительность. Этого можно избежать, используя Beautiful Soup вместе с Requests.
Теперь, когда вы поняли, какие библиотеки для веб-скрапинга на Python следует использовать, узнайте, как создать простой парсер с помощью Beautiful Soup!
Шаг 2: Инициализация проекта Python
Прежде чем написать первую строку кода, необходимо настроить проект для веб-скрапинга на языке Python. Технически для этого достаточно одного файла .py. Однако использование продвинутой IDE (Integrated Development Environment) облегчит вам работу c кодом. Здесь мы рассмотрим настройку Python-проекта в PyCharm, но подойдет и любая другая IDE для Python.
Откройте PyCharm и выберите «File > New Project… ». Во всплывающем окне «Новый проект» выберите «Чистый Python» и создайте новый проект.
Например, вы можете назвать свой проект python-web-scraper. Нажмите кнопку «Создать», и вы получите доступ к своему пустому Python-проекту. По умолчанию PyCharm инициализирует файл main.py. Для наглядности переименуйте его в scraper.py. Вот как теперь будет выглядеть ваш проект:
PyCharm автоматически инициализирует Python-файл со стандартным кодом. Удалите его, чтобы начать писать код с нуля.
Далее необходимо установить зависимости проекта. Установить Requests и Beautiful Soup можно, выполнив в терминале следующую команду:
pip install requests beautifulsoup4
Это приведет к одновременной установке двух библиотек. Дождитесь завершения процесса установки. Теперь вы готовы использовать Beautiful Soup и Requests для создания веб-краулера и парсера на Python. Убедитесь в импорте двух библиотек, добавив следующие строки в верхнюю часть файла сценария scraper.py:
import requests from bs4 import BeautifulSoup
PyCharm подсветит эти две строки серым цветом, потому что библиотеки не используются в коде. Если он подчеркнет их красным цветом, значит, что-то пошло не так в процессе установки. В этом случае попробуйте установить их снова.
Теперь вы готовы приступить к написанию логики веб-скрапинга на языке Python.
Шаг 2: Подключение к целевому URL
Первое, что необходимо сделать в веб-парсере — подключиться к целевому сайту. Для этого необходимо получить полный URL-адрес страницы из браузера. Обязательно скопируйте также секцию http:// или https:// HTTP-протокола. В данном случае это полный URL целевого сайта:
https://quotes.toscrape.com
Теперь вы можете использовать запросы для загрузки страницы с помощью следующей строки кода:
page = requests.get('https://quotes.toscrape.com')
Эта строка просто присваивает результат работы метода request.get() переменной page. Закулисно request.get() выполняет GET-запрос с использованием URL, переданного в качестве параметра. Затем он возвращает объект Response, содержащий ответ сервера на HTTP-запрос.
Если HTTP-запрос выполнен успешно, page.status_code будет содержать статус 200. Код ответа HTTP 200 OK означает, что HTTP-запрос был выполнен успешно. Статус HTTP 4xx или 5xx означает ошибку. Она может произойти по целому ряду причин, но следует помнить, что большинство сайтов блокируют запросы, не содержащие корректного User-Agent. Этот специальный заголовок представляет собой строку, характеризующую версию приложения и операционной системы, с которой поступил запрос. Подробнее о User-Agent для веб-скрапинга.
Задать допустимый заголовок User-Agent в запросах можно следующим образом:
headers = < 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' >page = requests.get('https://quotes.toscrape.com', headers=headers
Requests теперь будет выполнять HTTP-запрос с заголовками, переданными в качестве параметра.
На что следует обратить внимание, так это на свойство page.text . В нем будет содержаться HTML-документ, возвращенный сервером в строковом формате. Передайте свойство text в программу Beautiful Soup, чтобы извлечь данные со страницы. Давайте узнаем, как это сделать.
На что следует обратить внимание, так это на свойство page.text. В нем будет содержаться HTML-документ, возвращенный сервером в строковом формате. Передайте свойство text в программу Beautiful Soup для парсинга страницы. Как это сделать, узнаем на следующем шаге!
Шаг 3: Парсинг содержимого HTML-документа
Чтобы выполнить парсинг HTML-документа, возвращенного сервером после GET-запроса, передайте конструктору BeautifulSoup() файл page.text:
soup = BeautifulSoup(page.text, 'html.parser')
Второй параметр задает парсер, который будет использовать Beautiful Soup.
Теперь переменная soup содержит объект BeautifulSoup. Это древовидная структура, созданная в результате разбора HTML-документа, содержащегося в page.text, с помощью встроенного в Python парсера html.parser.
Теперь вы можете использовать его для выбора нужного HTML-элемента на странице. Смотрите, как!
Шаг 4: Выделение HTML-элементов с помощью Beautiful Soup
Beautiful Soup предлагает несколько подходов к выбору элементов в DOM. Отправными точками являются:
- find(): Возвращает первый HTML-элемент, соответствующий введенному селектору, если таковой вообще имеется.
- find_all(): Возвращает список HTML-элементов, удовлетворяющих условию селектора, переданному в качестве параметра.
В зависимости от параметров, передаваемых этим двум методам, они будут искать элементы на странице по-разному. В частности, можно выбрать элементы HTML:
# get all elements # on the page h1_elements = soup.find_all('h1')
# get the element with main_title_element = soup.find(id='main-title')
# find the footer element # based on the text it contains footer_element = soup.find(text=)
# find the email input element # through its "name" attribute email_element = soup.find(attrs=)
# find all the centered elements # on the page centered_element = soup.find_all(class_='text-center')
Объединение этих методов позволяет извлекать данные из любого HTML-элемента на странице. Обратите внимание на приведенный ниже пример:
# get all "li" elements # in the ".navbar" element soup.find(class_='navbar').find_all('li')
Чтобы упростить работу, в Beautiful Soup можно также использовать метод select(). Он позволяет применять CSS-селектор напрямую:
# get all "li" elements # in the ".navbar" element soup.select('.navbar > li')
Обратите внимание, что на момент написания статьи селекторы XPath не поддерживаются.
Важно усвоить, что для извлечения данных с интернет-страницы необходимо сначала определить интересующие вас HTML-элементы. В частности, важно определить стратегию выбора тех, которые содержат требующие извлечения данные.
Для этого можно воспользоваться предлагаемыми браузером инструментами для разработчиков. В браузере Chrome щелкните правой кнопкой мыши на интересующем вас HTML-элементе и выберите опцию «Просмотреть код». В данном случае это нужно сделать на элементе цитаты.
- Текст цитаты в HTML-элементе
- Автор цитаты в HTML-элементе
- Список тегов в элементе , каждый из которых содержится в HTML-элементе .
В частности, вы можете извлечь эти данные, используя следующие селекторы CSS в .quote:
Шаг 5: Извлечение данных из элементов
Во-первых, необходима структура данных, в которой будет храниться полученная благодаря парсингу информация. Для этого инициализируем переменную массива.
quotes = []
Затем с помощью Soup извлекаем из DOM элементы цитаты, применив определенный ранее CSS-селектор .quote:
quote_elements = soup.find_all('div', class_='quote')
Метод find_all() вернет список всех HTML-элементов
, идентифицированных классом quote. Итерация по списку цитат для получения данных о них приведена ниже:
for quote_element in quote_elements: # extract the text of the quote text = quote_element.find('span', class_='text').text # extract the author of the quote author = quote_element.find('small', class_='author').text # extract the tag HTML elements related to the quote tag_elements = quote_element.select('.tags .tag') # store the list of tag strings in a list tags = [] for tag_element in tag_elements: tags.append(tag_element.text)
Метод Beautiful Soup find() получит единственный интересующий элемент HTML. Поскольку строк тегов, которые связанны с цитатой, несколько, их следует хранить в списке.
Затем можно преобразовать полученные данные в словарь и добавить его в список цитат следующим образом:
quotes.append( < 'text': text, 'author': author, 'tags': ', '.join(tags) # merge the tags into a "A, B, . Z" string >)
Хранение данных в структурированном словаре облегчает доступ к ним и их понимание.
Отлично! Вы только что увидели, как извлечь все данные с одной страницы! Однако не забывайте, что у целевого сайта их гораздо больше. Пришло время научиться обходить весь сайт!
Шаг 6: Реализация логики поиска данных
Переходя по ссылке, содержащейся в этом HTML-элементе, можно легко перемещаться по всему сайту. Итак, начните с главной страницы и посмотрите, как перейти на каждую страницу, из которых состоит целевой сайт. Для этого достаточно найти HTML-элемент .next и извлечь из него относительную ссылку на следующую страницу.
Реализовать логику по обходу всего сайта можно следующим образом:
# the URL of the home page of the target website base_url = 'https://quotes.toscrape.com' # retrieve the page and initializing soup. # get the "Next →" HTML element next_li_element = soup.find('li', class_='next') # if there is a next page to scrape while next_li_element is not None: next_page_relative_url = next_li_element.find('a', href=True)['href'] # get the new page page = requests.get(base_url + next_page_relative_url, headers=headers) # parse the new page soup = BeautifulSoup(page.text, 'html.parser') # scraping logic. # look for the "Next →" HTML element in the new page next_li_element = soup.find('li', class_='next')
Цикл where выполняет итерацию по каждой странице до тех пор, пока не окажется на последней странице. Он извлекает относительный URL следующей страницы и использует его для создания полноценного URL-адреса для дальнейшего парсинга. Новая страница загружается, выполняется ее веб-скрапинг и та же логика повторяется снова.
Теперь вы знаете, как парсить многостраничный сайт. Осталось научиться преобразовывать извлеченные данные в более удобный формат, например CSV.
Шаг 7: Извлечение полученных данных в CSV-файл
Рассмотрим, как экспортировать список словарей, содержащих извлеченные данные, в CSV-файл. Для этого понадобится следующий код:
import csv # scraping logic. # reading the "quotes.csv" file and creating it # if not present csv_file = open('quotes.csv', 'w', encoding='utf-8', newline='') # initializing the writer object to insert data # in the CSV file writer = csv.writer(csv_file) # writing the header of the CSV file writer.writerow(['Text', 'Author', 'Tags']) # writing each row of the CSV for quote in quotes: writer.writerow(quote.values()) # terminating the operation and releasing the resources csv_file.close()
Этот фрагмент записывает данные о цитатах, содержащиеся в списке словарей, в файл quotes.csv . Обратите внимание, что csv является частью стандартной библиотеки Python. Поэтому его можно импортировать и использовать без установки каких-либо дополнительных зависимостей.
По сути, необходимо просто создать CSV-файл с помощью функции open(). Затем заполнить его функцией writerow() из объекта Writer библиотеки csv. В результате каждый словарь цитат будет записан в виде строки в CSV-формате.
Вы перешли от необработанных данных, содержащихся на сайте, к полуструктурированным данным, хранящимся в CSV-файле. Процесс извлечения данных завершен, и теперь вы можете взглянуть на свой полноценный Python-парсер.
Шаг 8: Собираем все вместе
Вот как выглядит готовый скрипт на Python для сбора данных:
import requests from bs4 import BeautifulSoup import csv def scrape_page(soup, quotes): # retrieving all the quote HTML element on the page quote_elements = soup.find_all('div', class_='quote') # iterating over the list of quote elements # to extract the data of interest and store it # in quotes for quote_element in quote_elements: # extracting the text of the quote text = quote_element.find('span', class_='text').text # extracting the author of the quote author = quote_element.find('small', class_='author').text # extracting the tag HTML elements related to the quote tag_elements = quote_element.find('div', class_='tags').find_all('a', class_='tag') # storing the list of tag strings in a list tags = [] for tag_element in tag_elements: tags.append(tag_element.text) # appending a dictionary containing the quote data # in a new format in the quote list quotes.append( < 'text': text, 'author': author, 'tags': ', '.join(tags) # merging the tags into a "A, B, . Z" string >) # the url of the home page of the target website base_url = 'https://quotes.toscrape.com' # defining the User-Agent header to use in the GET request below headers = < 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36' ># retrieving the target web page page = requests.get(base_url, headers=headers) # parsing the target web page with Beautiful Soup soup = BeautifulSoup(page.text, 'html.parser') # initializing the variable that will contain # the list of all quote data quotes = [] # scraping the home page scrape_page(soup, quotes) # getting the "Next →" HTML element next_li_element = soup.find('li', class_='next') # if there is a next page to scrape while next_li_element is not None: next_page_relative_url = next_li_element.find('a', href=True)['href'] # getting the new page page = requests.get(base_url + next_page_relative_url, headers=headers) # parsing the new page soup = BeautifulSoup(page.text, 'html.parser') # scraping the new page scrape_page(soup, quotes) # looking for the "Next →" HTML element in the new page next_li_element = soup.find('li', class_='next') # reading the "quotes.csv" file and creating it # if not present csv_file = open('quotes.csv', 'w', encoding='utf-8', newline='') # initializing the writer object to insert data # in the CSV file writer = csv.writer(csv_file) # writing the header of the CSV file writer.writerow(['Text', 'Author', 'Tags']) # writing each row of the CSV for quote in quotes: writer.writerow(quote.values()) # terminating the operation and releasing the resources csv_file.close()
Как здесь показано, веб-парсер можно создать менее чем за 100 строк кода. Этот скрипт Python способен обойти весь сайт, автоматически извлечь его данные и экспортировать их в CSV-файл.
Поздравляем! Вы только что узнали, как создать веб-парсер на Python с помощью Requests и Beautiful Soup!
Шаг 9: Запуск скрипта для веб-скрапинга на языке Python
Если вы являетесь пользователем PyCharm, запустите скрипт, нажав кнопку ниже:
Или запустите следующую команду Python в терминале внутри каталога проекта:
python scraper.py
Дождитесь окончания процесса, и вы получите доступ к файлу quotes.csv. Откройте его. Он должен содержать следующие данные:
Теперь у вас есть все 100 цитат, содержащихся на целевом сайте, в одном файле и в удобном для чтения формате!
Вывод
Из этого руководства вы узнали, как выполнять веб-скрапинг с помощью Python, что в этом случае необходимо для начала работы и какие библиотеки Python для парсинга являются лучшими. Затем на реальном примере мы показали, как использовать Beautiful Soup и Requests для создания приложения для веб-скрапинга. Как вы могли убедиться, для создания скрипта для парсинга на языке Python нужно не так уж и много кода.
Однако веб-скрапинг сопряжен с целым рядом проблем. В частности, все большую популярность приобретают технологии защиты от ботов и парсинга. Именно поэтому вам необходим современный инструмент для веб-скрапинга, который предлагает компания Bright Data.
Чтобы избежать проблем с блокировками, мы также рекомендуем выбрать прокси с учетом ваших потребностей из большого ассортимента прокси-сервисов Bright Data.
FAQ
Является ли Python подходящим языком для веб-скрапинга? Python не только отлично подходит для веб-скрапинга, но и считается одним из лучших для этого языков. Это объясняется его удобочитаемостью и относительной простотой. Кроме того, он имеет одно из самых больших сообществ в мире IT и предлагает широкий выбор библиотек и инструментов, предназначенных для парсинга. Является ли веб-скрапинг и краулинг частью науки о данных? Да, веб-скрапинг и краулинг являются частью большой области науки о данных. Скрапинг/кроулинг служит основой для всех других побочных продуктов, которые могут быть получены из структурированных и неструктурированных данных. К ним относятся аналитика, алгоритмические модели/результаты, инсайты и «применимые знания». Как с помощью Python получить с сайта конкретные данные? Веб-скрапинг данных с сайта с помощью Python подразумевает изучение страницы целевого URL, определение данных, которые необходимо извлечь, написание и выполнение кода извлечения данных, а также сохранение полученной информации в нужном формате. Как создать веб-парсер на Python? Первым шагом в создании веб-парсера с помощью Python является использование строковых методов для анализа сайта, затем сбор данных с него с использованием HTML-парсера и, наконец, взаимодействие с необходимыми формами и компонентами интернет-ресурса.
Скрапинг сайта с помощью Python: гайд для новичков
Пишем простой скрапер на Python для сайта с объявлениями о недвижимости. Получаем готовый очищенный готовый к экспорту датасет.
В этой статье мы разберемся, как создать HTML скрапер на Python, который получает неофициальный доступ к коду сайта и позволяет извлечь необходимые данные.
Безопасный веб-скрейпинг: как извлекать данные с сайтов, чтобы вас не заблокировали
Отличие от вызовов API
Альтернативный метод получения данных сайта — вызовы API. Взаимодействие с API — это официально предоставляемый владельцем сайта способ получения данных прямо из БД или обычных файлов. Обычно для этого требуется разрешение владельца сайта и специальный токен. Однако апи доступен не всегда, поэтому скрапинг так привлекателен, однако его законность вызывает вопросы.
Юридические соображения
Скрапинг может нарушать копирайт или правила использования сайта, особенно когда он используется для получения прибыли, конкурентного преимущества или причинения ущерба (например из-за слишком частых запросов). Однако скрапинг публично доступен и используется для личного использования, академических целей или безвредного некоммерческого использования.
Если данные являются платными, требуют регистрации, имеют явную защиту от скрапинга, содержат конфиденциальные данные или личные данные пользователей, то нужно избегать любого из видов скрапинга.
Установка Beautiful Soup в Python
Beautiful Soup — это Python библиотека для скрапинга данных сайтов через HTML код.
Установите последнюю версию библиотеки.
$ pip install beautifulsoup4
Чтобы делать запросы, установите requests (библиотеку для отправки HTTP запросов):
$ pip install requests
Импортируйте библиотеки в файле Python или Jupiter notebook:
from bs4 import BeautifulSoup import requests
И несколько стандартных библиотек, которые потребуются для скрапинга на Python:
import re from re import sub from decimal import Decimal import io from datetime import datetime import pandas as pd
Введение
Представьте, что мы хотим произвести скрапинг платформы, содержащей общедоступные объявления о недвижимости. Мы хотим получить цену недвижимости, ее адрес, расстояние, название станции и ближайший до нее тип транспорта для того, чтобы узнать, как цены на недвижимость распределяются в зависимости от доступности общественного транспорта в конкретном городе.
Предположим, что запрос приведет к странице результатов, которая выглядит следующим образом:
Как только мы узнаем, в каких элементах сайта хранятся необходимые данные, нам нужно придумать логику скрапинга, которая позволит нам получить всю нужную информацию из каждого объявления.
Нам предстоит ответить на следующие вопросы:
- Как получить одну точку данных для одного свойства (например данные из тега price в первом объявлении)?
- Как получить все точки данных для одного свойства со всей страницы (например все теги price с одной страницы)?
- Как получить все точки данных для одного свойства всех страниц с результатами (например все теги price со всех страниц с результатами)?
- Как устранить несоответствие, когда данные могут быть разных типов (например, есть некоторые объявления, в которых в поле цены указана цена по запросу. В конечном итоге у нас будет столбец, состоящий из числовых и строковых значений, что в нашем случае не позволяет провести анализ)?
- Как лучше извлечь сложную информацию (Например, предположим, что каждое объявление содержит информацию об общественном транспорте, например “0,5 мили до станции метро XY”)?
Логика получения одной точки данных
Все примеры кода для скрапинга на Python можно найти в Jupiter Notebook файле на GitHub автора.
Запрос кода сайта
Во-первых, мы используем поисковый запрос, который мы сделали в браузере в скрипте Python:
# поиск в определённой зоне url = 'https://www.website.com/london/page_size=25&q=london&pn=1' # делаем запрос и получаем html html_text = requests.get(url).text # используем парсер lxml soup = BeautifulSoup(html_text, 'lxml')
Переменная soup содержит полный HTML-код страницы с результатами поиска.
Поиск тегов-свойств
Для этого нам потребуется браузер. Некоторые популярные браузеры предлагают удобный способ получения информации о конкретном элементе напрямую. В Google Chrome вы можете выбрать любой элемент сайта и, нажав правой кнопкой, выбрать пункт “Исследовать элемент” . Справа откроется код сайта с выделенным элементом.
HTML классы и атрибут id
HTML-классы и id в основном используются для ссылки на класс в таблице стилей CSS, чтобы данные могли отображаться согласованным образом.
В приведенном выше примере, класс, используемый для получения информации о ценах из одного объявления, также применяется для получения цен из других объявлений (что соответствует основной цели класса).
Обратите внимание, что HTML-класс также может ссылаться на ценники за пределами раздела объявлений (например, специальные предложения, которые не связаны с поисковым запросом, но все равно отображаются на странице результатов). Однако для целей этой статьи мы фокусируемся только на ценах в объявлениях о недвижимости.
Вот почему мы сначала ориентируемся на объявление и ищем HTML-класс только в исходном коде для конкретного объявления:
# используем парсер lxml soup = BeautifulSoup(html_text, 'lxml') # находим одно объявление ad = soup.find('div', class_ = 'css-ad-wrapper-123456') # находим цену price = ad.find('p', class_ = 'css-aaabbbccc').text
Использование .text в конце метода find() позволяет нам возвращать только обычный текст, как показано в браузере. Без .text он вернет весь исходный код строки HTML, на которую ссылается класс:
Важное примечание: нам всегда нужно указывать элемент, в данном случае это p.
Логика получения всех точек данных с одной страницы
Чтобы получить ценники для всех объявлений, мы применяем метод find.all() вместо find():
ads = ad.find_all('p', class_ = 'css-ad-wrapper-123456')
Переменная ads теперь содержит HTML-код для каждого объявления на первой странице результатов в виде списка списков. Этот формат хранения очень полезен, так как он позволяет получить доступ к исходному коду для конкретных объявлений по индексу.
Чтобы получить все ценники, мы используем словарь для сбора данных:
map = <> id = 0 # получаем все элементы ads = ad.find_all('p', class_ = 'css-ad-wrapper-123456') for i in range(len(ads)): ad = ads[i] id += 1 map[id] = <> # находим цену price = ad.find('p', class_ = 'css-aaabbbccc').text # находим адрес address = ad.find('p', class_ = 'css-address-123456').text map[id]["address"] = address map[id]["price"] = price
Важное примечание: использование идентификатора позволяет находить объявления в словаре:
Получение точек данных со всех страниц
Обычно результаты поиска либо разбиваются на страницы, либо бесконечно прокручиваются вниз.
Вариант 1. Веб-сайт с пагинацией
URL-адреса, полученные в результате поискового запроса, обычно содержат информацию о текущем номере страницы.
Как видно на рисунке выше, окончание URL-адреса относится к номеру страницы результатов.
Важное примечание: номер страницы в URL-адресе обычно становится видимым со второй страницы. Использование базового URL-адреса с дополнительным фрагментом &pn=1 для вызова первой страницы по-прежнему будет работать (в большинстве случаев).
Применение одного цикла for-loop поверх другого позволяет нам перебирать страницы результатов:
url = 'https://www.website.com/london/page_size=25&q=london&pn=' map = <> id = 0 # максимальное количество страниц max_pages = 15 for p in range(max_pages): cur_url = url + str(p + 1) print("Скрапинг страницы №: %d" % (p + 1)) html_text = requests.get(cur_url).text soup = BeautifulSoup(html_text, 'lxml') ads = soup.find_all('div', class_ = 'css-ad-wrapper-123456') for i in range(len(ads)): ad = ads[i] id += 1 map[id] = <> price = ad.find('p', class_ = 'css-aaabbbccc').text address = ad.find('p', class_ = 'css-address-123456').text map[id]["address"] = address map[id]["price"] = price
Определение последней страницы результатов
Вы можете задаться вопросом, как определить последнюю страницу результатов? В большинстве случаев после достижения последней страницы, любой запрос с большим числом, чем фактическое число последней страницы, приведет нас обратно на первую страницу. Следовательно, использование очень большого числа для ожидания завершения сценария не работает. Через некоторое время он начнет собирать повторяющиеся значения.
Чтобы решить эту проблему, мы будем проверять, есть ли на странице кнопка с такой ссылкой:
url = 'https://www.website.com/london/page_size=25&q=london&pn=' map = <> id = 0 # используем очень большое число max_pages = 9999 for p in range(max_pages): cur_url = url + str(p + 1) print("Скрапинг страницы №: %d" % (p + 1)) html_text = requests.get(cur_url).text soup = BeautifulSoup(html_text, 'lxml') ads = soup.find_all('div', class_ = 'css-ad-wrapper-123456') # ищем ссылку в кнопке page_nav = soup.find_all('a', class_ = 'css-button-123456') if(len(page_nav) == 0): print("Максимальный номер страницы: %d" % (p)) break (. )
Вариант 2. Сайт с бесконечным скроллом
В таком случае HTML скрапер не сработает. Альтернативные методы мы обсудим в конце статьи.
Устранение несогласованности данных
Если нам нужно избавиться от ненужных данных в самом начале скрапинга на Python, мы можем использовать обходной метод:
Функция для определения аномалий
def is_skipped(price): ''' Определение цен, которые не являются ценами (например "Цена по запросу") ''' for i in range(len(price)): if(price[i] != '£' and price[i] != ',' and (not price[i].isdigit())): return True return False
И применить его при сборе данных:
(. ) for i in range(len(ads)): ad = ads[i] id += 1 map[id] = <> price = ad.find('p', class_ = 'css-aaabbbccc').text # пропускаем объявление без корректной цены if(is_skipped(price)): continue map[id]["price"] = price
Форматирование данных на лету
Мы могли заметить, что цена хранится в строке вместе с запятыми с символом валюты. Мы можем исправить это ещё на этапе скрапинга:
def to_num(price): value = Decimal(sub(r'[^\d.]', '', price)) return float(value)
Используем эту функцию:
(. ) for i in range(len(ads)): ad = ads[i] id += 1 map[id] = <> price = ad.find('p', class_ = 'css-aaabbbccc').text if(is_dropped(price)): continue map[id]["price"] = to_num(price) (. )
Получение вложенных данных
Информация об общественном транспорте имеет вложенную структуру. Нам потребуются данные о расстоянии, названии станции и типе транспорта.
Отбор информации по правилам
Каждый кусочек данных представлен в виде: число миль, название станции. Используем слово “миль” в качестве разделителя.
map[id]["distance"] = [] map[id]["station"] = [] transport = ad.find_all('div', class_ = 'css-transport-123') for i in range(len(transport)): s = transport[i].text x = s.split(' miles ') map[id]["distance"].append(float(x[0])) map[id]["station"].append(x[1])
Первоначально переменная transport хранит два списка в списке, поскольку есть две строки информации об общественном транспорте (например, “0,3 мили Слоун-сквер”, “0,5 мили Южный Кенсингтон”). Мы перебираем эти списки, используя len транспорта в качестве значений индекса, и разделяем каждую строку на две переменные: расстояние и станцию.
Поиск дополнительных HTML атрибутов для визуальной информации
В коде страницы мы можем найти атрибут testid, который указывает на тип общественного транспорта. Он не отображается в браузере, но отвечает за изображение, которое отображается на странице. Для получения этих данных нам нужно использовать класс css-StyledIcon:
map[id]["distance"] = [] map[id]["station"] = [] map[id]["transport_type"] = [] transport = ad.find_all('div', class_ = 'css-transport-123') type = ad.find_all('span', class_ = 'css-StyledIcon') for i in range(len(transport)): s = transport[i].text x = s.split(' miles ') map[id]["distance"].append(float(x[0])) map[id]["station"].append(x[1]) map[id]["transport_type"].append(type[i]['testid'])
Преобразование в датафрейм и экспорт в CSV
Когда скрапинг выполнен, все извлеченные данные доступны в словаре словарей.
Давайте сначала рассмотрим только одно объявление, чтобы лучше продемонстрировать заключительные шаги трансформации.
Преобразуем словарь в список списков, чтобы избавиться от вложенности
result = [] cur_row = 0 for idx in range(len(map[1]["distance"])): result.append([]) result[cur_row].append(str(map[1]["uuid"])) result[cur_row].append(str(map[1]["price"])) result[cur_row].append(str(map[1]["address"])) result[cur_row].append(str(map[1]["distance"][idx])) result[cur_row].append(str(map[1]["station"][idx])) result[cur_row].append(str(map[1]["transport_type"][idx])) cur_row += 1
Создаём датафрейм
df = pd.DataFrame(result, columns = ["ad_id", "price", "address", "distance", "station", "transport_type"])
Мы можем экспортировать датафрейм в CSV:
filename = 'test.csv' df.to_csv(filename)
Преобразование всех объявлений в датафрейм:
result = [] cur_row = 0 for id in map.keys(): cur_price = map[id]["price"] cur_address = map[id]["address"] for idx in range(len(map[id]["distance"])): result.append([]) result[cur_row].append(int(cur_id)) result[cur_row].append(float(cur_price)) result[cur_row].append(str(cur_address)) result[cur_row].append(float(map[id]["distance"][idx])) result[cur_row].append(str(map[id]["station"][idx])) result[cur_row].append(str(map[id]["transport_type"][idx])) cur_row += 1 # преобразование в датафрейм df = pd.DataFrame(result, columns = ["ad_id", "price","address", "distance", "station", "transport_type"]) # экспорт в csv filename = 'test.csv' df.to_csv(filename)
Мы это сделали! Теперь наш скрапер готов к тестированию.
Ограничения HTML скрапинга и его альтернативы
Этот пример показывает, насколько простым может быть скрапинг HTML на Python в стандартном случае. Для этого не нужно исследовать документацию. Это требует, скорее, творческого мышления, чем опыта веб-разработки.
Однако HTML скраперы имеют недостатки:
- Можно получить доступ только к информации в HTML-коде, которая загружается непосредственно при вызове URL-адреса. Веб-сайты, которые требуют JavaScript и Ajax для загрузки контента, не будут работать.
- HTML-классы или идентификаторы могут изменяться в связи с обновлениями веб-сайта.
- Может быть легко обнаружен, если запросы кажутся аномальными для веб-сайта (например, очень большое количество запросов в течение короткого промежутка времени).
- Shell скрипты — загружают всю страницу, с помощью регулярных выражений могут обрабатывать html.
- Screen scraper — изображают реального пользователя, используют браузер (Selenium, PhantomJS).
- ПО для скрапинга — рассчитаны на стандартные случаи, не требуют написания кода (webscraper.io).
- Веб сервисы скраперы — не требуют написания кода, хорошо справляются со скрапингом, платные (zyte.com).
Следите за новыми постами по любимым темам
Подпишитесь на интересующие вас теги, чтобы следить за новыми постами и быть в курсе событий.