{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Анализа текстуалних података - припрема текста са блога и/ли сајта" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Податке које генеришемо и/ли желимо да обрадимо и анализирамо често су у текстуалном формату (помислите само на извештаје лекара, текстове закона, текстове порука размењених на друштвеним мрежама...), због чега ћемо се у наредном сегменту позабавити и анализом текста. Ова област је изузетно велика и активна (нове методе и алгоритми генеришу се готово на дневном нивоу), те не претендујемо да овде одговоримо на сва питања у вези са текстом већ да отворимо нека почетна питања и понудимо неке од алата за једноставне анализе, које ће, надамо се, послужити као мотивација за нека будућа истраживања.\n", "\n", "Ова радна свеска служи да се прикупе текстуални подаци са веб страна и сачувају у *csv* фајл тако да можемо да се бавимо анализом како смо и до сада навикли. Савладавање ове радне свеске није неопходно за праћење остатка, она више служи за инспирацију уколико будете желели да преузмете и анализирате неки други текст са интернета. У наставку ћемо показати како се:\n", "- преузима текст са веб стране\n", "- користе библиотеке *requests* и *beautifulsoup* за издвајање корисних и текстуалних података из *html* фајла" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# библиотеке које ћемо користити за преузимање текста са веб страна\n", "import requests\n", "import bs4 as bs\n", "\n", "# библиотека функција за баратање стринговима, од користи за анализу текста\n", "import string\n", "\n", "# претходно коришћене библиотеке за манипулацију подацима и цртање\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "У овој радној свесци преузећемо текстове са ових веб адреса:\n", "\n", "https://petlja.org/petlja/fondacija\n", "\n", "https://petlja.org/petlja/foundation/" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "У оквиру библиотеке [**requests**](https://requests.readthedocs.io/en/master/) налази се функција **get** уз помоћ које ћемо преузети садржај са жељене веб адресе:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "url = 'https://petlja.org/petlja/fondacija'\n", "stranica = requests.get(url)\n", "#stranica.text" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "У *stranici* је сада садржај ове веб стране, а ако нас занима само текст, то можемо проверити користећи **stranica.text**, међутим тако ћемо бити затрпани *html* кодом у мање читљивом формату (пробајте!). Како би нам преузети сарджај био читљивији, од помоћи ће нам бити функција [**BeautifulSoup**](https://www.crummy.com/software/BeautifulSoup/bs4/doc/) која ће дати садржај разложити препознајући *html* структуру и раздвојити све тагове у нове редове (упоредите садржај soup и stranica.text)." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "soup = bs.BeautifulSoup(stranica.text,\"html.parser\")\n", "#soup" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Следећа линија кода је тренутно искоментарисана зато што је њен исход велика количина html кода, која нам служи за брзу претрагу и уочавање уз који таг се налази текст са сајта који желимо да преузмемо. \n", "\n", "Постоје алтернативни начини да ово потражите користећи свој претраживач (углавном користећи Developer алате у свом претраживачу), али овде се фокусирамо на претрагу у оквиру ове радне свеске. \n", "Једноставно речено, циљ нам је да у прегршти текста који ће бити исписан када се наредна линија покрене, препознамо html структуру, то јест да су информације углавном оивичене таговима, нпр. ```
``` и ```<\\body>```. Циљ нам је да нађемо блок текста на српском, односно енглеском и да видимо који таг је искоришћен да тај текст означи." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": false }, "outputs": [], "source": [ "#print(soup.prettify())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Претходном претрагом у позадини наше жељене веб стране дошли смо до тага уз текст који пратимо `````` и ```<\\p>```, као и да је атрибут који прати тај таг ```{'class':'mb-3'}```.\n", "Практична ствар је што са библиотеком коју користимо не морамо да пишемо функцију која ће пронаћи сва појављивања овог тага са одређеним атрибутом, та функција већ постоји: **find_all**. Њеним позивањем добићемо све сегменте претходног html кода који су оивичени задатим тагом." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "potencijalnitekst = soup.find_all('p',attrs={'class':'mb-3'})\n", "#potencijalnitekst" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ако последњу линију покренете, приметићете да је *potencijalnitekst* заправо листа, те ћемо у наставку проверити њену дужину и преузети садржај свих елемената." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Уколико желите да анализирате текстове са неких других веб страна, претходни процес ће најчешће бити ствар коју ћете морати да измените у коду пошто различити аутори веб страна уз другачије тагове пакују текст, нпр. ако желите да преузмете текстове популарних музичких песама са нпр. [овог сајта](https://lyrics.fandom.com/wiki/ABBA:Dancing_Queen) текст ћете наћи уз таг ```div```, ca атрибутом ```{'class':'lyricsbox'}```. Оба ова тага су у складу са очекивањима, p долази од речи параграф (енг. *paragrah*), док је div сегмент (енг. *division*)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Видимо да су сви параграфи текста преузети (што можемо проверити и одласком на дату веб страну), али су тагови још увек ту, и има више сегментата, текста, тачније:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "7" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(potencijalnitekst)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Како је potencijalnitekst листа, можемо погледати садржај првог елемента:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "
\n",
" Smatramo da je razumevanje algoritama i umeće algoritamskog izražavanja potrebno svima, a takođe je važno da oni koji su talentovani za programiranje svoj talenat prepoznaju i razvijaju.
\n",
"\n",
" Za sticanja algoritamske pismenosti neophodan je neki vid programiranja, isto kao što se bez praktikovanja pismenog izražavanja ne može steći klasična pismenost. Programiranje ne mora biti komplikovano, rezervisano za stručnjake, a suvoparno i dosadno ostalima. Naša želja je da programiranje približimo svima: deci i njihovim roditeljima, učenicima i njihovim nastavnicima, radoznalim korisnicima tehnologije i svim ljudima koji se pitanju šta je sledeće što treba da nauče.\n",
"
\n", " | Rec | \n", "
---|---|
0 | \n", "Smatramo | \n", "
1 | \n", "da | \n", "