Парсинг Сервис

Что такое парсер сайтов на примере.

Начал изучение языка программирования Python, как мне кажется перспективный язык и больше всего подкупила простота кода и визуальная красота. Не буду вдаваться в детали языка, каждый желающий может найти много статей по синтаксису, приведу сам код парсера. Данный скрипт опубликован только в целях изучения языка Python. Приведу также ссылку на видеоуроки , код был взят оттуда и переработан под сайт krisha.kz
ссылка на файл с кодом
import requests
from bs4 import BeautifulSoup
from time import sleep
from selenium import webdriver
import csv
#функция для получения html
def get_html(url):
r = requests.get(url)
return r.text
#функция подсчета количества страниц
#используем библиотеку BeautifulSoup для поиска html тегов на странице
#
def get_total_pages(html):
soup = BeautifulSoup(html, 'lxml') # определяем объект soup
try:
divs = soup.find('nav', class_='paginator-public') # находим на странице первый объект nav с именем класса paginator-public
pages = divs.find_all('a', class_='paginator-page-btn')[-2].get('href') # находим на странице все теги ""a"" с именем класса paginator-page-btn, из них выбираем элемент с индексом [-2] это будет последняя страница
total_pages = pages.split('=')[1].split('&')[0] # из полученной ссылки делаем сплит и выбираем значение между знаком ""="" и ""&""
return int(total_pages) #возвращаем полученное значение
except:
return 2
#функция для записи csv файла
def write_csv(data):
with open('krisha.csv', 'a', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow((data['title'],
data['price'],
data['etaj'],
data['square'],
data['address'],
data['description'],
data['url'],
data['telephone']))
#функция для получения телефонов
#так как на сайте скрыты телефоны, необходимо использовать дополнительный пакет selenium
#для имитации нажатия на ссылку с телефоном, для этого запускается браузер chrome в режиме
#""headless"" т.е. без отображения окна
def get_phone(url):
options = webdriver.ChromeOptions()
options.add_argument('headless')
options.add_argument('window-size=1200x600')
#driver = webdriver.Chrome('C:\\python37\\chromedriver_win32\\chromedriver.exe') # or Firefox() or smth else
driver = webdriver.Chrome(options=options) # определяем объект типа webdriver
driver.get(url) # передаем ему на вход url
link = driver.find_element_by_id('tm-telephone-body') # переменной link присваиваем ссылку, которая нам покажет телефон
link.click() # кликаем на ссылку
sleep(1) # делаем паузу в 1 секунду
tel = driver.find_element_by_class_name('offer__contacts-phones').text.strip() # присваиваем переменной tel показанные номера телефонов
driver.quit() # не забываем закрывать невидимый браузер
return tel # возвращаем телефон
# функция получения данных с сайта, используем библиотеку BeautifulSoup, она позволяет выполнять поиск по html тегам
#
def get_page_data(html):
soup = BeautifulSoup(html, 'lxml') # определяем объект soup
divs = soup.find('section', class_='a-list') # находим тег section с именем класса a-list
ads = divs.find_all('div', class_='a-card__inc') # в найденном объекте ищем все div с классом a-card__inc
# запускаем цикл по всем найденным полям, которые нас интересуют
# т.к. ссылка состоит 3-комнатная квартира, 79.4 м², 5/5 эт. я решил ее разделить на поля квартира, площадь, этаж
# далее выбираем цену, адрес и описание
#
for ad in ads:
try:
div = ad.find('a', class_='a-card__title').text
kv = div.split("","")[0]
except:
kv = ''
try:
div = ad.find('a', class_='a-card__title').text
square = div.split("","")[1]
except:
square = ''
try:
div = ad.find('a', class_='a-card__title').text
etaj = div.split("","")[2]
except:
etaj = ''
try:
price = ad.find('div', class_='a-card__price').text.strip()
except:
price = ''
try:
address = ad.find('div', class_='a-card__subtitle').text.strip()
except:
address = ''
try:
descr = ad.find('div', class_='a-card__text-preview').text.strip()
except:
descr = ''
try:
div = ad.find('div', class_='a-card__header-left')
url = ""krisha.kz"" + div.find('a').get('href')
#tel = ''
except:
url = ''
#tel = ''
tel1 = get_phone(url) # тут вызываем функцию выборки телефонов
# определяем кортеж из наших полей и передаем его функции write_csv
data = {'title':kv,
'price':price,
'etaj':etaj,
'square':square,
'address':address,
'description':descr,
'url':url,
'telephone':tel1}
write_csv(data)
# основная функция
# базовый url для Астаны имеет вид krisha.kz/prodazha/kvartiry/astana/
# к нему добавляется запрос query_part и еще дальше идет блок со страницами page_part
#
def main():
#url = 'krisha.kz/prodazha/kvartiry/astana/?das[live.rooms]=1'
base_url = 'krisha.kz/prodazha/kvartiry/astana/'
page_part = '&page='
query_part = '?das[live.rooms]=1'
total_pages = get_total_pages(get_html(url))
#
for i in range(1, total_pages):
url_gen = base_url + query_part + page_part + str(i)
html = get_html(url_gen)
get_page_data(html)
# html = get_html('krisha.kz/prodazha/kvartiry/astana/?das[live.rooms]=1')
# get_page_data(html)
#блок main
if __name__ == '__main__':
main()
полученный в результате работы скрипта csv выглядит так, здесь я намерено убрал часть телефонных номеров:
1-комнатная квартира,16 500 000 ₸, 19/21 эт., 70 м²,""р-н Байконур, Кенесары"",""монолитный дом, 2014 г.п., состояние: хорошее, санузел раздельный, частично меблирована, Все необходимое рядом: магазины, супермаркеты, аптеки, школы и дошкольные учреждения, остановки общественного транспорта. Район с хорошей инфраструктурой. В квартире очень приятный микроклимат. Вкладывая де…"",krisha.kz/a/show/48283479,+7 ... 8924
1-комнатная квартира,12 750 000 ₸, 6/10 эт., 43 м²,""Алматинский р-н, Переулок Сартау 16"",""жил. комплекс Сарытау, монолитный дом, 2016 г.п., состояние: евроремонт, потолки 2.7м., санузел совмещенный, телефон: есть возможность подключения, интернет оптика, частично меблирована, ЖК «Сарытау» состоит из одного 10-этажного дома, выполненного по оригинальному проекту, и расположен в тих…"",krisha.kz/a/show/47455009,+7 ... 3397
1-комнатная квартира,11 800 000 ₸, 11/16 эт., 46 м²,""р-н Байконур, Бейсекбаева"",""жил. комплекс Гранитный, монолитный дом, 2014 г.п., состояние: евроремонт, потолки 3м., санузел совмещенный, частично меблирована, Продается 1-комнатная квартира в ЖК """"Гранитный"""" по ул. Бейсекбаева, Иманова с ремонтом! Район БТИ. Удобная транспортная развязка. Квартира теплая, уютная. Продажа…"",krisha.kz/a/show/47783199,""+7 ... 3377
+7 ... 9696""
1-комнатная квартира,7 800 000 ₸, 13/13 эт., 23.6 м²,""Алматинский р-н, Сатпаева 20а — Момышулы"",""жил. комплекс 12 месяцев, 2018 г.п., состояние: евроремонт, жил. площадь 15 кв.м., кухня 5 кв.м., санузел совмещенный, Продам 1 комн-студию по Сатпаева-Момышулы напротив Ресторана Туран, 5минут до Байтерек. Квартира абсолютно новая, новый евроремонт качественно делали для себя, сантехника вся н…"",krisha.kz/a/show/47352917,""+7 ... 1805
+7 ... 9123""
1-комнатная квартира,20 500 000 ₸, 4/8 эт., 50.6 м²,""Есильский р-н, Алихана Бокейханова — проспект Мангилик Ел"",""жил. комплекс Vivat Promenade, монолитный дом, 2018 г.п., состояние: евроремонт, потолки 3м., санузел совмещенный, телефон: отдельный, частично меблирована, Продается одна комнатная квартира в новом доме 2018 года. Жилой комплекс «Vivat Promenade» находится возле международного выставочн…"",krisha.kz/a/show/48169299,""+7 ... 3377
+7 ... 9696""
1-комнатная квартира,12 500 000 ₸, 12 эт., 42 м²,""Есильский р-н, Чингиза Айтматова 36/8 — Кайыма Мухамедханова"",""жил. комплекс Памир, монолитный дом, 2018 г.п., состояние: евроремонт, санузел раздельный, телефон: есть возможность подключения, интернет через TV кабель, пустая, Жилой комплекс Памир новостройка на левобережье Астаны, южнее Кургальджинского шоссе, на левом берегу р. Ишим, за ТРЦ «Хан Шаты…"",krisha.kz/a/show/46923223,+7 ... 3840