{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Python для сбора данных\n", "\n", "*Алла Тамбовцева, НИУ ВШЭ*\n", "\n", "### Задание 1\n", "\n", "Используя код с лекции, напишите функцию, которая принимает на вход ссылку на страницу новости на сайте [nplus1.ru](https://nplus1.ru/) и возвращает список из следующих элементов:\n", "\n", "* название новости;\n", "* краткое описание новости;\n", "* имя автора новости;\n", "* рубрики, к которым относится новость;\n", "* сложность текста новости;\n", "* текст новости." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Используя код с лекции, получаем:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import requests\n", "from bs4 import BeautifulSoup\n", "\n", "def get_info(url0):\n", " page0 = requests.get(url0)\n", " soup0 = BeautifulSoup(page0.text, 'lxml')\n", " author = soup0.find_all('meta', \n", " {'name' : 'author'})[0]['content']\n", " title = soup0.find_all('meta', \n", " {'property' : 'og:title'})[0]['content']\n", " description = soup0.find_all('meta', \n", " {'property' : 'og:description'})[0]['content']\n", " date = soup0.find_all('meta', \n", " {'itemprop' : 'datePublished'})[0]['content']\n", " difficult = soup0.find_all('span', \n", " {'class' : 'difficult-value'})[0].text\n", " raw_rubrics = soup0.find_all('p', \n", " {'class' : 'table'})[0].find_all('a')\n", " rubrics = []\n", " for r in raw_rubrics:\n", " rubrics.append(r.text)\n", " \n", " pars = []\n", " for p in soup0.find_all('p', {'class' : None}):\n", " pars.append(p.text)\n", " text = \" \".join(pars)\n", " \n", " text_final = text.split(\"Нашли опечатку?\")[0].replace('\\xa0', \n", " ' ').replace('\\n', ' ')\n", " return [author, title, description, date, difficult, \n", " rubrics, text_final] " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Задание 2\n", "\n", "Создайте список ссылок на новости с главной страницы сайта [nplus1.ru](https://nplus1.ru/), примените написанную в задании 1 функцию к каждой ссылке в списке и сформируйте новый список списков с данными по новостям. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Список ссылок тоже был создан на лекции:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "url = \"https://nplus1.ru/\"\n", "page = requests.get(url)\n", "soup = BeautifulSoup(page.text)\n", "\n", "urls = []\n", "for link in soup.find_all('a'):\n", " if '/news' in link.get('href'):\n", " urls.append(link.get('href'))\n", " \n", "full_urls = ['https://nplus1.ru' + u for u in urls]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Но давайте не будем спешить: импортируем функцию `sleep` для задержки, чтобы на каждой итерации цикла, прежде чем перейти к следующей новости, Python ждал несколько секунд. Во-первых, это нужно, чтобы сайт «не понял», чтобы мы его грабим, да еще автоматически. Во-вторых, с небольшой задержкой всегда есть гарантия, что страница прогрузится (сейчас это пока не очень важно, но особенно актуально будет, когда будем обсуждать встраивание в браузер с Selenium). Приступим." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "https://nplus1.ru/news/2020/04/27/venus-atmosphere-tidal-waves...done\n", "https://nplus1.ru/news/2020/04/27/zumwalt...done\n", "https://nplus1.ru/news/2020/04/27/starship-pressure-passed...done\n", "https://nplus1.ru/news/2020/04/27/e-fan-x...done\n", "https://nplus1.ru/news/2020/04/25/hyperphagia-neurons...done\n", "https://nplus1.ru/news/2020/04/25/dna-pocket...done\n", "https://nplus1.ru/news/2020/04/25/moon-landing-spray...done\n", "https://nplus1.ru/news/2020/04/25/thermogalvanic-hydrogel-cooling...done\n", "https://nplus1.ru/news/2020/04/24/30-years-hubble...done\n", "https://nplus1.ru/news/2020/04/24/feline-grimace-scale...done\n", "https://nplus1.ru/news/2020/04/24/supermassive-black-hole-escape-star...done\n", "https://nplus1.ru/news/2020/04/24/adobe...done\n", "https://nplus1.ru/news/2020/04/24/broken-hearts...done\n", "https://nplus1.ru/news/2020/04/24/00s-taxi...done\n", "https://nplus1.ru/news/2020/04/24/cold-sweet...done\n", "https://nplus1.ru/news/2020/04/24/avian...done\n", "https://nplus1.ru/news/2020/04/24/kentaurs-interstellar...done\n", "https://nplus1.ru/news/2020/04/24/ocean-macroplastic-finding...done\n", "https://nplus1.ru/news/2020/04/24/smartwatch...done\n", "https://nplus1.ru/news/2020/04/24/antarctic-calyptocephalella...done\n", "https://nplus1.ru/news/2020/04/23/underwater-quantum-communication...done\n", "https://nplus1.ru/news/2020/04/21/self-adapt-PVDF...done\n", "https://nplus1.ru/news/2020/04/27/venus-atmosphere-tidal-waves...done\n", "https://nplus1.ru/news/2020/04/25/thermogalvanic-hydrogel-cooling...done\n", "https://nplus1.ru/news/2020/04/25/hyperphagia-neurons...done\n", "https://nplus1.ru/news/2020/04/22/carbon-nanothread-bundle...done\n", "https://nplus1.ru/news/2020/04/21/model-based-learning...done\n", "https://nplus1.ru/news/2020/04/23/gw-190412-ligo...done\n", "https://nplus1.ru/news/2020/04/21/digital-embryo...done\n" ] } ], "source": [ "from time import sleep\n", "\n", "data = []\n", "for u in full_urls:\n", " res = get_info(u)\n", " data.append(res)\n", " print(u + \"...done\")\n", " sleep(0.5) # задержка 0.5 секунд" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Задание 3\n", "\n", "Преобразуйте полученный в задании 2 список в датафрейм, добавьте названия столбцов, при необходимости измените тип столбцов. Выгрузите полученный датафрейм в файл Excel." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "\n", "df = pd.DataFrame(data)\n", "df.columns = ['author', 'title', 'description', 'date', 'difficult', \n", " 'rubrics', 'text']\n", "\n", "df['difficult'] = df['difficult'].astype(float)\n", "df.to_excel('nplus1.xlsx')" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.4" } }, "nbformat": 4, "nbformat_minor": 2 }