Парсинг и аудит



    Начнем с идеи. Допустим, вы, как настоящий аудитор, хотите провести экспертизу отчетности заводчика собак, используя в том числе и сторонние ресурсы. Для этого вы пробуете получить систематизированную информацию о щенках заводчика, зная, к примеру, лишь название их пород, и составить из нее таблицу в Pandas, пригодную к дальнейшей обработке любого характера (всевозможные статистические изыскания, агрегация и так далее). Но ваши данные хранятся в глубине некоторого абстрактного вебсайта, откуда вы можете вынуть их в только виде архива, где сложены документы нескольких форматов, внутри которых есть текст, картинки, таблицы. А если пород щенков много, а на каждую из них есть по десятку pdf-файлов с таблицами, откуда вам нужна не вся информация, а также, например, нужны названия этих таблиц или сноски? Добавим в наш проект несколько функций, решающих следующие задачи: выгрузка и распаковка архива с данными, поиск и обработка pdf файлов из архива, анализ полученных данных.

    Для начала импортируем все необходимое. Разделим библиотеки, нужные нам, на системные:

    import os
    import re
    import glob
    import csv
    import shutil

    и внешние, требующие установки (pip install, как я и говорил):

    import requests as req
    import pandas as pd
    from zipfile import ZipFile
    import tabula
    import PyPDF2
    from pdf2image import convert_from_path
    from pytesseract import image_to_string
    from PIL import Image, ImageDraw

    Теперь для каждого вашего щеночка скачаем большой архив с данными, обратившись к сайту по названию его породы:

    def get_doquments_archive(breed):
                url = 'https://yourwebsite' + breed + '/document/download'
                  with req.get(url, stream=True) as r:
                    r.raise_for_status()
                    with open('/Users/user/Desktop/' + breed + '.zip', 'wb') as f:
                             for chunk in r.iter_content(chunk_size=8192):
                                       f.write(chunk)

    Теперь у нас есть архив на рабочем столе. Распакуем его, для этого нам понадобится знать всего лишь путь к файлу с архивом:

    def unzipper(zippath, cond = False):
     dirpath = zippath[:-4] + '_package'
     if os.path.exists(dirpath) and os.path.isdir(dirpath):
    shutil.rmtree(dirpath)
    os.mkdir(dirpath)
    with ZipFile(zippath, 'r') as zipObj:
    zipObj.extractall(path = dirpath)

    На этом шаге мы получим папку с документами, где могут быть pdf, csv, xls, png и другие приятные штуки. Допустим, мы желаем обработать несколько pdf файлов, содержащих таблицы с данными. Но как их оттуда вынуть? Для начала выделим из папки документы нужного нам формата:

    all_pdfs = glob.glob(dirpath + '/*_pd*.pdf')

    Отлично. Теперь у нас есть набор файлов, внутри которых есть текст и таблицы. При попытке вынуть оттуда информацию может оказаться, что такую смесь инструменты распознают очень криво, особенно если таблицы склеены друг с другом, а их заголовки или сноски – отдельно стоящий текст. На помощь приходит tabula! Но для начала вынем из первой страницы каждого документа немного текстового описания, не входящего в таблицу (такой текст для tabula может быть проблемой). Поскольку на первой странице также может быть таблица, воспользуемся фокусом:

    def get_text_description(path):
    pdfFileObj = open(path,'rb')
    pdfReader = PyPDF2.PdfFileReader(pdfFileObj)
    pages = convert_from_path(declar, 0)
    page = pages[0]
    pname = '/Users/user/Desktop/text_description.png'
    page.save(pname, 'JPEG')
    text = image_to_string(Image.open('/Users/user/Desktop/text_description.png'),
                                              lang = 'rus')
    text_file = open('res', "w")
    text_file.write(text)
    text_file.close()

    Теперь начнем работать с таблицей. Если повезет, и таблица в нашем pdf вполне читемая, tabula корректно выгрузит ее в формате csv, таким образом, информацию даже не придется парсить:

    tabula.convert_into(file, 'output_file.csv', output_format = "csv", pages = 'all')

    Посмотрите, как теперь может быть просто получить, например, данные о характере выбранного щенка:

    data = pd.read_csv('/Users/user/Desktop/output_file.csv')
    temperament = data[data['Порода'] == 'Цвергшнауцер']['Характер']

    Но если автор текста склеил таблицы между собой, добавил в строки разное количество столбцов или перемешал их с текстом? Тогда мы приведем полученный от tabula файл в новый формат:

    def get_table_data(path):
     data = []
     with open(path) as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
    for val in row.values():
    data.append(val)
    data = str(data)
    data = re.sub('\]|\[|,|\'', '', data)
    data = data.replace("\\n", "")
    return data

    Для чего? Это позволит искать нужную информацию быстро и безболезненно с помощью регулярных выражений. Хотим найти набор возможных цветов породы:

    def get_colors(data):
     res = re.search('^Цвета: (.*)', data).group(1)
     return res

    Теперь мы накопили некоторое количество информации из файлов по одному щенку (допустим, характер, цвета, масса). Добавим ее в pandas dataframe как новую строку:

    def append_new_row(dataframe, breed, temperament, colors, weight):
      return dataframe.append({'Порода': breed,
    'Характер': temperament,
    'Цвета': colors,
    'Масса' : weight
    }, ignore_index=True)

    Что мы теперь имеем:



    Итак, мы выгрузили с сайта архив с данными, распаковали его, вынули нужные нам документы, достали из них важную информацию и привели ее к удобному формату. Теперь эти данные можно сравнивать с предоставляемыми компанией, преобразовывать и анализировать, а также многое другое! Гораздо удобнее, чем качать и выписывать вручную.

    def clean_all(path):
    os.remove(path + '.zip')
    shutil.rmtree(path + '_package')

    Важно, чтобы ваши действия оставались полностью законными. Забирать данные с сайтов можно, красть контент нельзя. Качать автоматически можно, класть сервер нельзя. Изучайте авторские права и УК РФ, не наносите ущерб.

    Средняя зарплата в IT

    111 380 ₽/мес.
    Средняя зарплата по всем IT-специализациям на основании 7 299 анкет, за 2-ое пол. 2020 года Узнать свою зарплату
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 1

      0
      Из пушки по воробьям?

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое