«Ошибка парсинга XML документа»
Несколько дней назад (с 23,06,17) в сбербанк бизнес при загрузке электронного реестра выгруженного из 1С возникает подобная ошибка. Лечение: Редактором (например AkelPad), открываем сохраненный реестр, верхнюю строчку меняем на сохраняем в кодировке 1251 . загружаем в сбербанк, с указанием «кодировка=windows». Почему то после обновления исходный файл даже с указанием кодировки UTF система сбербанк не принимает. Возможно кому то пригодиться.
Дополнен 6 лет назад
Исходная строка? xml version=»1.0″ encoding=»UTF-8″? правильная строка? xml version=»1.0″ encoding=»windows-1251″?
Голосование за лучший ответ
Ну, дык, а нельзя в обработке выгрузки поменять кодировку,
чтобы каждый раз не лазить в файло?
Тем более, если этот вопрос задан в разделе „Программирование“, то люди, которые отвечают в этом разделе, сделают именно так!
Ну и в чём, собственно, состоял вопрос?
Или вы намеренно пошли на нарушение „Пользовательского Соглашения»?
Где написано:
„2.1. На Сайте существует три основных способа размещения Материалов:
«Вопрос» — сообщение Пользователя, размещенное с целью получения информации от других Пользователей, ограниченные рамками настоящего Соглашения.
«Ответ» — сообщение Пользователя, размещенное в ответ на «Вопрос», ограниченные рамками настоящего Соглашения.
«Комментарии» — отзывы Пользователей на размещенные на Сайте Материалы, а также ответы на эти отзывы. “
Применение эффективного асинхронного web-парсинга при работе с Big Data (библиотека Scrapy)
Привет, Хабр! Сегодня с вами Марина Коробова, участница профессионального сообщества NTA.
Многие компании и организации занимаются сбором большого объёма внешних данных для анализа и принятия эффективных решений. Конечно, всё это можно делать вручную, но это долгий, монотонный и нецелесообразный процесс, в котором можно допустить ошибки. В этом посте мы сравним два инструмента для автоматизации сбора данных из внешних источников Scrapy и BeautifulSoup4.
Введение
Парсинг или веб-скрапинг — это автоматизированный сбор и структурирование информации из открытых источников при помощи специальной программы, называемой парсером. Технически получить доступ к открытой информации можно с помощью API, но как правило доступ ограничен или требует вложения денежных средств.
Рассмотрим принцип работы парсинга. Данный процесс происходит в несколько этапов:
- Отправка HTTP-запроса на сервер.
- Поиск необходимых данных.
- Трансформация полученных данных.
При отправке HTTP-запроса на сервер у нас есть два варианта:
- отправить запрос и ждать, пока сервер даст ответ (синхронный запрос);
- отправить запрос и продолжить работу. Когда данные будут получены, программа вызовет функцию обработчик события (асинхронный запрос).
У каждой из представленных реализаций есть свои плюсы и минусы. Так, например, асинхронный запрос значительно увеличивает производительность кода, поскольку позволяет обрабатывать несколько запросов одновременно, но его довольно сложно реализовать. В свою очередь, синхронный запрос прост в разработке и отладке, но имеет низкую эффективность за счёт последовательной отправки HTTP-запросов.
Основные проблемы парсинга
Парсинг, как и любая технология, сталкивается с рядом проблем. Перечислим наиболее актуальные:
- блокировка доступа к данным: использование CAPTCHA, блокирование IP-адресов и другое;
- скорость выполнения: большой объём данных требует много ресурсов и времени;
- сложность обработки ошибок: ошибки соединения, ошибки синтаксиса и другие;
- работа с динамическим контентом: необходимо разрабатывать специальные инструменты для анализа сайтов, использующих технологии Ajax и Javascript.
Реализация парсера на основе Beautiful Soup. Обзор возможностей.
Beautiful Soup — это библиотека Python для извлечения данных из файлов форматов HTML и XML. Beautiful Soup (или BS4) использует DOM-модель (Document Object Model) для трансформации и извлечения данных.
Основными возможностями BS4 являются:
- поиск элементов на странице по тегу, классу, ID и другим атрибутам;
- извлечение текста и атрибутов элементов;
- навигация по дереву элементов страницы;
- манипуляции с HTML-кодом, такие как добавление, удаление или изменение элементов.
Для извлечения данных из HTML-кода необходимо использовать конструктор BeautifulSoup() , который принимает два аргумента: разметку (HTML-код) и анализатор (необходим для обработки HTML-кода). BS4 поддерживает различные библиотеки для синтаксического анализа, включая стандартные html.parser, а также более быстрые, такие как lxml и html5lib. В нашем случае будем использовать lxml. Также, для отправки запросов на сайт воспользуемся библиотекой requests.
Реализация кода на базе Beautiful Soup
Для начала установим и импортируем библиотеки.
# установка pip install beautifulsoup4 pip install requests pip install lxml # импорт from bs4 import BeautifulSoup import requests
Проиллюстрируем пример парсинга одной страницы многостраничного сайта www.banki.ru. Данную задачу можно разбить на два этапа:
- Выгрузка необходимых данных. В нашем случае мы используем отзывы на инвестиционные компании.
- Парсинг HTML-кода в удобный формат. В нашем случае будем сохранять информацию в файл с расширением .json.
# веб-сайт, который хотим спарсить url = 'https://www.banki.ru/investment/responses/list/' # определим главную страницу root = 'https://www.banki.ru' # GET()-запрос на сайт page = requests.get(url) # проверка подключения print(page.status_code) # получаем содержимое страницы content = page.text # создаем объект BeautifulSoup soup = BeautifulSoup(content, "lxml") # сохраняем все с тэгом 'article' и классом 'responses__item' # в них будет находится весь код отзыва, включая заголовок, оценку, текст и прочее allfd = soup.find_all('article', class_="responses__item")
В большинстве случаев объём текста отзыва не умещается полностью в отведенную для него область, поэтому нам необходимо перейти на страницу самого отзыва и получить полный текст с неё.
# воспользуемся циклом, чтобы получить все необходимые ссылки links = [] for href in allfd: links.append(href.find('a', href=True)['href'])
Пройдёмся по каждой ссылке в цикле и сохраним информацию о заголовке и тексте отзыва. На последнем этапе выгрузим полученную информацию в файл banks_one_page.json.
with open ('banks_one_page.json', 'a+', encoding="utf-8") as file: for link in links: result = requests.get(f'') if (page.status_code == 200): content = result.text soup = BeautifulSoup(content, 'lxml') fd = soup.find('div', class_='article-text response-page__text markup-inside-small markup-inside-small--bullet').get_text(strip=True, separator=' ') title = soup.find('h1').get_text(strip=True, separator=' ') json.dump(, file, ensure_ascii=False, indent=4)
Парсинг многостраничного сайта заключается в последовательном парсинге каждой страницы в цикле.
i = 1 page = requests.get(f'https://www.banki.ru/investment/responses/list?page=&isMobile=0') with open ('banks_all_pages.json', 'a+', encoding="utf-8") as file: while (page.status_code == 200): content = page.text soup = BeautifulSoup(content, "lxml") allfd = soup.find_all('article', class_="responses__item") links = [] for href in allfd: links.append(href.find('a', href=True)['href']) for link in links: result = requests.get(f'') if (page.status_code == 200): #time.sleep(1) content = result.text soup = BeautifulSoup(content, 'lxml') fd = soup.find('div', class_='article-text response-page__text markup-inside-small markup-inside-small--bullet').get_text(strip=True, separator=' ') title = soup.find('h1').get_text(strip=True, separator=' ') json.dump(, file, ensure_ascii=False, indent=4) i += 1 page = requests.get(f'https://www.banki.ru/investment/responses/list?page=&isMobile=0')
В результате мы получили файл с названием и текстом отзыва. В дальнейшем мы можем анализировать эту информацию, например, визуализировать наиболее часто встречающиеся слова в тексте.
Реализация парсера на основе Scrapy. Обзор возможностей.
Scrapy — это высокоуровневый Python-фреймворк для парсинга данных с веб-сайтов, построенный на базе асинхронной библиотеки Twisted.
Основными возможностями Scrapy являются:
- автоматическая обработка запросов и ответов с использованием асинхронности;
- извлечение данных из HTML и XML документов с помощью XPath и CSS-селекторов;
- эффективная обработка веб-форм и управление сессиями;
- расширяемость за счёт огромного количества плагинов, упрощающих разработку и настройку веб-пауков.
Реализация кода на базе Scrapy
Для начала необходимо установить библиотеки. Разработчики Scrapy настоятельно рекомендуют создать специальную виртуальную среду, чтобы избежать конфликта с системными пакетами – ситуации, когда один из пакетов не может работать при наличии другого. Создание изолированной виртуальной среды для проекта позволить исключить данную ситуацию.
Будем работать через терминал anaconda.
cconda install -c conda-forge scrapy
Создадим каталог, где находятся шаблоны, необходимые для управления проектом.
# banks_one_page — имя проекта scrapy startproject banks_one_page # перейдём в созданный каталог cd banks_one_page
Перед парсингом сайта необходимо пояснить, что же такое веб-паук.
Веб-паук — класс, определяющий алгоритм сканирования веб-страниц. Существует несколько типов веб-пауков:
- scrapy.Spider — веб-паук, предоставляющий базовую структуру и функциональность для создания других пауков;
- Generic Spiders — шаблоны веб-пауков, которые можно использовать для создания подклассов scrapy.Spider:
- CrawlSpider — веб-паук, использующий набор правил (rules), задаваемых пользователем, каждое из которых определяет поведение для сканирования сайта;
- XMLFeedSpiders — веб-паук, предназначенный для извлечения данных из XML-файлов;
- CSVFeedSpider — веб-паук, предназначенный для извлечения данных из CSV-файлов;
- SitemapSpider — веб-паук, предназначенный для извлечения данных из sitemap.xml файлов, в которых хранится информация о URL-адресах, доступных для сканирования.
Создадим нашего паука. Нам необходимо переходить по страницам, чтобы импортировать информацию о заголовке и тексте отзыва. Для этого воспользуемся шаблоном crawl.
# one_page — имя веб-паука # после конструкции -t указываем необходимый шаблон паука, в нашем случае crawl scrapy genspider -t crawl one_page www.banki.ru/investment/responses/list
Теперь в папке со всеми веб-пауками spiders, которая находится внутри проекта, должен быть создан новый скрипт с именем паука one_page, в котором записан шаблон для сканирования веб-сайта.
Далее запустим оболочку Scrapy для нашего сайта. Это необходимо для тестирования кода.
scrapy shell url = 'https://www.banki.ru/investment/responses/list?page=1&isMobile=0' r = scrapy.Request(url) fetch(r)
На этом этапе мы столкнулись с ошибкой HTTP 429 Too Many Requests. Чаще всего эта ошибка означает, что количество запросов к сайту достигло предела. Но в нашем случае мы отправили всего один запрос, поэтому, скорее всего, веб-сайт блокирует наши запросы, потому что не может нас идентифицировать.
В данном случае нам следует передать информацию о клиенте в User-Agent. В оболочке scrapy это можно сделать следующий образом.
r = scrapy.Request(url, headers=) # Был использован User-Agent моего браузера. При реализации кода вы должен использовать свой User-Agent. fetch(r) # получим html-текст страницы response.body
Мы получили код «200», что говорит об успешно выполненном запросе.
Если мы хотим получить конкретный элемент, необходимо воспользоваться xpath. В данном случае получим главный заголовок сайта.
Откроем скрипт one_page.py и пропишем работу паука. Перед этим необходимо настроить USER_AGENT в settings.py.
import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class OnePageSpider(CrawlSpider): # name – имя паука name = "one_page" # allowed_domains – домены сайта, в пределах которого необходимо сканировать allowed_domains = ["www.banki.ru"] # start_urls – список начальных адресов start_urls = ["https://www.banki.ru/investment/responses/list"] # rules - правила, определяющие поведение паука # первое правило: проваливаемся внутрь отзыва для того, чтобы достать заголовок и текст отзыва rules = (Rule(LinkExtractor(restrict_xpaths="//div[@class = 'responses__item__message']/a"), callback='parse_item', follow = True), ) def parse_item(self, response): item = <> item['title'] = response.xpath("//h1[contains(@class, 'response-page__title')]/text()").get().strip() item['review'] = response.xpath("//div[contains(@class, 'article-text')]/text()").get().strip() return item
Чтобы запустить ноутбук и импортировать полученные данные, необходимо с помощью терминала зайти в папку, где хранится наш паук, и запустить следующую функцию.
scrapy crawl one_page -o feedback_one_page.json
Произведём парсинг многостраничного сайта.
# all_pages — имя веб-паука scrapy genspider –t crawl all_pages www.banki.ru/investment/responses/list
Откроем скрипт all_pages.py и пропишем работу паука.
import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class AllPagesSpider(CrawlSpider): # name – имя паука name = "all_pages" # allowed_domains – домены сайта, в пределах которого необходимо сканировать allowed_domains = ["www.banki.ru"] # start_urls – список начальных адресов start_urls = ["https://www.banki.ru/investment/responses/list"] """ rules - правила, определяющие поведение паука первое правило: проваливаемся внутрь отзыва для того, чтобы достать заголовок и текст отзыва второе правило: переходим по страницам """ rules = (Rule(LinkExtractor(restrict_xpaths="//div[@class = 'responses__item__message']/a"), callback='parse_item', follow = True) ,Rule(LinkExtractor(restrict_xpaths="//li[@class='ui-pagination__item ui-pagination__next']/a")) ) def parse_item(self, response): item = <> item['title'] = response.xpath("//h1[contains(@class, 'response-page__title')]/text()").get().strip() item['review'] = response.xpath("//div[contains(@class, 'article-text')]").get().strip() return item
Чтобы запустить ноутбук и импортировать полученные данные, необходимо с помощью терминала зайти в папку, где хранится наш паук, и запустить следующую функцию.
scrapy crawl all_pages -o feedback_all_pages.json
В результате мы получили файл с названием и текстом отзыва, скрипт отработал значительно быстрее, чем BS4.
Краткие итоги
Сравнительная таблица работы BeautifulSoup и Scrapy:
BeautifulSoup
Scrapy
Выгрузка зарплатных реестров в Сбербанк в формате CSV
Сбербанк пользователей Сбербанк-Онлайн переводит по зарплатным проектам на выгрузку реестров в формате CSV. Кто-то уже выгружает в данном формате? У нас релиз (5.0.22.9) и там нет данного формата
Тема закрыта.
Наталья Иванова ГК КАМИН
Platinum Member3385
3461
12 фев 2015 11:48 #2
#2 от Наталья Иванова ГК КАМИНПришлите на Hotline@kamin.kaluga.ru требование банка по формату файла выгрузки, зарегистрируем предложение добавить данную возможность.
Иванова Наталья
Группа компаний КАМИН
Тема закрыта.
Миронов Владимир
Platinum Member960
700
12 фев 2015 12:02 #3
#3 от Миронов ВладимирФормат CSV нужен для загрузки непосредственно в реестр в меню зарплатный проект. Если выгрузить в xml и сделать импорт (Дополнительно — обмен с 1С — импорт — реестр), то точно также сформируется реестр. Останется только дозаполнить поля шапки и подвала.
PS. Точного названия меню и подменю не помню.Тема закрыта.
Муниципальное автономное учреждение дополнительного образования детско-юношеская спортивная школа «Авангард»
New Member
19
0
04 март 2015 14:27 #4
#4 от Муниципальное автономное учреждение дополнительного образования детско-юношеская спортивная школа «Авангард»
При выгрузке в сбербанк-онлайн из КАМИН 5.0 выдается ошибка: «Ошибка парсинга xml документа (строка: 4, столбец: 23)
Ошибка парсинга xml документа (строка: 5, столбец: 16)» Что это может быть?Сбербанк Онлайн не загружает электронный реестр с зарплатными ведомостями
СББОЛ не производит импорт нашей зарплатной ведомости, мотивируя тем, что файл имеет якобы недопустимый формат и сообщает :»ошибка парсинга xml документа (строка: 2 , столбец: 472). Кто нибудь сталкивался с такой проблемой?
Этот Сбербанк, который «Всегда рядом» (их девиз!), не может мне помочь своей техподдержкой (которой не дождаться, т.к. все операторы всегда заняты) с декабря прошлого года. И обидно каждый раз перед выплатой зарплаты вручную набирать в этом СББОЛе список сотрудников получателей — полностью ФИО и 20 значный лицевой счет каждого . ♀️
И это при том, что у них в СББОЛ есть все данные по нашим сотрудникам. Неужели нельзя оттуда вставлять реквизиты при заполнении ?!
ООО на УСНО.7 У меня такой же вопрос
Заполнить, проверить и подать уведомление о сумме налога
16+. Реклама. АО «ПФ «СКБ Контур». ОГРН 1026605606620. 620144, Екатеринбург, ул. Народной Воли, 19А.
г. Кириши 54 617 баллов
Цитата (бухгалтер УК): импорт нашей зарплатной ведомости
В какой программе формируете?
Цитата (бухгалтер УК): «ошибка парсинга xml документа (строка: 2 , столбец: 472).Возможно, это связано с версией установленного у вас Парсера.
ЗЫ: под парсингом подразумевается процесс поиска определенной информации в большом фрагменте текста, а так же разбиение данных на смысловые части.
бухгалтер УК Автор вопроса
Формируем в 1С Предприятие 8.3 (не в ЗУПе)г. Фрязино 24 684 балла
Цитата (бухгалтер УК): СББОЛ не производит импорт нашей зарплатной ведомости, мотивируя тем, что файл имеет якобы недопустимый формат и сообщает :»ошибка парсинга xml документа (строка: 2 , столбец: 472). Кто нибудь сталкивался с такой проблемой?
Этот Сбербанк, который «Всегда рядом» (их девиз!), не может мне помочь своей техподдержкой (которой не дождаться, т.к. все операторы всегда заняты) с декабря прошлого года. И обидно каждый раз перед выплатой зарплаты вручную набирать в этом СББОЛе список сотрудников получателей — полностью ФИО и 20 значный лицевой счет каждого .
И это при том, что у них в СББОЛ есть все данные по нашим сотрудникам. Неужели нельзя оттуда вставлять реквизиты при заполнении ?!
ООО на УСНО.Скорее всего вы загружаете правильный файл в неправильном месте. Еще раз внимательно прочитайте инструкцию.