Рубрики
Без рубрики

Введение в сеть соскабливание с LXML и Python

Автор оригинала: FreeCodeCapm Team.

Timber.io.

Почему вы должны беспокоить, как Web Scrape? Если ваша работа не требует от вас, чтобы узнать его, то позвольте мне дать вам некоторую мотивацию.

Что, если вы хотите создать сайт, который лечит самые дешевые продукты от Amazon, Walmart, а также пару других интернет-магазинов? Многие из этих интернет-магазинов не предоставляют вам простой способ получить доступ к своей информации, используя API. В отсутствие API ваш единственный выбор – создать веб-скребок. Это позволяет автоматически извлекать информацию с этих веб-сайтов и делает эту информацию простым в использовании.

Вот пример типичного ответа API в JSON. Это ответ от Reddit:

Есть много библиотек Python, которые могут помочь вам с веб-соскабливанием. Есть lxml , Beautifulsoup и полноценный каркас под названием Снапировка Отказ

Большинство учебных пособий обсуждают Beautifulsoup и Scrapy, поэтому я решил пойти с LXML в этом посте. Я научу вам основы XPaths и как вы можете использовать их для извлечения данных из HTML-документа. Я возьму вас через пару различных примеров, чтобы вы могли быстро получить скорость с LXML и XPaths.

Получать данные

Если вы Gamer, вы уже знаете (и вероятную любовь) этот сайт. Мы будем пытаться извлечь данные из Пар Отказ Более конкретно, мы выберем из « популярных новых выпусков » информации.

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

Прежде всего, открывайте страницу « популярные новые релизы » на Steam и прокрутите вниз, пока не увидите популярных новых выпусков вкладки. На данный момент я обычно открываю инструменты разработчика Chrome и посмотрите, какие теги HTML содержат необходимые данные. Я широко использую инструмент инспектора элемента (кнопка в левом верхнем углу инструментов разработчика). Это позволяет вам увидеть HTML-разметку за определенным элементом на странице одним щелчком мыши.

Как обзор высокого уровня, все на веб-странице инкапсулируется в теге HTML, а теги обычно вложены. Вам необходимо понять, какие теги вам нужно извлечь данные, и вы будете хороши, чтобы пойти. В нашем случае, если мы посмотрим, мы видим, что каждый отдельный элемент списка инкапсулирован в явере ( A ) Тег.

Сами якорные теги инкапсулированы в Div с идентификатором Tab_newRelestes_content Отказ Я упоминаю идентификатор, потому что на этой странице есть две вкладки. Вторая вкладка является стандартным «новым выпуском» вкладками, и мы не хотим извлечь информацию с этой вкладки. Поэтому мы сначала извлеките вкладку «популярные новые выпуски», а затем извлеките необходимую информацию из этого тега.

Это идеальное время для создания нового файла Python и начать писать наш скрипт. Я собираюсь создать Scrape.py файл. Теперь давайте пойдем вперед и импортируем необходимые библиотеки. Первый – это Запросы Библиотека и вторая – это lxml.html библиотека.

import requests import lxml.html

Если у вас нет Запросы Установлен, вы можете легко установить его, запустив эту команду в терминале:

$ pip install requests

Библиотека запросов поможет нам открыть веб-страницу в Python. Мы могли бы использовать lxml Чтобы открыть HTML-страницу, но она не работает хорошо со всеми веб-страницами. Быть на безопасной стороне, я собираюсь использовать Запросы Отказ

Извлечение и обработка информации

Теперь давайте откроем веб-страницу, используя запросы и пропустите этот ответ на lxml.html.fromstring Отказ

html = requests.get('https://store.steampowered.com/explore/new/') doc = lxml.html.fromstring(html.content)

Это дает нам объект Htmlelement тип. Этот объект имеет XPath Метод, который мы можем использовать для запроса HTML-документа. Это дает нам структурированный способ извлечения информации из HTML-документа.

Теперь сохраните этот файл и откройте терминал. Скопируйте код из Scrape.py Файл и вставьте его в сеанс интерпретатора Python.

Мы делаем это, чтобы мы могли быстро проверить наши XPaths без постоянного редактирования, сохранения и выполнения наших Scrape.py файл.

Попробуем написание XPath для извлечения Div, который содержит вкладку «Популярные новые выпуски». Я объясню код, когда мы идем вместе:

new_releases = doc.xpath('//div[@id="tab_newreleases_content"]')[0]

Это утверждение вернет список всех Рав ...| на HTML-странице, которые имеют идентификатор Tab_newRelestes_content Отказ Теперь, потому что мы знаем, что только один div на странице имеет этот идентификатор, мы можем вывести первый элемент из списка ( [0] ), и это было бы нашему требованию Div Отказ Давайте сломаем XPath и попытаться понять это:

  • // Эти двойные форварды скажите lxml Что мы хотим искать все теги в документе HTML, который соответствует нашим требованиям/фильтрам. Другой вариант – использовать / (одна передовая чечка). Одиночная прямая косой возвращает только немедленные детские бирки/узлы, которые соответствуют нашим требованиям/фильтрам
  • Div рассказывает lxml что мы ищем Рав ...| На странице HTML [@ ID = “Tab_newRelestes_content”]
  • рассказывает lxml что мы заинтересованы только в тех Рав …| которые имеют идентификатор Tab_newRelesense_content.

Прохладный! У нас требуется требуется Div Отказ Теперь давайте вернемся к Chrome и проверьте, какая тег содержит названия релизов.

Название содержится в Div с классом tab_item_name Отказ Теперь, когда у нас есть вкладка «Популярные новые выпуски», мы можем запустить дополнительные запросы XPath на этой вкладке. Запишите следующий код в одной и той же консоли Python, которую мы ранее работали наш код в:

titles = new_releases.xpath('.//div[@class="tab_item_name"]/text()')

Это дает нам названия всех игр в вкладке «популярные новые релизы». Вот ожидаемый выход:

Давайте немного сломаем эту XPath, потому что это немного отличается от последнего.

  • Отказ Рассказывает LXML, что нас интересуют только теги, которые являются детьми new_realestes тег
  • [@ Class = "Tab_item_name"] довольно похоже на то, как мы фильтровали Рав ...| на основе ID Отказ Единственное отличие состоит в том, что здесь мы фильтрация на основе имени класса /Текст ()
  • Рассказывает LXML, что мы хотим, который мы хотим, содержащийся в теге, который мы просто извлекли. В этом случае он возвращает название, содержащееся в Div с tab_item_name Название класса

Теперь нам нужно извлечь цены на игры. Мы можем легко сделать это, запустив следующий код:

prices = new_releases.xpath('.//div[@class="discount_final_price"]/text()')

Я не думаю, что мне нужно объяснить этот код, так как он довольно похож на код добычи заголовка. Единственное изменение, которое мы сделали, – это изменение имени класса.

Теперь нам нужно извлечь теги, связанные с названиями. Вот HTML Markup:

Запишите следующий код в терминале Python, чтобы извлечь теги:

tags = new_releases.xpath('.//div[@class="tab_item_top_tags"]')total_tags = []for tag in tags:    total_tags.append(tag.text_content())

Так что мы здесь делаем, выделяют Рав ...| Содержащие теги для игр. Затем мы верим в список извлеченных тегов, а затем извлеките текст из этих тегов, используя text_content () метод. text_content () Возвращает текст, содержащийся в HTML-теге без разметки HTML.

Примечание: Мы могли бы также использовать понимание списка, чтобы сделать этот код короче. Таким образом, я написал это так, чтобы даже те, кто не знают о соприкосновении списка, может понять код. В любом случае, это альтернативный код:

tags = [tag.text_content() for tag in new_releases.xpath('.//div[@class="tab_item_top_tags"]')]

Давайте также отделим теги в списке, чтобы каждый тег был отдельным элементом:

tags = [tag.split(', ') for tag in tags]

Теперь единственное, что осталось, состоит в том, чтобы извлечь платформы, связанные с каждым заголовком. Вот HTML Markup:

Основная разница вот в том, что платформы не содержатся в виде текстов в рамках определенного тега. Они перечислены как имя класса. Некоторые названия имеют только одну платформу, связанную с ними, как это:

Хотя некоторые названия имеют 5 платформ, связанных с ними, как это:

  

Как мы видим, эти охватывает Содержит тип платформы в качестве имени класса. Единственное общее между ними охватывает это то, что все они содержат Platform_img класс. Прежде всего, мы извлеките Рав ...| с Tab_item_details класс. Тогда мы извлеким охватывает содержащий Platform_img класс. Наконец, мы извлеките имя второго класса из тех охватывает Отказ Вот код:

platforms_div = new_releases.xpath('.//div[@class="tab_item_details"]')total_platforms = []for game in platforms_div:    temp = game.xpath('.//span[contains(@class, "platform_img")]')    platforms = [t.get('class').split(' ')[-1] for t in temp]    if 'hmd_separator' in platforms:        platforms.remove('hmd_separator')    total_platforms.append(platforms)

В линия 1, Начнем с извлечения Tab_item_details Div Отказ XPath в Линия 5 немного по-другому. Здесь у нас есть [содержит (@class, "platform_img")] вместо того, чтобы просто иметь [@ Class = "platform_img"] Отказ Причина в том, что [@ Class = "platform_img"] Возвращает тех охватывает которые имеют только Platform_img класс связан с ними. Если охватывает иметь дополнительный класс, они не будут возвращены. Тогда как [содержит (@class, "platform_img")] Фильтры все охватывает которые имеют Platform_img класс. Неважно, это единственный класс или если есть больше классов, связанных с этим тегом.

В линия 6 Мы используем понимание списка для уменьшения размера кода. .get () Метод позволяет извлечь атрибут тега. Здесь мы используем его для извлечения Класс атрибут a промежуток Отказ Мы получим строку обратно из .get () метод. В случае первой игры возвращается строка Platform_img Win Таким образом, мы разделяем эту строку на основе запятой и пробелы. Затем мы храним последнюю часть (которая является фактическим именем платформы) расщепленной строки в списке.

В Линии 7-8 Мы снимаем hmd_separator Из списка, если он существует. Это потому, что hmd_separator не является платформой. Это просто вертикальная сепараторная панель, используемая для отделения фактических платформ из оборудования VR/AR.

Это код, который мы имеем до сих пор:

import requestsimport lxml.htmlhtml = requests.get('https://store.steampowered.com/explore/new/')doc = lxml.html.fromstring(html.content)new_releases = doc.xpath('//div[@id="tab_newreleases_content"]')[0]titles = new_releases.xpath('.//div[@class="tab_item_name"]/text()')prices = new_releases.xpath('.//div[@class="discount_final_price"]/text()')tags = [tag.text_content() for tag in new_releases.xpath('.//div[@class="tab_item_top_tags"]')]tags = [tag.split(', ') for tag in tags]platforms_div = new_releases.xpath('.//div[@class="tab_item_details"]')total_platforms = []for game in platforms_div:    temp = game.xpath('.//span[contains(@class, "platform_img")]')    platforms = [t.get('class').split(' ')[-1] for t in temp]    if 'hmd_separator' in platforms:        platforms.remove('hmd_separator')    total_platforms.append(platforms)

Теперь нам просто нужно это вернуть ответ JSON, чтобы мы могли легко превратить это в API на основе колба. Вот код:

output = []for info in zip(titles,prices, tags, total_platforms):    resp = {}    resp['title'] = info[0]    resp['price'] = info[1]    resp['tags'] = info[2]    resp['platforms'] = info[3]    output.append(resp)

Этот код является самоснабжением. Мы используем Zip Функция для цикла во всех этих списках параллельно. Затем мы создаем словарь для каждой игры и назначить название, цену, теги и платформы как отдельный ключ в этом словаре. Наконец, мы добавляем этот словарь в список выходных.

Обертывание

В следующем посте мы посмотрим на то, как мы можем преобразовать это в API на основе колбы и разместите его на Heroku.

Я Yasoob от Советы Python Отказ Я надеюсь, что вы, ребята, наслаждались этим руководством. Если вы хотите прочитать больше учебников аналогичной природы, пожалуйста, перейдите в Советы Python Отказ Я регулярно пишу советы, трюки Python, трюки и учебники в этом блоге. И если вы заинтересованы в изучении промежуточного Python, пожалуйста, проверьте мою книгу с открытым исходным кодом здесь Отказ

Просто отказ от ответственности: мы лесозаготовительная компания здесь @ древесина Отказ Мы бы понравились, если вы опробуете наш продукт (это серьезно здорово!), Но вы здесь, чтобы узнать о веб-соскании в Python, и мы не хотели убирать от этого.

Первоначально опубликовано timber.io .