JSON

JSON — (англ. JavaScript Object Notation) — текстовый формат обмена данными, основанный на JavaScript. При этом формат независим от JS и может использоваться в любом языке программирования.

JSON входит в стандартный пакет python, устанавливать его не нужно, достаточно просто импортировать  import json

Сегодня мы будем рассматривать JSON с точки зрения сохранения информации. В этом уроке мы будем говорить о JSON-объектах: как их создавать, сохранять, генерировать и как манипулировать ими.

JSON-объект выглядит так, заключается в фигурные скобки. Он очень похож на словарь в Python, если вы с ними уже знакомы, то освоить этот раздел будет очень просто.

[{
"name": "Иван",
"age": 27
}]

«name» — это ключ(key), а «Иван» — это значение(value),  ключ и значение разделяются двоеточием, каждая пара ключ:значение, отделены друг от друга запятой.

Значение(value) может быть:

строкой;
числом;
True или False;
Null;

Другим объектом, в том числе списком или словарем и может иметь какую угодно вложенность.

Один из простых примеров генерирования JSON объекта во время парсинга(#2):

import requests
from bs4 import BeautifulSoup
import json

# 1 ------------------------------------------------------
url = ' https://mob25.com/'
response = requests.get(url=url)
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'lxml')
# 1 ------------------------------------------------------
# 2 ------------------------------------------------------
result_json = {
    'name': soup.find('p', id='p_header').text,
    'price': soup.find('span', id='price').text}
# 2 ------------------------------------------------------
# 3 ------------------------------------------------------
with open('res.json', 'w', encoding='utf-8') as file:
    json.dump(result_json, file, indent=4, ensure_ascii=False)
# 3 ------------------------------------------------------
>>> {
    "name": "Мышь Logitech G PRO HERO Black USB проводная",
    "price": "5100 руб"
}

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

В этом блоке мы совершили get запрос на страницу и передали результат запроса в конструктор BeautifulSoup;

Создали простой словарь result_json={} , вручную обозначили ключи, а значения для словаря мы получили из объекта soup с помощью тегов;

В менеджере контекста with  обозначили название файла с расширением .json, указали кодировку «utf-8».

Методы JSON

json.dump() — преобразует объекты python (в нашем примере это словарь) в соответствующий объект JSON. Метод .dump() первым параметром ожидает словарь, который мы будем записывать в файл, а вторым параметром — файл, куда мы будем записывать наш словарь.

indent=4 улучшает читаемость файла json, и обозначает отступ в пробелах;

ensure_ascii=False — если не указать, могут возникнуть проблемы с кодировкой. Если установить значение True, то кириллические символы будут отображены в ascii, примерно вот так \u041c\u044b\u0448\u044c.

json.dumps() — отличается лишь тем, что кодирует наши данные в Python string  и служит для преобразования примитивных типов данных. В ваших парсерах вы, скорее всего, будете использовать именно первый вариант;

json.load() — метод считывает файл в формате JSON и возвращает объекты Python, про метод load() подробнее мы поговорим позже когда, будем считывать json-файлы;

json.loads() — метод считывает строку в формате JSON и возвращает объекты Python.

Пример кода

Далее будет еще один пример кода по извлечению данных с сайта и формированию словаря для дальнейшего дампа в .json.

import requests
from bs4 import BeautifulSoup
import json

# 1 ------------------------------------------------------
url = 'https://mob25.com/'
response = requests.get(url=url)
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'lxml')
# 1 ------------------------------------------------------

# 2 ------------------------------------------------------
name = [x.text.strip() for x in soup.find_all('a', class_='name_item')]
description = [x.text.strip().split('\n') for x in soup.find_all('div', class_='description')]
price = [x.text for x in soup.find_all('p', class_='price')]
# 2 ------------------------------------------------------

result_json = []

# 3 ------------------------------------------------------
for list_item, price_item, name in zip(description, price, name):
    result_json.append({
        'name': name,
        'brand': [x.split(':')[1] for x in list_item][0],
        'type': [x.split(':')[1] for x in list_item][1],
        'connect': [x.split(':')[1] for x in list_item][2],
        'game': [x.split(':')[1] for x in list_item][3],
        'price': price_item
    })
# 3 ------------------------------------------------------

# 4 ------------------------------------------------------
with open('res.json', 'w', encoding='utf-8') as file:
    json.dump(result_json, file, indent=4, ensure_ascii=False)
# 4 ------------------------------------------------------

В этом коде активно применялись list comprehension для извлечения необходимых данных и формирования списка словарей.

В блоке №1 нет ничего нового для вас;

В блоке №2 мы извлекаем информацию с каждой карточки на сайте тренажёре, извлекаем наименование товара, его описание и стоимость. Если мы посмотрим на элементы страницы HTML, мы увидим,  что description  извлекается методом find_all() и получается список списков, который необходимо записать в наш список словарей;

В этом блоке мы инициируем цикл, в котором проходимся по трём основным спискам, мы создали их в блоке 2, и на каждой итерации записываем значение в соответствующий ключ нашего словаря.

В результате выполнения этого кода мы получаем файл res.json в каталоге с нашим проектом.

Извлечение значений атрибута

Именно его значение, а не текст, который заключен в теге. Этим методом можно собирать любые значения атрибутов, class=»», name=»», src=»», href=»», id=»», не имеет значения какой тег. Чтоб далеко не ходить, мы будем тренироваться на нашем тренажёре.

В результате выполнения кода у нас получится вот такой список:  [‘brand’, ‘model’, ‘type’, ‘display’, ‘material_frame’, ‘material_bracer’, ‘size’, ‘site’]. Это понадобится вам для решения задачи, которая ждет вас далее.

import requests
from bs4 import BeautifulSoup

response = requests.get(' https://mob25.com/')
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'lxml')
description = soup.find('ul', id='description').find_all('li')
for li in description:
    print(li['id'])
>>> brand
    model
    type
    display
    material_frame
    material_bracer
    size
    site

В первую очередь нам необходимо найти и получить родительский элемент, в этом примере это <ul id=»description»>, description = soup.find(‘ul’, id=’description’).find_all(‘li’) — будет хранить список всех дочерних элементов <li>, давайте на них посмотрим.

Далее мы проходимся по каждому элементу в этом списке и обращаемся с ним как с элементами словаря — li[‘id’]. Мы можем добавлять элементы в список на каждой итерации, а можем использовать list comprehension li_id = [x[‘id’] for x in description] и получить готовый список без лишнего кода.

import requests
from bs4 import BeautifulSoup

response = requests.get(' https://mob25.com/')
response.encoding = 'utf-8'
soup = BeautifulSoup(response.text, 'lxml')
description = soup.find('ul', id='description').find_all('li')
li_id = [x['id'] for x in description]
print(li_id)
>>> ['brand', 'model', 'type', 'display', 'material_frame', 'material_bracer', 'size', 'site']


Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: