-
Notifications
You must be signed in to change notification settings - Fork 0
2. Домашнє завдання №2
Bohdan Mahometa edited this page Apr 11, 2021
·
26 revisions
1. Пошук інформації про книжку. Пріоритет - високий.
- 1.1 Пошук інформації про книжку за її назвою.
- 1.2 Пошук інформації про книжку за автором.
- 1.3 Комбінований пошук інформації про книжку (за назвою і автором).
- 2.1 Пошук посилань відео-оглядів на знайдену книгу із платформи YouTube за допомогою однойменного API. Пріоритет - високий.
- 3.1 Отримання відгуків про книгу із сайту Goodreads за допомогою Beautiful Soup 4. Пріоритет - високий.
- 3.2 Відображення відгуків про книгу на веб-сайті. Пріоритет - високий.
- 3.3 Аналіз користі відгуків. Знаходження найкорисніших позитивних та негативних відгуків. Пріоритет - середній.
- 3.4 Відображення найкорисніших позитивних та негативних відгуків із платформи Goodreads. Пріоритет - середній.
- 4.1 Відображеня рейтингу книги на платформі Goodreads.
- 4.2 Відображення наявності українських перекладів знайденої книги.
1. Вимоги до користувацького інтерфейсу.
- 1.1 Доступ до наданої функціональності відбувається через веб-сайт.
- 1.2 Інтерфейс повинен бути англійською мовою.
- 1.3 Інтерфейс повинен бути максимально простий та зрозумілий.
- 2.1 Логіка вебсайту повинна бути написана на мові програмування Python з дотримуванням стандарту PEP08.
- 2.2 Backend повинен бути реалізований з використанням фреймворку Flask.
- 2.3 Весь процес пошуку та виведення інформації про книгу повинен виконуватися не довше ніж 5 секунд.
- 3.1 Як розробникам, нам потрібно обмежити користувача в зловживанні сервісами, які ми надаємо.
- 3.2 Як розробники, ми не хочемо втратити API-ключі, тому нам потрібно контролювати частоту звертань сервера до API.
- 3.3 Як розробники, ми маємо забезпечити правильну відповідь системи на виняткові ситуації, що можуть статися під час користування веб-сайтом.
- Запит:
- Метод HTTP-запиту: GET
- Endpoint: https://www.goodreads.com/search/index.xml
- Параметри query string:
- key: API ключ
- q: фраза, за якою відбувається пошук
- search[field]: вказує, в чому шукати фразу q (може бути 'title', 'author', або 'all'). Якщо не вказано, то шукає в усьому.
- page: номер сторінки результату пошуку (на одній сторінці може бути до 20 знайдених книг).
- Відповідь:
- Формат відповіді - XML
- Структура XML:
└───GoodreadsResponse
├───Request
│ ├───authentication
│ │ └───key - contains API key
│ └───method
└───search
├───query
├───results-start - порядковий номер першої книги на сторінці (integer)
├───results-end - порядковий номер останньої книги на сторінці (integer)
├───total-results - кількість книг на сторінці, тобто кількість дітей xml-елемента results, (integer)
├───source (string)
├───query-time-seconds - час, який сервер витратив на обробку запиту (real number)
└───results
├───work
│ ├───id (integer)
│ ├───books_count (integer)
│ ├───ratings_count (integer)
│ ├───text_reviews_count (integer)
│ ├───original_publication_year (integer)
│ ├───original_publication_month (integer)
│ ├───original_publication_day (integer)
│ ├───average_rating (real number)
│ └───best_book
│ ├───id (integer)
│ ├───title (string)
│ ├───author
│ │ ├───id (integer)
│ │ └───name (string)
│ ├───image_url (string)
│ └───small_image_url (string)
├───work
│ ...
├───work
│ ...
...
└───work
...
- Запит:
- Метод HTTP-запиту: GET
- Endpoint: https://www.goodreads.com/book/isbn/ISBN?format=json
- Параметри query string:
- key: API ключ
- isbn: ISBN книги, огляди якої шукаємо.
- rating: Показати лише відгуки з певним рейтингом (optional)
- Відповідь:
- Формат відповіді - json
- Структура json-об'єкту:
- Відповідь містить лише одну пару name/value
{'reviews_widget': html-розмітка}
- Отримана html-розмітка містить html-елемент iframe, значення одного з атрибутів якого є посиланням на огляди. Відповідно, щоб отримати огляди, потрібно пропарсити сторінку за цим посиланням.
Модуль xml.etree.ElementTree дозволяє представляти дані XML у вигляді дерева. Для цього він надає клас ElementTree (представляє все дерево) та клас Element (представляє одну вершину дерева, корінь чи будь-яку іншу).
Деякі зручні способи перетворити XML-дані в об'єкти модуля xml.etree.ElementTree:
- функція xml.etree.ElementTree.fromstring(text)
- Перетворює стрічку text у об'єкт класу Element і повертає його.
- Отриманий об'єкт класу Element представляє корінь дерева, тобто елемент, що найвищий в ієрархії.
- За допомогою отриманого об'єкту можна доступитися до всіх інших елементів, їх атрибутів та вмісту.
- функція ET.parse(source)
- Читає XML-дані з файлу і повертає об'єкт класу ElementTree.
- аргумент source - файл-об'єкт або шлях до файлу з XML-даними.
- За допомогою отриманого об'єкту класу ElementTree можна доступитися до всіх XML-елементів, їх атрибутів та вмісту.
- Щоб отримати корінь (елемент, який найвищий в ієрархії), якщо маємо об'єкт класу ElementTree, можна використати метод getroot.
- Об'єкт класу Element є iterable. Тобто можна пройтися по всіх дітях XML-елементу за допомогою циклу for.
- Іншим способом доступитися до дітей XML-елементу є індексування. Наприклад,
element[0]
поверне першу дитину XML-елемента. - Метод екземляру iter класу Element повертає ітератор, щоб пройтися по всіх нащадках XML-елементу. Наприклад,
list(element.iter())
поверне список всіх нащадків element. - Метод екземляру find класу Element дозволяє знайти дитину XML-елемента з вказаною назвою тега. Наприклад,
element.find("some_name_of_tag")
поверне об'єкт класу Element, що є дитиною element та має назву "some_name_of_tag" - Щоб знайти всіх дітей element за назвою тега, потрібно використати метод findall. Наприклад,
element.findall('some_name_of_tag')
повертає список всіх тегів, які є дітьми element і мають назву 'some_name_of_tag'. - Доступитися до атрибута XML-елементу можна використовуючи метод Element.get. Наприклад,
element.get('type', 'no type')
поверне значення атрибуту type, якщо він існує, інакше поверне стрічку 'no type'. - Щоб доступитися (змінити чи просто отримати) до тексту, що міститься у вмісті XML-елементу, потрібно скористатися атрибутом text об'єкта класу Element.
- Щоб доступитися (змінити чи просто отримати) до тегу XML-елемента, потрібно скористатися атрибутом tag. Наприклад,
element.tag
поверне назву тега element,element.tag = "nice"
змінить назву тега element на "nice".
- Щоб записати XML-дані, що містяться в об'єкті ElementTree, можна скористатися методом write. Наприклад,
tree.write('output.xml')
запише XML-дані в файл з назвою 'output.xml'. - Якщо ж замість об'єкта класу ElementTree, в нас є об'єкт класу Element, то
tree = ElementTree(element)
створить дерево, коренем якого є element, аtree.write('output.xml')
запише це дерево в файл.
Модуль JSON дозволяє кодувати і декодувати дані в зручному форматі.
- json.dump (obj, fp, skipkeys = False, ensure_ascii = True, check_circular = True, allow_nan = True, cls = None, indent = None, separators = None, default = None, sort_keys = False, ** kw) - серіалізуює obj, записуючи його в файл-об'єкт fp.
- Якщо skipkeys = True, то ключі словника не базового типу (str, unicode, int, long, float, bool, None) будуть проігноровані, замість того, щоб викликати виключення TypeError.
- Якщо ensure_ascii = True, всі не-ASCII символи будуть записані в файл послідовностями \uXXXX, і результатом буде рядок, що містить тільки ASCII символи. Якщо ensure_ascii = False, рядки запишуться як є.
- Якщо check_circular = False, то перевірка циклічних посилань буде пропущена, а такі посилання будуть викликати OverflowError.
- Якщо allow_nan = False, при спробі серіалізувати значення з коми, що виходить за допустимі межі, буде викликатися ValueError (nan, inf, -inf) в суворій відповідності зі специфікацією еуJSON, замість того, щоб використовувати еквіваленти з JavaScript (NaN, Infinity, -Infinity ).
- Якщо indent є невід'ємним числом, то масиви і об'єкти в JSON будуть виводитися з цим рівнем відступу. Якщо рівень відступу 0, негативний або "", то замість цього просто використовуватимуться нові рядки. Значення за замовчуванням None відображає найбільш компактне уявлення. Якщо indent - рядок, то вона і буде використовуватися в якості відступу.
- Якщо sort_keys = True, то ключі виведеного словника будуть відсортовані.
- json.dumps (obj, skipkeys = False, ensure_ascii = True, check_circular = True, allow_nan = True, cls = None, indent = None, separators = None, default = None, sort_keys = False, ** kw) - серіалізує obj в рядок.
- json.load (fp, cls = None, object_hook = None, parse_float = None, parse_int = None, parse_constant = None, object_pairs_hook = None, ** kw) – десеріалізує JSON з fp.
- object_hook - опціональна функція, яка викликається для кожного JSON-об'єкта (тобто словника), який передається їй як аргумент. Повернуте значення цієї функції буде використовуватися замість словника.
- object_pairs_hook - опціональна функція, яка застосовується до результату декодування об'єкта з певною послідовністю пар ключ / значення. Буде використаний результат, що повертається функцією, замість справжнього словника. Якщо заданий так само object_hook, то пріоритет віддається object_pairs_hook.
- parse_float, якщо визначений, буде викликаний для кожного значення JSON з плаваючою точкою. За замовчуванням, це еквівалентно float(num_str).
- parse_int, якщо визначений, буде викликаний для рядка JSON з числовим значенням. За замовчуванням еквівалентно int (num_str).
- parse_constant, якщо визначений, буде викликаний для наступних рядків: "-Infinity", "Infinity", "NaN". Може бути використано для порушення винятків при виявленні помилкових чисел JSON. Якщо не вдасться десеріалізувати JSON, буде порушено виняток ValueError.
- json.loads (s, encoding = None, cls = None, object_hook = None, parse_float = None, parse_int = None, parse_constant = None, object_pairs_hook = None,** kw) - десеріалізує s (екземпляр str, що містить документ JSON) в об'єкт Python.
- List - структура даних, яка містить впорядкований набір елементів.
- Set - невпорядкована множина з відмнних хешованих елементів.
- Dict - розділяє хешовані значення за довільними змінювальними елементами.
- Default dict - словник, ініціалізований зі значеннями за замовчуванням, коли кожен ключ зустрічається один раз.
- Deque - узагальнення стеків та черг.
- Heapq - бінарне дерево, для якого кожна батьківська комірка має значення менше або рівне за значення своїх нащадків.
- Counter - підклас словника для підрахунку хешованих об'єктів. Це невпорядкована колекція, де елементи зберігаються як ключі словника і їхні значення зберігаються як значення словника.
- Bisect - модуль, що встановлює алгоритм для вставки елементів до списку поки утримує список впорядкованим.
![](https://raw.githubusercontent.com/UstymHanyk/BookGoogle/main/images/data_types.png)