<jupyter_start><jupyter_text>Python для анализа данных Веб-скрэйпинг: сбор информации со страницы (дополнительный материал).*Автор: <NAME>, НИУ ВШЭ*В этом примере мы зайдем на сайт государственной думы и попробуем получить данные обо всех ее депутатах, в какой фракции и комитете он состоит, а также занимаю должность. Все это в итоге представим в виде DataFrame и сохраним как csv файл, для дальнейшей работы.Делаем все как обычно, заходим на сайт думы, используем requests и BeatifulSoup<jupyter_code>import requests
from bs4 import BeautifulSoup
import pandas as pd
import re

url = "http://duma.gov.ru/duma/deputies/7/"
page = requests.get(url)

text = page.text
soup = BeautifulSoup(text, "html.parser")<jupyter_output><empty_output><jupyter_text>Имена депутатов будет хранить в deputates, комитеты в которых они состоят в commissions, должность в occupations и партию в party.<jupyter_code>deputates = []
commissions = []
occupations = []
party = []<jupyter_output><empty_output><jupyter_text>Депутатов много (487 человек) и скрейпинг может занимать прилично времени. Поэтому ограничим количество обработанных человек с помощью счетчика count и проверки. Для примера оставим 10 человек.Данные обо всхе депутатах находятся в теге "a" и с классом "person__image-wrapper person__image-wrapper--s"Найдем все такие теги<jupyter_code>count = 0    
person = soup.find_all('a', class_ = "person__image-wrapper person__image-wrapper--s")<jupyter_output><empty_output><jupyter_text>Теперь для каждого депутата мы должны получить его имя и ссылку, по которой мы пройдем и выясним остальную информацию: комитет, должность и фракцию.К нашему счастью вместе с фото депутата в теге "img" хранится элемент  "alt" которой по наведению на фото, покажет в левом нижнем углу текст, который в нашем случае представляет собой Имя Фамилию и Отчество. Если бы не это, нам пришлось бы делать два поиска по тегам, т.к. имя хранится в одном теге, а фамилия и отчество в другом.В том же теге "img" хранится ссылка на страницу с этим конкретным депутатом. Получим ее из элемента "href". Поэтому не нужно делать новый поиск тега.Делаем обычный request к странице депутата, как мы делали в примере с PDF.На странице с депутатом нам нужно найти тег в котором хранится его комитет и фракция. Посмотрев исходный код страницы, находим нужные теги - "a" с классами link "link--underline link--external" и "link link--underline person__description__link". Сохраняем их по своим массивамОдна проблема, должность в комитете находится в строке с самим комитетом. Но к нашему счастью, они указываются в скобочках. Поэтому найдем индекс первого появления скобочек в строке с комитетом. Вырежем их и запишем в нужный массив. Точно также запишем комитет, обрезав у него конец строки<jupyter_code>person[0]
for p in person:
    print(p.find('img'))
    name = p.find('img')
    print(name.get('alt'))
    print(p.get('href'))
    print(deputates)
    url_deput = "http://duma.gov.ru/" + p.get("href")
    print(url_deput)
    page = requests.get(url_deput)
    soup_deput = BeautifulSoup(page.text, "html.parser")
    comm = soup_deput.find('a', class_ = "link link--underline link--external")
    #print(comm)
    t = comm.text.strip()
    t_new = t[:t.find('(')]
    print(t_new)
    break
t = comm.text.strip()
t[t.find('(')]
for p in person:  
    
    # Обрезаем скрейпинг, т.к. очень долго идет обработка
    if count > 10:
        break
    
    #Получаем имена
    name = p.find('img', class_ = 'person__image person__image--s') # находим тег img и забираем из него значение alt
    deputates.append(name.get("alt"))
    
    # Получаем ссылку на депутата
    url_deput = "http://duma.gov.ru/" + p.get("href") # в нашем найденном теге уже есть нужная ссылка на депутата. Забираем ее
    
    # Делаем запрос
    page = requests.get(url_deput)
    soup_deput = BeautifulSoup(page.text, "html.parser")
    
    #Ищем комитет
    comm = soup_deput.find('a', class_ = "link link--underline link--external")
    t = comm.text.strip("\n")
    # регулярным выражением убираем все непечатный символы
    commissions.append(re.sub('\W+',' ',t[:t.index("(")-1]).strip()) # убираем должность
    occupations.append(t[t.index("(") + 1:t.index(")")]) #должность всегда в скобочках, 
                                                         #находим первые вхождени ( и )

    # Поиск фракции
    part = soup_deput.find('a', class_ = "link link--underline person__description__link")
    party.append(part.text)

    count += 1 # обновляем счетчик<jupyter_output><empty_output><jupyter_text>Все данные получены, осталось создать DataFrame и сохранить его в виде csv<jupyter_code>df = pd.DataFrame({'Депутат': deputates, 'Коммитет':commissions ,'Должность':occupations, 'Фракция': party})
df.to_csv("Gos_duma.csv")<jupyter_output><empty_output><jupyter_text>Можно посмотреть на первые несколького элементов используя команду df.head()<jupyter_code>df.head()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09775349119611415, 'fraction_numerical': 0.0028334345274235984, 'mean_word_length': 4.342702702702702, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '375227', 'license': 'MIT', 'n_tokens_mistral': 1905, 'n_tokens_neox': 2136, 'n_words': 514, 'path': '01 python/lect 8 materials/8_Bonus_Scraping.ipynb', 'repo_name': 'ksetdekov/HSE_DS', 'size': '4950'}