В этой статье я покажу как сделать свой парсер, который будет получать данные с сайта E-katalog.ru по ссылке из любой категории с листингом товаров — название товара, цену, заголовок страницы товара, урл и записывать данные в csv-файл. Скрипт на Python.
Статья написана в образовательных целях, чтобы быстро научиться программировать парсеры. Код сайта со временем изменится и скрипт не будет работать путём копипаста, нужно будет изменить XPath-выражения. Цель этого и всех других хау-ту статей на этом сайте состоит в том, чтобы вы понимали, как создать парсер и поддерживать его с течением времени по мере внесения изменений на исходный сайт.
Инструментарий: Python 3 + библиотеки
Я буду использовать Python 3 и некоторые распространенные библиотеки Python.
Вот данные, которые этот парсер поможет вам извлечь в csv-таблицу:
- Называние
- Цена
- Url
- Title
В парсер легко добавить любые данные с сайта, помимо уже существующих — урл картинок или сами картинки, описания, отзывы и т.д.
Я сохраню данные в виде электронной таблицы Excel (CSV), которая выглядит следующим образом:
Установка необходимых пакетов для парсинга E-katalog.ru
Буду использовать следующие библиотеки:
- requests
- csv
- time
- lxml
- fake_headers
Устанавливаю их с помощью pip3:
pip3 install requests, csv, time, lxml, fake_headers
Код проекта на Python
Весь код, используемый в этом проекте, доступен для загрузки с Github по адресу https://github.com/Megaduox/parser_ekatalog.ru
Первая функция get_links( ):
def get_links(page_url):
pagination_pages = set()
request = requests.get(page_url, headers=HEADERS)
tree = html.fromstring(request.content)
pages_count = tree.xpath('//div[@class="ib page-num"]//a[last()]/text()')
print('\nКод ответа корневого УРЛ:', request.status_code)
print('Всего страниц пейджинации:', pages_count)
for url in range(int(pages_count[0])):
full_url = f"https://www.e-katalog.ru/list/431/{url}/"
pagination_pages.add(full_url)
while len(pagination_pages) != 0:
current_url = pagination_pages.pop()
print('Сбор ссылок с URL:', current_url)
request = requests.get(current_url, headers=HEADERS)
tree = html.fromstring(request.content)
links = tree.xpath("//a[@class='model-short-title no-u']/@href")
for link in links:
QUEUE_URL.add(DOMAIN+link)
time.sleep(3)
Вот что она делает:
- функция get_links() принимает на вход url, берёт все ссылки с него на товары из листинга и проходит по всей пейдижнации
- Складывает ссылки с каждой страницы пейджинации в множество QUEUE_URL
Далее добавляю код:
def get_data(product_link):
product = dict()
request = requests.get(product_link, headers=HEADERS)
tree = html.fromstring(request.content)
product_name = tree.xpath("//h1/text()")
product_price = tree.xpath("//div[@class='desc-short-prices'][1]//"
"div[@class='desc-big-price ib']//span[1]/text()")
product['Url'] = product_link
product['Title'] = tree.findtext('.//title')
for name in product_name:
product['Name'] = name
for price in product_price:
product['Price'] = price
time.sleep(3)
print('Сбор данных с URL', product_link)
return product
Здесь функция get_data() принимает на вход один урл товара, парсит данные. Сами данные никуда не записывает, а возвращает список данных в виде словаря.
И в финале добавляю основную функцию main():
def main():
with open('data.csv', 'a', newline='') as csvfile:
fieldnames = ["Name", "Price", "Url", "Title"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames, quoting=csv.QUOTE_ALL)
writer.writeheader()
get_links(URL)
while len(QUEUE_URL) != 0:
current_url = QUEUE_URL.pop()
add_to_csv_from_file(get_data(current_url))
if __name__ == "__main__":
main()
Эта функция записывает получившиеся данные в файл csv, вызывая в своей работе get_links() для парсинга списка всех товаров и рекурсивно get_data() для парсинга конкретного урла.
Не забываем импортировать нужные библиотеки и объявить глобальные переменные:
# -*- coding: cp1251 -*-
import requests
import csv
import time
from lxml import html
from fake_headers import Headers
HEADERS = Headers(
browser="chrome",
os="win",
headers=True
).generate()
URL = 'https://www.e-katalog.ru/list/431/'
DOMAIN = 'https://www.e-katalog.ru'
ALL_DATA = dict()
QUEUE_URL = set()
Проблемы, с которыми вы можете столкнуться
- E-katalog.ru не особо защищается, можно спокойно парсить, но помните, что не надо перегружать сервер сайта и нужно делать задержку между запросами.
- Если товара нет в наличии на странице, то в csv-файле будет пустая ячейка, потому что меняется вёрстка.
- Если нужно парсить каждый день несколько тысяч товаров, то нужно работать через прокси-сервер.
Список выше только часть проблем, с которыми сталкиваешься при парсинге и у каждого сайта они могут быть индивидуальны, особенно, если проект крупный.
Эти и многие другие проблемы являются причиной того, что компании, которые специализируются на парсинге, такие как мы, работают лучше, чем скрипты, разработанные самостоятельно. Если же есть желание разобраться самостоятельно, вы можете взять за основу мой скрипт и использовать его для отслеживания цен с сайта e-katalog.ru.
Если вам нужна помощь в сложных проектах по парсингу и сбору данных, напишите, мы будем рады вам помочь.