Парсер лучших за сутки статей habr(а) на Python. Очень подробно и просто
Всем привет, сегодня я вам покажу и расскажу, как можно легко написать парсер для сбора лучших статей дня в виде json файла, в формате, «Название статьи»: «ссылка». Кто не понял о каких лучших статьях дня я говорю, вот ссылка «https://habr.com/ru/top/daily/».
Итак, библиотеки, которые будут нам нужны (вставляем в командную строку, либо в терминале или куда вам удобно):
pip install beautifulsoup4 pip install requests pip install fake-useragent pip install lxml
Инициализируем модули в наш заранее созданный проект, т.е. файл с расширением py.
from bs4 import BeautifulSoup import random import json import requests import datetime from fake_useragent import UserAgent
Создаем переменную с модулем fake_useragent, чтобы мы могли потом использовать для генерации user-agent:
ua = UserAgent()
Определяем заголовки (для того чтобы сервер сайта мог понять, как он должен отправить ответ, а также помогает серверу определить отправителя запроса)
headers = < 'accept': 'application/json, text/plain, */*', 'user-Agent': ua.google, >
Создаем словарь, где будут храниться название и ссылка на каждую статью:
article_dict = <>
Указываем url c форматирование кода, где i — номер страницы, которое вставляться при каждом проходе цикла.
url = f'https://habr.com/ru/top/daily/'
Отправляем get запрос на сайт, указывая в первом аргументе — переменную с url сайта, во-втором заголовки. Атрибут text, нужен чтобы получить текстовое содержанием html страницы.
req = requests.get(url, headers=headers).text
Теперь с помощью BeautifulSoup соберем весь html код страницы.
soup = BeautifulSoup(req, 'lxml')
Если попробовать вывести такой код с помощью print(soup), выведется весь html код страницы.
Далее, используя наш «soup» созданный в прошлом шаге, с помощью метода find_all собираем все ссылки с помощью тега «a» в первом аргументе, во-втором, с помощью F12, ищем класс у всех ссылок наших статей, как мы видим это — tm-article-snippet__title-link.

all_hrefs_articles = soup.find_all('a', class_='tm-title__link')
Класс указывается с нижним подчеркиванием, т.к. это ключевое (зарезервированное) слово в Python.
Создаем еще один цикл, где мы будем проходиться по всем статьям собранных в переменной all_hrefs_articles.
for article in all_hrefs_articles:
В теге «a» с классом «tm-article-snippet__title-link» находится еще один тег «span» c нашими именами ссылок, получим его с помощью метода find.
article_name = article.find('span').text # собираем названия статей
Теперь получим ссылку на статью, указываем что это f строка, и с помощью get запроса в скобочках получаем атрибут «href» — основной атрибут тега «a».
article_link = f'https://habr.com'
Получается ссылка, например: «https://habr.com/ru/company/tinkoff/blog/715604/»
Теперь указываем пару ключ — значение для названия и ссылку на статью (для нашего словаря):
article_dict[article_name] = article_link
Выходим из обоих циклов. С помощью конструкции «with open» создаем файл articles_ + дата и время создания файла с помощью модуля datetime, который мы импортировали, файл создаем с расширением .json (ну мне так удобнее), следующее мы указываем ‘w’, что означает, что нужно создать файл с таким-то названием и вписать следующий код, который мы укажем внутри файла, также указываем кодировку » encoding =’utf-8′ «, чтобы файл мог отобразить русские символы.
with open(f"articles_.json", "w", encoding='utf-8') as f:
Создаем конструкцию try, except (если нет ошибок при парсинге, выводится try, если выводится ошибка при парсинге => except)
try: except:
В try, мы «говорим», чтобы в json файл отправлялись данные, 1 — словарь с нашими статьями , 2 — имя файла, куда отправлять данные (в открытии файла мы указали в конце его как f, чтобы с ним можно было работать), 3 — отступы (я сделал 4 для удобства чтения, можно указать свое), 4 — экранирование ASCII символов, и следующей строкой вывод, что статьи успешно были получены.
print('Статьи были успешно получены')
В except, мы выводим, что статьи не удалось получить и нужно искать проблемы в коде.
print('Статьи не удалось получить')
В конечном итоге, должно получиться что-то похожее:
from bs4 import BeautifulSoup import random import json import requests import datetime from fake_useragent import UserAgent ua = UserAgent() headers = < 'accept': 'application/json, text/plain, */*', 'user-Agent': ua.google, >article_dict = <> url = f'https://habr.com/ru/top/daily/' req = requests.get(url, headers=headers).text soup = BeautifulSoup(req, 'lxml') all_hrefs_articles = soup.find_all('a', class_='tm-title__link') # получаем статьи for article in all_hrefs_articles: # проходимся по статьям article_name = article.find('span').text # собираем названия статей article_link = f'https://habr.com' # ссылки на статьи article_dict[article_name] = article_link with open(f"articles_.json", "w", encoding='utf-8') as f: try: json.dump(article_dict, f, indent=4, ensure_ascii=False) print('Статьи были успешно получены') except: print('Статьи не удалось получить')
Парсинг на Python с Beautiful Soup
Парсинг — это распространенный способ получения данных из интернета для разного типа приложений. Практически бесконечное количество информации в сети объясняет факт существования разнообразных инструментов для ее сбора. В процессе скрапинга компьютер отправляет запрос, в ответ на который получает HTML-документ. После этого начинается этап парсинга. Здесь уже можно сосредоточиться только на тех данных, которые нужны. В этом материале используем такие библиотеки, как Beautiful Soup, Ixml и Requests. Разберем их.
Установка библиотек для парсинга
Чтобы двигаться дальше, сначала выполните эти команды в терминале. Также рекомендуется использовать виртуальную среду, чтобы система «оставалась чистой».
pip install lxml pip install requests pip install beautifulsoup4
Поиск сайта для скрапинга
Для знакомства с процессом скрапинга можно воспользоваться сайтом https://quotes.toscrape.com/, который, похоже, был создан для этих целей.

Из него можно было бы создать, например, хранилище имен авторов, тегов или самих цитат. Но как это сделать? Сперва нужно изучить исходный код страницы. Это те данные, которые возвращаются в ответ на запрос. В современных браузерах этот код можно посмотреть, кликнув правой кнопкой на странице и нажав «Просмотр кода страницы».

На экране будет выведена сырая HTML-разметка страница. Например, такая:
На этом примере можно увидеть, что разметка включает массу на первый взгляд перемешенных данных. Задача веб-скрапинга — получение доступа к тем частям страницы, которые нужны. Многие разработчики используют регулярные выражения для этого, но библиотека Beautiful Soup в Python — более дружелюбный способ извлечения необходимой информации.
Создание скрипта скрапинга
В PyCharm (или другой IDE) добавим новый файл для кода, который будет отвечать за парсинг.
# scraper.py
import requests
from bs4 import BeautifulSoup
url = 'https://quotes.toscrape.com/'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
print(soup)Отрывок выше — это лишь начало кода. В первую очередь в верхней части файла выполняется импорт библиотек requests и Beautiful Soup. Затем в переменной url сохраняется адрес страницы, с которой будет поступать информация. Эта переменная затем передается функции requests.get() . Результат присваивается переменной response . Дальше используем конструктор BeautifulSoup() , чтобы поместить текст ответа в переменную soup . В качестве формата выберем lxml . Наконец, выведем переменную. Результат должен выглядеть приблизительно вот так.
Вот что происходит: ПО заходит на сайт, считывает данные, получает исходный код — все по аналогии с ручным подходом. Единственное отличие в том, что в этот раз достаточно лишь одного клика.
Прохождение по структуре HTML
HTML — это HyperText Markup Language («язык гипертекстовой разметки»), который работает за счет распространения элементов документа со специальными тегами. В HTML есть много разнообразных тегов, но стандартный шаблон включает три основных: html , head и body . Они организовывают весь документ. В случае со скрапингом интерес представляет только тег body .
Написанный скрипт уже получает данные о разметке из указанного адреса. Дальше нужно сосредоточиться на конкретных интересующих данных.
Если в браузере воспользоваться инструментом «Inspect» (CTRL+SHIFT+I), то можно достаточно просто увидеть, какая из частей разметки отвечает за тот или иной элемент страницы. Достаточно навести мышью на определенный тег span , как он подсветит соответствующую информацию на странице. Можно увидеть, что каждая цитата относится к тегу span с классом text .
Таким образом и происходит дешифровка данных, которые требуется получить. Сперва нужно найти некий шаблон на странице, а после этого — создать код, который бы работал для него. Можете поводить мышью и увидеть, что это работает для всех элементов. Можно увидеть соотношение любой цитаты на странице с соответствующим тегом в коде.
Скрапинг же позволяет извлекать все похожие разделы HTML-документа. И это все, что нужно знать об HTML для скрапинга.
Парсинг HTML-разметки
В HTML-документе хранится много информации, но благодаря Beautiful Soup проще находить нужные данные. Порой для этого требуется всего одна строка кода. Пойдем дальше и попробуем найти все теги span с классом text . Это, в свою очередь, вернет все теги. Когда нужно найти несколько одинаковых тегов, стоит использовать функцию find_all() .
# scraper.py
import requests
from bs4 import BeautifulSoup
url = 'https://quotes.toscrape.com/'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
quotes = soup.find_all('span', class_='text')
print(quotes)Этот код сработает, а переменной quotes будет присвоен список элементов span с классом text из HTML-документа. Вывод этой переменной даст следующий результат.
Свойство text библиотеки Beautiful Soup
Возвращаемая разметка — это не совсем то, что нужно. Для получения только данных — цитат в этом случае — можно использовать свойство .text из библиотеки Beautiful Soup. Обратите внимание на код, где происходит перебор всех полученных данных с выводом только нужного содержимого.
# scraper.py
import requests
from bs4 import BeautifulSoup
url = 'https://quotes.toscrape.com/'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
quotes = soup.find_all('span', class_='text')
for quote in quotes:
print(quote.text)Это и дает вывод, который требовался с самого начала.
Для поиска и вывода всех авторов можно использовать следующий код. Работаем по тому же принципу — сперва нужно вручную изучить страницу. Можно обратить внимание на то, что каждый автор заключен в тег с классом author . Дальше используем функцию find_all() и сохраняем результат в переменной authors . Также стоит поменять цикл, чтобы перебирать сразу и цитаты, и авторов.
# scraper.py
import requests
from bs4 import BeautifulSoup
url = 'https://quotes.toscrape.com/'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
quotes = soup.find_all('span', class_='text')
for quote in quotes:
print(quote.text)Таким образом теперь есть и цитаты, и их авторы.
“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.” --Albert Einstein “It is our choices, Harry, that show what we truly are, far more than our abilities.” --J.K. Rowling “There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.” --Albert Einstein .Наконец, добавим код получения всех тегов для каждой цитаты. Здесь уже немного сложнее, потому что сперва нужно получить каждый внешний блок каждой коллекции тегов. Если этот первый шаг не выполнить, то теги можно будет получить, но ассоциировать их с конкретной цитатой — нет.
Когда блок получен, можно опускаться ниже с помощью функции find_all для полученного подмножества. А уже дальше потребуется добавить внутренний цикл для завершения процесса.
# scraper.py
import requests
from bs4 import BeautifulSoup
url = 'https://quotes.toscrape.com/'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
quotes = soup.find_all('span', class_='text')
authors = soup.find_all('small', class_='author')
tags = soup.find_all('div', class_='tags')
for i in range(0, len(quotes)):
print(quotes[i].text)
print('--' + authors[i].text)
tagsforquote = tags[i].find_all('a', class_='tag')
for tagforquote in tagsforquote:
print(tagforquote.text)
print('\n')Этот код даст такой результат. Круто, не так ли?
“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.” --Albert Einstein change deep-thoughts thinking world “It is our choices, Harry, that show what we truly are, far more than our abilities.” --J.K. Rowling abilities choices .Практика парсинга с Beautiful Soup
Еще один хороший ресурс для изучения скрапинга — scrapingclub.com. Там есть множество руководств по использованию инструмента Scrapy. Также имеется несколько страниц, на которых можно попрактиковаться. Начнем с этой https://scrapingclub.com/exercise/list_basic/?page=1.
Нужно просто извлечь название элемента и его цену, отобразив данные в виде списка. Шаг первый — изучить исходный код для определения HTML. Судя по всему, здесь использовался Bootstrap.
После этого должен получиться следующий код.
# shop_scraper.py
import requests
from bs4 import BeautifulSoup
url = 'https://scrapingclub.com/exercise/list_basic/?page=1'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
items = soup.find_all('div', class_='col-lg-4 col-md-6 mb-4')
for n, i in enumerate(items, start=1):
itemName = i.find('h4', class_='card-title').text.strip()
itemPrice = i.find('h5').text
print(f': за ')1: $24.99 за Short Dress 2: $29.99 за Patterned Slacks 3: $49.99 за Short Chiffon Dress 4: $59.99 за Off-the-shoulder Dress .Скрапинг с учетом пагинации
Ссылка выше ведет на одну страницу коллекции, включающей на самом деле несколько страниц. На это указывает page=1 в адресе. Скрипт Beautiful Soup можно настроить и так, чтобы скрапинг происходил на нескольких страницах. Вот код, который будет извлекать данные со всех связанных страниц. Когда все URL захвачены, скрипт может выполнять запросы к каждой из них и парсить результаты.
# shop_scraper.py
# версия для понимания процессов
import requests
from bs4 import BeautifulSoup
url = 'https://scrapingclub.com/exercise/list_basic/?page=1'
response = requests.get(url)
soup = BeautifulSoup(response.text, 'lxml')
items = soup.find_all('div', class_='col-lg-4 col-md-6 mb-4')
for n, i in enumerate(items, start=1):
itemName = i.find('h4', class_='card-title').text.strip()
itemPrice = i.find('h5').text
print(f': за ')
pages = soup.find('ul', class_='pagination')
urls = []
links = pages.find_all('a', class_='page-link')
for link in links:
pageNum = int(link.text) if link.text.isdigit() else None
if pageNum != None:
hrefval = link.get('href')
urls.append(hrefval)
for slug in urls:
newUrl = url.replace('?page=1', slug)
response = requests.get(newUrl)
soup = BeautifulSoup(response.text, 'lxml')
items = soup.find_all('div', class_='col-lg-4 col-md-6 mb-4')
for n, i in enumerate(items, start=n):
itemName = i.find('h4', class_='card-title').text.strip()
itemPrice = i.find('h5').text
print(f': за ')Результат будет выглядеть следующим образом.
1: $24.99 за Short Dress 2: $29.99 за Patterned Slacks 3: $49.99 за Short Chiffon Dress . 52: $6.99 за T-shirt 53: $6.99 за T-shirt 54: $49.99 за BlazerЭтот код можно оптимизировать для более продвинутых читателей:
import requests
from bs4 import BeautifulSoup
url = 'https://scrapingclub.com/exercise/list_basic/'
params =
# задаем число больше номера первой страницы, для старта цикла
pages = 2
n = 1
while params['page'] for n, i in enumerate(items, start=n):
itemName = i.find('h4', class_='card-title').text.strip()
itemPrice = i.find('h5').text
print(f': за ')
# [-2] предпоследнее значение, потому что последнее "Next"
last_page_num = int(soup.find_all('a', class_='page-link')[-2].text)
pages = last_page_num if pages < last_page_num else pages
params['page'] += 1Выводы
Beautiful Soup — одна из немногих библиотек для скрапинга в Python. С ней очень просто начать работать. Скрипты можно использовать для сбора и компиляции данных из интернета, а результат — как для анализа данных, так и для других сценариев.
Как правильно парсить теги Html на Python
Есть вопрос как парсить Html страницы на python а точнее вот ссылка на страницу: https://3dtoday.ru/3d-models?page=1. Именно надо парсить этот кусок кода:
Не понимаю как спарсить текст тега ?
Отслеживать
задан 23 июн 2020 в 7:45
user388705 user3887052 ответа 2
Сортировка: Сброс на вариант по умолчанию
Вам нужно было воспользоваться requests и bs4
import requests from bs4 import BeautifulSoup r = requests.get('https://3dtoday.ru/3d-models?page=1') soup = BeautifulSoup(r.text, 'html.parser') element = soup.find_all('div', class_='threedmodels_models_list__elem__str') elem_soup = BeautifulSoup(str(element[1]), 'html.parser') title = elem_soup.find_all('a')[2].text print(title)Output: Держатель фильтра рожка кофеварки.
Ответ на комментарий, чтобы получить заголовки 18 элементов, нужно добавить цикл
for index in range(18): elem_soup = BeautifulSoup(str(element[index]), 'html.parser') title = elem_soup.find_all('a')[2].text print(title)Web Scraping с помощью python
Недавно заглянув на КиноПоиск, я обнаружила, что за долгие годы успела оставить более 1000 оценок и подумала, что было бы интересно поисследовать эти данные подробнее: менялись ли мои вкусы в кино с течением времени? есть ли годовая/недельная сезонность в активности? коррелируют ли мои оценки с рейтингом КиноПоиска, IMDb или кинокритиков?
Но прежде чем анализировать и строить красивые графики, нужно получить данные. К сожалению, многие сервисы (и КиноПоиск не исключение) не имеют публичного API, так что, приходится засучить рукава и парсить html-страницы. Именно о том, как скачать и распарсить web-cайт, я и хочу рассказать в этой статье.
В первую очередь статья предназначена для тех, кто всегда хотел разобраться с Web Scrapping, но не доходили руки или не знал с чего начать.Off-topic: к слову, Новый Кинопоиск под капотом использует запросы, которые возвращают данные об оценках в виде JSON, так что, задача могла быть решена и другим путем.
Задача
- Этап 1: выгрузить и сохранить html-страницы
- Этап 2: распарсить html в удобный для дальнейшего анализа формат (csv, json, pandas dataframe etc.)
Инструменты
- re
Регулярные выражения, конечно, нам пригодятся, но использовать только их, на мой взгляд, слишком хардкорный путь, и они немного не для этого. Были придуманы более удобные инструменты для разбора html, так что перейдем к ним. - BeatifulSoup, lxml
Это две наиболее популярные библиотеки для парсинга html и выбор одной из них, скорее, обусловлен личными предпочтениями. Более того, эти библиотеки тесно переплелись: BeautifulSoup стал использовать lxml в качестве внутреннего парсера для ускорения, а в lxml был добавлен модуль soupparser. Подробнее про плюсы и минусы этих библиотек можно почитать в обсуждении. Для сравнения подходов я буду парсить данные с помощью BeautifulSoup и используя XPath селекторы в модуле lxml.html. - scrapy
Это уже не просто библиотека, а целый open-source framework для получения данных с веб-страниц. В нем есть множество полезных функций: асинхронные запросы, возможность использовать XPath и CSS селекторы для обработки данных, удобная работа с кодировками и многое другое (подробнее можно почитать тут). Если бы моя задача была не разовой выгрузкой, а production процессом, то я бы выбрала его. В текущей постановке это overkill.
Загрузка данных
Первая попытка
Приступим к выгрузке данных. Для начала, попробуем просто получить страницу по url и сохранить в локальный файл.
import requests user_id = 12345 url = 'http://www.kinopoisk.ru/user/%d/votes/list/ord/date/page/2/#list' % (user_id) # url для второй страницы r = requests.get(url) with open('test.html', 'w') as output_file: output_file.write(r.text.encode('cp1251'))

Открываем полученный файл и видим, что все не так просто: сайт распознал в нас робота и не спешит показывать данные.
Разберемся, как работает браузер
Однако, у браузера отлично получается получать информацию с сайта. Посмотрим, как именно он отправляет запрос. Для этого воспользуемся панелью "Сеть" в "Инструментах разработчика" в браузере (я использую для этого Firebug), обычно нужный нам запрос — самый продолжительный.

Как мы видим, браузер также передает в headers UserAgent, cookie и еще ряд параметров. Для начала попробуем просто передать в header корректный UserAgent.
headers = < 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:45.0) Gecko/20100101 Firefox/45.0' >r = requests.get(url, headers = headers)
На этот раз все получилось, теперь нам отдаются нужные данные. Стоит отметить, что иногда сайт также проверяет корректность cookie, в таком случае помогут sessions в библиотеке Requests.
Скачаем все оценки
Теперь мы умеем сохранять одну страницу с оценками. Но обычно у пользователя достаточно много оценок и нужно проитерироваться по всем страницам. Интересующий нас номер страницы легко передать непосредственно в url. Остается только вопрос: "Как понять сколько всего страниц с оценками?" Я решила эту проблему следующим образом: если указать слишком большой номер страницы, то нам вернется вот такая страница без таблицы с фильмами. Таким образом мы можем итерироваться по страницам до тех, пор пока находится блок с оценками фильмов ( ).
Полный код для загрузки данных
import requests # establishing session s = requests.Session() s.headers.update(< 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:45.0) Gecko/20100101 Firefox/45.0' >) def load_user_data(user_id, page, session): url = 'http://www.kinopoisk.ru/user/%d/votes/list/ord/date/page/%d/#list' % (user_id, page) request = session.get(url) return request.text def contain_movies_data(text): soup = BeautifulSoup(text) film_list = soup.find('div', ) return film_list is not None # loading files page = 1 while True: data = load_user_data(user_id, page, s) if contain_movies_data(data): with open('./page_%d.html' % (page), 'w') as output_file: output_file.write(data.encode('cp1251')) page += 1 else: break
Парсинг
Немного про XPath
XPath — это язык запросов к xml и xhtml документов. Мы будем использовать XPath селекторы при работе с библиотекой lxml (документация). Рассмотрим небольшой пример работы с XPath
from lxml import html test = ''' one two
another tag
''' tree = html.fromstring(test) tree.xpath('//h2') # все h2 теги tree.xpath('//h2[@align]') # h2 теги с атрибутом align tree.xpath('//h2[@align="center"]') # h2 теги с атрибутом align равным "center" div_node = tree.xpath('//div')[0] # div тег div_node.xpath('.//h2') # все h2 теги, которые являются дочерними div ноде
Подробнее про синтаксис XPath также можно почитать на W3Schools.
Вернемся к нашей задаче
Теперь перейдем непосредственно к получению данных из html. Проще всего понять как устроена html-страница используя функцию "Инспектировать элемент" в браузере. В данном случае все довольно просто: вся таблица с оценками заключена в теге . Выделим эту ноду:
from bs4 import BeautifulSoup from lxml import html # Beautiful Soup soup = BeautifulSoup(text) film_list = soup.find('div', ) # lxml tree = html.fromstring(text) film_list_lxml = tree.xpath('//div[@class = "profileFilmsList"]')[0]

Каждый фильм представлен как или . Рассмотрим, как вытащить русское название фильма и ссылку на страницу фильма (также узнаем, как получить текст и значение атрибута).
# Beatiful Soup movie_link = item.find('div', ).find('a').get('href') movie_desc = item.find('div', ).find('a').text # lxml movie_link = item_lxml.xpath('.//div[@class = "nameRus"]/a/@href')[0] movie_desc = item_lxml.xpath('.//div[@class = "nameRus"]/a/text()')[0]
Еще небольшой хинт для debug'a: для того, чтобы посмотреть, что внутри выбранной ноды в BeautifulSoup можно просто распечатать ее, а в lxml воспользоваться функцией tostring() модуля etree.
# BeatifulSoup print item #lxml from lxml import etree print etree.tostring(item_lxml)
Полный код для парсинга html-файлов под катом
def read_file(filename): with open(filename) as input_file: text = input_file.read() return text def parse_user_datafile_bs(filename): results = [] text = read_file(filename) soup = BeautifulSoup(text) film_list = film_list = soup.find('div', ) items = film_list.find_all('div', ) for item in items: # getting movie_id movie_link = item.find('div', ).find('a').get('href') movie_desc = item.find('div', ).find('a').text movie_id = re.findall('\d+', movie_link)[0] # getting english name name_eng = item.find('div', ).text #getting watch time watch_datetime = item.find('div', ).text date_watched, time_watched = re.match('(\d\.\d\.\d), (\d:\d)', watch_datetime).groups() # getting user rating user_rating = item.find('div', ).text if user_rating: user_rating = int(user_rating) results.append(< 'movie_id': movie_id, 'name_eng': name_eng, 'date_watched': date_watched, 'time_watched': time_watched, 'user_rating': user_rating, 'movie_desc': movie_desc >) return results def parse_user_datafile_lxml(filename): results = [] text = read_file(filename) tree = html.fromstring(text) film_list_lxml = tree.xpath('//div[@class = "profileFilmsList"]')[0] items_lxml = film_list_lxml.xpath('//div[@class = "item even" or @class = "item"]') for item_lxml in items_lxml: # getting movie id movie_link = item_lxml.xpath('.//div[@class = "nameRus"]/a/@href')[0] movie_desc = item_lxml.xpath('.//div[@class = "nameRus"]/a/text()')[0] movie_id = re.findall('\d+', movie_link)[0] # getting english name name_eng = item_lxml.xpath('.//div[@class = "nameEng"]/text()')[0] # getting watch time watch_datetime = item_lxml.xpath('.//div[@class = "date"]/text()')[0] date_watched, time_watched = re.match('(\d\.\d\.\d), (\d:\d)', watch_datetime).groups() # getting user rating user_rating = item_lxml.xpath('.//div[@class = "vote"]/text()') if user_rating: user_rating = int(user_rating[0]) results.append(< 'movie_id': movie_id, 'name_eng': name_eng, 'date_watched': date_watched, 'time_watched': time_watched, 'user_rating': user_rating, 'movie_desc': movie_desc >) return results
Резюме

В результате, мы научились парсить web-сайты, познакомились с библиотеками Requests, BeautifulSoup и lxml, а также получили пригодные для дальнейшего анализа данные о просмотренных фильмах на КиноПоиске.
Полный код проекта можно найти на github'e.
UPD
- Аутентификация: зачастую для того, чтобы получить данные с сайта нужно пройти аутентификацию, в простейшем случае это просто HTTP Basic Auth: логин и пароль. Тут нам снова поможет библиотека Requests. Кроме того, широко распространена oauth2: как использовать oauth2 в python можно почитать на stackoverflow. Также в комментариях есть пример от Terras того, как пройти аутентификацию в web-форме.
- Контролы: На сайте также могут быть дополнительные web-формы (выпадающие списки, check box'ы итд). Алгоритм работы с ними примерно тот же: смотрим, что посылает браузер и отправляем эти же параметры как data в POST-запрос (Requests, stackoverflow). Также могу порекомендовать посмотреть 2й урок курса "Data Wrangling" на Udacity, где подробно рассмотрен пример scrapping сайта US Department of Transportation и посылка данных web-форм.




