• 4 июля стартует курс «Python для Пентестера ©» от команды The Codeby

    Понятные и наглядные учебные материалы с информацией для выполнения ДЗ; Проверка ДЗ вручную – наставник поможет улучшить написанный вами код; Помощь преподавателей при выполнении заданий или в изучении теории; Групповой чат в Telegram с другими учениками, проходящими курс; Опытные разработчики – команда Codeby School, лидер по информационной безопасности в RU-сегменте

    Запись на курс до 15 июля. Подробнее ...

  • 11 июля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 20 июля. Подробнее ...

Статья Парсим ресурсы Codeby на языке Python

i



🧰 Что такое парсинг?
Парсинг (Parsing) – это принятое в информатике определение синтаксического анализа. Для этого создается математическая модель сравнения лексем с формальной грамматикой, описанная одним из языков программирования. Например, PHP, Perl, Ruby, Python.
Когда человек читает, то, с точки зрения науки филологии, он совершает синтаксический анализ, сравнивая увиденные на бумаге слова (лексемы) с теми, что есть в его словарном запасе (формальной грамматикой).
Программа (скрипт), дающая возможность компьютеру «читать» – сравнивать предложенные слова с имеющимися во Всемирной сети, называется парсером. Сфера применения таких программ очень широка, но все они работают практически по одному алгоритму.
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀Источник:
👋 План действий
Сегодня я вам расскажу как правильно парсить данные с помощью языка Python, и будем мы парсить именно codeby ресурсы.
Если зайти на страницу ресурсов:

Screenshot 2022-06-13 at 15-38-34 Брендинг codeby.png

то мы увидим обычные ресурсы, которые видит любой пользователь Codeby (парсинг контента для авторизованных пользователей я сделаю позже), а сейчас мы должны спарсить эти ресурсы, что именно мы будем получать с сайта?


Screenshot 2022-06-13 at 15-40-24 Брендинг codeby.png

Мы должны спарсить этот блок, включая: название ресурса, автор ресурса, дата создания ресурса и так же описание ресурса ("Исходник в векторе, png и jpg"), ну и конечно же после этого мы должны всё это экспортировать в CSV файле.
Надеюсь вы поняли, приступим к коду.


✴️ Пишем парсер
Перед написанием кода нужно установить 3 библиотеки - requests, csv, bs4

установка библиотеки requests
pip install requests

установка библиотеки BeautifulSoup(bs4)
pip install bs4

установка библиотеки Csv
pip install csv

●︎ requests - нужен для запросов, обращение к сайту(codeby.net);
●︎ beautifulSoup - нужен для парсинга, а именно для нас парсинг блоков;
●︎ csv - нужен для порядка данных, таблица.

После установки библиотек создадим несколько библиотек данных Codeby:
Python:
import requests
from bs4 import BeautifulSoup
import csv

CSV = 'resources.csv' # создания csv файла после запуска парсинга (можете указать путь)
HOST = "https://codeby.net/" # хост
URL = "https://codeby.net/resources/categories/brending-codeby.11/" # страница где мы именно будем парсить\
pages = requests.get(URL) # передаем наш URL ссылку к pages'y

первые три строчки для импортирования, переменная CSV это путь создания csv файла (таблица), в нашем случае он создастся в текущем каталоге, где находится python файл;
переменная HOST хранит ссылку на сайт, в нашем случае codeby;
переменная URL хранит ссылку страницы где мы будем парсить;
переменная pages хранит тот самый URL в качестве requests, без этого у вас не получится подключиться к этой странице.


После того как мы это сделали, нам нужны заголовки, а точнее юзер-агент и accept, их указывать обязательно не нужно, но без них некоторые сайты блокируют ваш IP, так что в случае такой ситуации рекомендуется это сделать.

Нам нужны User-agent и Accept, где их достать? Заходим на сайт где ресурсы кодебай (не приватные), дальше открываем код элемента, и нажимаем на Netwrok, не закрывая окна обновляем страницу, здесь у нас появятся вот эти фильтры:
image(1).png


где указано стрелочками нажимаем, и дальше откроется окошко с данными, но нам нужны именно User-Agent и Accept:
image.png


сразу копируем.

А теперь нам надо эти данные впихнуть в словаре, для этого в питоне нужно сделать словарь:
Python:
HEADERS = {

    "accept": "ext/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
    "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0"
}

вот и всё, словарь заполнен, переходим к функциям.


1️⃣ Создаем функцию get_html()

Данная функция предназначена для запроса к сайту, использовании заголовков (HEADERS) и параметров, давайте напишем эту функцию:
Python:
# подключение к странице

def get_html(url, params=''):
    r = requests.get(url, headers=HEADERS, params=params)
    return r

get_html принимает два аргумента url, params. Аргумент url принимает саму ссылку. А вот params уже не так важен. Он нужен, если на сайте будут какие-то параметры, типа: codeby.net...?page. Так как на странице ресурсов отсутствуют такие параметры, то аргумент вы можете просто оставить пустым. В переменной r уже происходит GET-запрос к сайту с помощью библиотеки requests, где мы передаем headers, url и params. Затем возвращаем ответ c помощью return.


2️⃣ Создаем функцию get_content()

Вот и дошли до функции, которая будет отвечать за парсинг. Давайте её напишем:
Python:
# полученные html элементы: парсим с bs4
def get_content(html):
    soup = BeautifulSoup(pages.text, 'html.parser')
    items = soup.find_all("div", class_="structItem")
    resources = [] # место где добавляются ресурсы
Функция get_content принимает аргумент html. Затем создаётся переменная soup, которая необходима для сбора данных со страницы. Переменная items хранит весь блок ресурса (который оставил выше), он хранится в div элементе а его класс structItem. И как же это получить? Всё просто, открываем код элемента, выделяем блок и видим данные:

image(2).png

Все блоки имеют div элементы, а так же класс StructItem (скопировать весь класс необязательно). Теперь у нас будет доступ ко всем блокам.

В списке resources уже будут внутренние блоки, а именно: название ресурса, дата создания ресурса, автор ресурса и описание, для этого сделаем небольшой цикл for:
Python:
# цикл: перебираем все данные ресурса включая:(Название ресурса, автор, дата создание)
    for item in items:
        resources.append(
            {

                "title":item.find("div", class_="structItem-title").get_text(), # название ресурса
                "author": item.find("a", class_="username").get_text(), # автор ресурса
                "time": item.find("time", class_="u-dt").get_text(), # дата создание ресурса
                "desc": item.find("div", class_="structItem-resourceTagLine").get_text() # описание ресурса
            }

        )

    return resources

Здесь создаем цикл, который перебирает и добавляет все данные уже в список resources с помощью функции append():
image_code.png

Похожие блоки включают в себя время создания ресурса, его автора и т.п. Я думаю, что сделать это будет не так уж и сложно.

Вот и всё, мы закончили с парсингом (наконец-то), а теперь сделаем функцию, которая всё это сохранит в CSV-файл,

3️⃣Создаем функцию save_documents_csv()

Эта функция, которая будет сохранять все наши данные в CSV-файл. Лет'с гоу:
Python:
def save_documents_csv(items, path):
    with open(path, "w", newline='') as file:
        writer = csv.writer(file, delimiter=";")
        writer.writerow(['Название ресурсов', "Автор ресурсов", "Дата создание ресурсов", "Описание"])
        resources = []

        for item in items:
            writer.writerow([item['title'], item["author"], item["time"], item["desc"]])

Делаем режим для записи файла (w - write), затем с помощью writerow создаем блоки, где каждый блок будет иметь соответствующие данные. Например, в ключе title хранится значение об авторе ресурса.


4️⃣Создаем функцию parser()

Это последняя функция, которая нужна для запуска парсинга, вывода и сохранении в csv файле)
Код функции:

Python:
def parser():
    html = get_html(URL)
    if html.status_code == 200:
        resource = []
        resource.extend(get_content(html.text))
        save_documents_csv(resource, CSV)
    #print(get_content(html))
    #save_documents_csv(CSV)
parser()

Переменная html хранит исходный код страницы. С помощью условия if html.status_code == 200: мы проверяем, что статус ответа от сервера равен 200(успешное подключение), то у нас запустится парсинг. Функция save_documents_csv сохранит эти данные в CSV-файле.
Вот и всё!

📓Весь код

Python:
import requests # нужен запросы, обращаться сайт, статус и т.п
from bs4 import BeautifulSoup # парсинг, собрирать данные и многое другое
import csv # таблица данных, лучше чем в терминале))


# Resources [https://codeby.net/resources/categories/brending-codeby.11/]
# Domain [https://codeby.net/]
# Block Resource(test): DIV structItem structItem--resource is-prefix2  js-inlineModContainer js-resourceListItem-896
# All block resources: structItem-cell structItem-cell--icon structItem-cell--iconExpanded

CSV = 'resources.csv'
HOST = "https://codeby.net/"
URL = "https://codeby.net/resources/categories/brending-codeby.11/"
pages = requests.get(URL)
# User-Agent Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0
# ext/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
HEADERS = {

    "accept": "ext/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
    "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0"
}

# подключение к странице
def get_html(url, params=''):
    r = requests.get(url, headers=HEADERS, params=params)
    return r

# полученные html элементы: парсим с bs4
def get_content(html):
    soup = BeautifulSoup(pages.text, 'html.parser')
    items = soup.find_all("div", class_="structItem")
    resources = [] # место где добавляются ресурсы


# цикл: перебираем все данные ресурса включая:(Название ресурса, автор, дата создание)
    for item in items:
        resources.append(
            {

                "title":item.find("div", class_="structItem-title").get_text(), # название ресурса
                "author": item.find("a", class_="username").get_text(), # автор ресурса
                "time": item.find("time", class_="u-dt").get_text(), # дата создание ресурса
                "desc": item.find("div", class_="structItem-resourceTagLine").get_text() # описание ресурса
            }

        )

    return resources


def save_documents_csv(items, path):
    with open(path, "w", newline='') as file:
        writer = csv.writer(file, delimiter=";")
        writer.writerow(['Название ресурсов', "Автор ресурсов", "Дата создание ресурсов", "Описание"])
        resources = []

        for item in items:
            writer.writerow([item['title'], item["author"], item["time"], item["desc"]])

def parser():
    html = get_html(URL)
    if html.status_code == 200:
        resource = []
        resource.extend(get_content(html.text))
        save_documents_csv(resource, CSV)
    #print(get_content(html))
    #save_documents_csv(CSV)
parser()


📑Результат работы парсинга:
Screenshot_2022-06-13_at_00-42-39_CSV_Viewer_Online.png

Результат кода парсинга в CSV формате. Всё успешно работает.


📂 Важные ссылки
Документация по библиотеке requests -
Документация по библиотеке BeautifulSoup -

Уроки по библиотеке csv -

Нашли ошибку в тексте или коде? Срочно сообщите!
 
Последнее редактирование модератором:

OldGuard

One Level
28.02.2020
7
5
Даже не слыхал про это))) (в плане использовании)
прочитаю как нибудь про апи
Я так понял, что изучаешь тему и заодно документируешь, чтобы лучше отложилось в памяти. Молодец) Желаю успехов в дальнейшем развитии)
 
  • Нравится
Реакции: MLNK и I3ody_World

f22

Codeby Team
Gold Team
05.05.2019
1 631
153
Нам нужны User-agent и Accept, где их достать?
Гораздо проще воспользоваться готовым модулем)


Ну или выбрать любой другой похожий





нная функция предназначена для запроса к сайту, использовании заголовков (HEADERS) и параметров, давайте напишем эту функцию:
А зачем нужна переменная r?

Раз уж вы стали изучать язык python, неплохо было бы ознакомиться со стандартами написания кода, в том числе и PEP8
Добавьте в своём редакторе кода настройку, которая будет подсвечивать недочёты. В том же pycharm она работает из коробки и выдаёт вот такое полотно)
1655211768924.png

Неплохо было бы добавить аннотирование переменных и функций, документ строки с описанием и точку входа для более понятного внешнего вида.


Попробуйте добавить к вашей программе какой-нибудь графический интерфейс и поддержку прокси - будет выглядеть ещё лучше)

Успехов!
 

I3ody_World

Green Team
11.06.2022
31
18
Огромное спасибо вам! П
Гораздо проще воспользоваться готовым модулем)

Огромное спасибо за ваш теплый ответ. Про fake_useragent я вообще не знал, теперь буду знать спасибо
А зачем нужна переменная r?
Переменная r это сам рекуист который можно посмотреть статус состояние подключение, вывод, ну и многое другое

Раз уж вы стали изучать язык python, неплохо было бы ознакомиться со стандартами написания кода, в том числе и PEP8
Добавьте в своём редакторе кода настройку, которая будет подсвечивать недочёты. В том же pycharm она работает из коробки и выдаёт вот такое полотно)
1655211768924.png 1655211768924.png
очень много ворнингов согласен))) хм, наверное в 3.10 версии PEP изменился, надо сделать код свежим, в коментах оставлю

Попробуйте добавить к вашей программе какой-нибудь графический интерфейс и поддержку прокси - будет выглядеть ещё лучше)
сделать на GUI это было бы вообще кайф, что касается прокси, вот знаешь я очень много пытался получать их, бесплатные прокси найдешь в интернете но они как то не действует , питон говорит что они не правильные..((
а покупать прокси не так уж и хочется..

Спасибо тебе за ответ, для меня это ЧеСтЬ )))
 

I3ody_World

Green Team
11.06.2022
31
18
Друзья, выше код из статьи я изменил, оказывается в нашем коде есть 20+- Warning'ов который показывает Pycharm, следуя по инструкции PEP8 я убрал эти ворнинги теперь нет никаких проблемов.
Python:
import requests  # нужен запросы, обращаться сайт, статус и т.п
from bs4 import BeautifulSoup  # парсинг, собирать данные и многое другое
import csv  # таблица данных

# CSV, HOST, URL & pages
CSV = 'resources.csv'
HOST = "https://codeby.net/"
URL = "https://codeby.net/resources/categories/brending-codeby.11/"
pages = requests.get(URL)

# Словарь с данными
HEADERS = {

    "accept": "ext/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
    "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0"
}


def get_html(url, params=""):

    r = requests.get(url, headers=HEADERS, params=params)
    return r


def get_content():
    soup = BeautifulSoup(pages.text, 'html.parser')
    items = soup.find_all("div", class_="structItem")
    resources = []

# цикл: перебираем все данные ресурса включая:(Название ресурса, автор, дата создание)
    for item in items:
        resources.append(
            {

                "title": item.find("div", class_="structItem-title").get_text(),  # название ресурса
                "author": item.find("a", class_="username").get_text(),  # автор ресурса
                "time": item.find("time", class_="u-dt").get_text(),  # дата создание ресурса
                "desc": item.find("div", class_="structItem-resourceTagLine").get_text()  # описание ресурса
            }

        )

    return resources


# функция который сохраняет данные в CSV
def save_documents_csv(items, path):
    with open(path, "w", newline='') as file:
        writer = csv.writer(file, delimiter=";")
        writer.writerow(['Название ресурсов', "Автор ресурсов", "Дата создание ресурсов", "Описание"])

        for item in items:
            writer.writerow([item['title'], item["author"], item["time"], item["desc"]])


# Run
def parser():
    html = get_html(URL)
    if html.status_code == 200:
        resource = []
        resource.extend(get_content())
        save_documents_csv(resource, CSV)
    parser()


если посмотреть на пайчарме то ворнинги и т.п отстутствует:
Screenshot_20220614_182340.png


@f22 спасибо тебе)) обычно я не обращаю внимание на синтаксис PEP и этих ворнингов, мне главное чтобы код работал)) но теперь буду знать и как исправлять ворнингов)))

а и ещё, рекомендую пользоваться этой руководстве по PEP8
Про библиотеке fake_useragent я установил, вызываю его но получаю вот такой вот ошибку
Screenshot_20220614_183900.png

видимо внутрення ошибка
 
Последнее редактирование:
  • Нравится
Реакции: OldGuard и f22

f22

Codeby Team
Gold Team
05.05.2019
1 631
153
@f22 спасибо тебе)) обычно я не обращаю внимание на синтаксис PEP и этих ворнингов, мне главное чтобы код работал)) но теперь буду знать и как исправлять ворнингов)))
Пожалуйста)
Когда код выглядит опрятно, читать и воспринимать его гораздо проще)

видимо внутрення ошибка
Нет, дело не в ошибке.
Вы читайте документацию по модулю - вот же на главной странице:
1655222578265.png

Сначала нужно создать экземпляр класса UserAgent(), а потом уже получить у него нужное поле
Или получить поле сразу:
1655222639516.png


А вы зачем-то обновлять его полезли)
 
  • Нравится
Реакции: I3ody_World

I3ody_World

Green Team
11.06.2022
31
18
Пожалуйста)
Когда код выглядит опрятно, читать и воспринимать его гораздо проще)


Нет, дело не в ошибке.
Вы читайте документацию по модулю - вот же на главной странице:
Посмотреть вложение 60487
Сначала нужно создать экземпляр класса UserAgent(), а потом уже получить у него нужное поле
Или получить поле сразу:
Посмотреть вложение 60488

А вы зачем-то обновлять его полезли)
Ах, да емае почему я такой не внимательный, кстати если написать my_ua.firefox он выводит файрвокс юзер агента?
 

I3ody_World

Green Team
11.06.2022
31
18
Мб, сделаю парсер для просмотра ресурсов с приватных контент, хз, с моего акка надо кукисы впихать или же авторизацию сделать
 
Мы в соцсетях: