#!/usr/bin/env python # coding: utf-8 # # Основы программирования в Python # # *Алла Тамбовцева, НИУ ВШЭ* # Посмотрим на другие примеры использования `selenium`. # # **Пример.** Зайдем на сайт книжного магазина и найдем все книги В.Пелевина. Загрузим библиотеку, веб-драйвер и откроем страницу в браузере через Python. # In[1]: from selenium import webdriver as wb br = wb.Chrome("/Users/allat/Downloads/chromedriver") # открываем страницу в Chrome в автоматическом режиме br.get("http://www.biblio-globus.ru/") # Найдем с помощью CSS Selector'а (*SelectorGadget*) поле для ввода названия книги или автора. # In[2]: field = br.find_element_by_css_selector("input") # Сохраним фамилию автора: # In[3]: author = "Пелевин" # Введем фамилию автора в поле для поиска (`.send_keys`) и подождем чуть-чуть: # In[4]: field.send_keys("Пелевин") br.implicitly_wait(2) # подождем пару секунд # Теперь найдем кнопку для поиска (значок *лупа* рядом со строкой поиска) через CSS Selector: # In[5]: submit = br.find_element_by_css_selector("#search_submit") # Кликнем на нее: # In[6]: submit.click() # Сохраним первую страницу с результатами в переменную `page1`. # In[7]: page1 = br.page_source # In[9]: page1 # Теперь обработаем эту страницу через `BeautifulSoup`: # In[10]: from bs4 import BeautifulSoup # In[11]: soup1 = BeautifulSoup(page1, 'lxml') # Найдем все названия книг на этой странице. По исходному коду можно увидеть, что они имеют тэг `a` с атрибутом `class`, равным `name`: # In[12]: soup1.find_all('a', {'class':'name'}) # С помощью списковых включений выберем из ссылок с тэгом `` текст (так мы уже делали, и не раз). # In[13]: books1 = [b.text for b in soup1.find_all('a', {'class':'name'})] # In[14]: books1 # Теперь аналогичным образом сгрузим информацию о наличии книг: # In[15]: instore1 = [s.text for s in soup1.find_all('div', {'class':'title_data green'})] # In[16]: instore1 # Уберем лишнее: # In[17]: instore1 = [i.strip() for i in instore1] # убираем лишние пробелы # In[18]: instore1 # Сгрузим расположение: # In[19]: place1 = [p.text for p in soup1.find_all('div', {'class':'placement'})] # In[20]: place1 # И, конечно, цену: # In[21]: price1 = [p.text for p in soup1.find_all('div', {'class':'title_data price'})] # In[22]: price1 # Осталось пройтись по всем страницам, которые были выданы в результате поиска. Для примера перейдем на страницу 2 и на этом остановимся. # In[23]: next_p = br.find_element_by_css_selector('.next_page') # In[24]: next_p.click() # Проделаем то же самое, что и с первой страницей. По-хорошему нужно написать функцию, которая будет искать на странице названия книг, их расположение и цену. Но оставим это в качестве задания читателю :) # In[25]: page2 = br.page_source soup2 = BeautifulSoup(page2, 'lxml') books2 = [b.text for b in soup2.find_all('a', {'class':'name'})] instore2 = [s.text for s in soup2.find_all('div', {'class':'title_data green'})] instore2 = [i.strip() for i in instore2] place2 = [p.text for p in soup2.find_all('div', {'class':'placement'})] price2 = [p.text for p in soup2.find_all('div', {'class':'title_data price'})] # Расширим списки результатов с первой страницы данными, полученными со второй страницы, используя метод `.extend()`. # In[26]: books1.extend(books2) instore1.extend(instore2) place1.extend(place2) price1.extend(price2) # Осталось импортировать библиотеку `pandas` и создать датафрейм. # In[27]: import pandas as pd # Для разнообразия создадим датафрейм не из списка списков, а из словаря. Ключами словаря будут названия столбцов в таблице, а значениями – списки с сохраненной информацией (названия книг, цены и проч.). # In[28]: df = pd.DataFrame({'books': books1, 'in_store': instore1, 'placement': place1, 'price': price1}) # In[29]: df.head() # Давайте приведем столбец с ценой к числовому типу. Уберем слова *Цена* и *руб*, а потом сконвертируем строки в числа с плавающей точкой. Напишем функцию `get_price()`, # In[30]: def get_price(price): book_price = price.split(' ')[1] # разобьем строку по пробелу и возьмем второй элемент book_price = book_price.replace(',', '.') # заменим запятую на точку price_num = float(book_price) # сконвертируем в float return price_num # In[31]: # проверка get_price(df.price[0]) # Всё отлично работает! Применим функцию к столбцу *price* и создадим новый столбец *nprice*. # In[32]: df['nprice'] = df.price.apply(get_price) # In[33]: df.head() # Теперь можем расположить книги по цене в порядке возрастания: # In[34]: df.sort_values('nprice') # Выберем какую-нибудь книгу: # In[36]: df[df.books == "Чапаев и Пустота"] # И сохраним всю таблицу в csv-файл: # In[37]: df.to_csv("books.csv")