Парсинг Avito.ru при помощи Python 3

Поділитися
Вставка
  • Опубліковано 22 вер 2024
  • Мои курсы:
    Boosty:
    boosty.to/omol...
    Patreon:
    / karty-vsekh-41011404
    Парсим сайт Avito.ru при помощи библиотек языка Python 3 - requests и BeautifulSoup, а результат сохраняем в csv файл
    ⭐ "Практический курс парсинга сайтов на Python" ⭐
    Лендинг курса:
    zaemiel.github...
    О курсе и карта курса:
    / 30462246
    Видео о курсе:
    • Практический курс парс...
    ** ИСХОДНЫЙ КОД **
    Основных проектов доступен в Patreon:
    / iskhodnyi-kod-26640469
    ***
    Поддержите канал:
    🔷 Для донатов. Всегда очень признателен за это:
    www.donational...

КОМЕНТАРІ • 305

  • @РаульДюк-й9и
    @РаульДюк-й9и 5 років тому +2

    Под всеми видео Олега сначала можно ставить лайк, а потом смотреть. Ошибиться невозможно.
    Спасибо! Ваши уроки -просто находка.

  • @ИванИванов-л9ы3к
    @ИванИванов-л9ы3к 7 років тому +34

    Данное видео крутое дополнение к книге Р.Митчелл "Скрапинг веб-сайтов с помощью Python". Там много теории, здесь очень понятно разжеванная практика.

    • @201086z
      @201086z 6 років тому +1

      Практика круче теории. Теории вагоны, но вот чтобы всё было разжёвано на практике - это поискать надо.

    • @artemdeveloper7304
      @artemdeveloper7304 4 роки тому +1

      Спасибо за наводку. Книгу скачал.

  • @ДмитрийБорисюк-з6м
    @ДмитрийБорисюк-з6м 7 років тому +6

    Отлично, просто шикарно рассказано лучшее мне еще пока не встречалось. С меня подписка и лайки !!!

  • @letsgooooo
    @letsgooooo 5 років тому +21

    5:54 сформировать список уродо... :-D
    Спасибо за видео, шикарный туториал!

  • @dizelvinable
    @dizelvinable 7 років тому +2

    Очень хорошо объясняете! Даже я - начинающий программист Python - и то всё понял. Спасибо большое! Очень ценная информация!

  • @flashmf1
    @flashmf1 3 роки тому +2

    Спасибо за урок.
    Актуально и в 2021 году.
    На сайте изменилась структура xml, но это даже к лучшему. На ходу приходится смотреть и переписывать значения методов find и тд. + регулярки использовать для опыта.
    Далее на сайте у них еще фаервол. Пришлось time и random использовать для задержки при обходе страничек.

    • @kbchertila
      @kbchertila 3 роки тому

      Привет, можешь мне код скинуть?? не могу разобраться в find_all

  • @АлександрРычков-т4л
    @АлександрРычков-т4л 7 років тому +1

    самый толковый урок из всех! спасибо автору!!!

  • @КатеринаД-г5х
    @КатеринаД-г5х 7 років тому +5

    СПАСИБО ВАМ
    ОГРОМНОЕ ВАМ СПАСИБО
    ПРОСТО ОГРОМЕННОЕ ВАМ СПАСИБИЩЕ

  • @triders
    @triders 4 роки тому +1

    Спасибо за видео, все понятно и с комментариями!

  • @ДиванныйЭксперд
    @ДиванныйЭксперд 5 років тому

    Вот смотришь, все так легко! Красиво! Просто! ) Спасибо за видео!

  • @sergaik88
    @sergaik88 6 років тому

    Отличная подача материала. Автор молодец. Лайк. подписка.

  • @СергейКурилов-з9г
    @СергейКурилов-з9г 5 років тому +1

    Хорошее видео, заставляет не только тупо повторять, но и исследовать библиотеки и сайт для парсинга :)

  • @switprogress
    @switprogress 4 роки тому +1

    Спасибо! У меня почему-то в один столбец сохраняет, попробую разобраться. Видео просто супер!

  • @respecktpro2954
    @respecktpro2954 4 роки тому

    Как всегда годнота.Огромное спасибо за контент!

  • @sainco3036
    @sainco3036 7 років тому +15

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

  • @raytorres9052
    @raytorres9052 7 років тому +4

    огромное спасибо за подробный показ пакетов Request ( кстати уже не нашел под этим именем) и Python.
    буду ждать ещё видео на Python

    • @zaemiel
      @zaemiel  7 років тому +1

      Спасибо.
      Библиотека называете requests
      там 's' на конце

    • @raytorres9052
      @raytorres9052 7 років тому

      К сожалению при поиске в 2017 году только Request. (( может в github создателей есть ResquestS ?)

    • @zaemiel
      @zaemiel  7 років тому +2

      docs.python-requests.org/en/master/
      в гугле по запросу python requests - первая ссылка
      6.04.2017

    • @jonik_doit4463
      @jonik_doit4463 7 років тому

      Добрый вечер. Что нужно делать если при выяснении количества страниц отсутствует class:
      pages = soup.find('div', class_ = 'pager').find_all('a', class_ = 'КЛАСС НЕТ?')[-1].get('href')
      Спасибо!

    • @zaemiel
      @zaemiel  7 років тому +1

      у ссылок часто не бывает классов. Класс не обязательно указывать.
      .find_all('a')

  • @dmitrypobedinski2255
    @dmitrypobedinski2255 4 роки тому

    однозначно лайк! урок божественный!

  • @cattiew_
    @cattiew_ 5 років тому

    Спасибо за видео, очень помогло! Все очень ясно и понятно объяснено

  • @koboshon
    @koboshon 4 роки тому

    Большое спасибо за видео!

  • @aleksandr3094
    @aleksandr3094 6 років тому +22

    "Тут тоже два тэга p, только один пустой... сука..."
    Цитаты великих людей

    • @zaemiel
      @zaemiel  6 років тому +1

      что-то не припомню, чтобы я такое говорил

    • @aleksandr3094
      @aleksandr3094 6 років тому

      ну пересмотри

    • @a.panfilov.s
      @a.panfilov.s 5 років тому +9

      @@aleksandr3094 он сказал ссылка)Но мне тоже это послышалось..XD

    • @MrNovenkij
      @MrNovenkij 5 років тому

      @@a.panfilov.s +1

  • @АртемСудоргин-ц4ж
    @АртемСудоргин-ц4ж 4 роки тому

    Спасибо. Разложил по полочкам!

  • @13danyocean13
    @13danyocean13 5 років тому

    Good Stuff)) Раньше всю обработку форм через js делал, этот способ для таких задач явно лучше. Спасибо.

  • @ПетрАнисимов-ж6ж
    @ПетрАнисимов-ж6ж 4 роки тому

    Огромное спасибо Автору видео!! Очень круто. Единственное конечно сам Авито уже помеянлся, но в целом не сложно подстроить код

  • @a.panfilov.s
    @a.panfilov.s 5 років тому

    Спасибо, Олег!

  • @BabaykaMoscow
    @BabaykaMoscow 7 років тому +33

    for i in range(1, total_pages + 1)

    • @zaemiel
      @zaemiel  7 років тому +4

      да, забыл об этом, а потом было уже поздно.

    • @BabaykaMoscow
      @BabaykaMoscow 7 років тому +1

      Олег Молчанов Хороший урок. спасибо! :)

    • @abyrvalg809
      @abyrvalg809 5 років тому +1

      for i in range(1, get_total_pages(base_url_with_query_string) + 1)

  • @e001as_def
    @e001as_def 5 років тому

    Спасибо за видео

  • @viktorkroft
    @viktorkroft 5 років тому

    Спасибо, очень хороший видос и подача

  • @daddy_eddy
    @daddy_eddy 2 роки тому +2

    Спасибо.
    Видео можно удалять и переделывать, т.к. нет на Авито больше ссылок в пагинации. Попробуй теперь решить такую задачу...очень интересно.

  • @remvord
    @remvord 7 років тому

    спасибо за труд )

  • @apollon0326
    @apollon0326 5 років тому +1

    Я смог, значит видео отличное!

  • @АлександрОстапченко-м4в

    Шикарно, мужик ты крут!!!☺

  • @bahrammaraimov9760
    @bahrammaraimov9760 4 роки тому

    Спасибо большое from KG

  • @vladimirmuratov2220
    @vladimirmuratov2220 4 роки тому +1

    Олег, доброго Вам дня!!! Большое спасибо за Ваши видео, очень помогают, многое узнал. Вопрос: Вы со Scrapy дружите? Если да - то если у Вас будет время и желание... Заранее благодарен. С уважением, Владимир

  • @prosto_komputer
    @prosto_komputer 6 років тому

    Спсибо автору

  • @ОлегКосарев-ю1ы
    @ОлегКосарев-ю1ы 3 роки тому +1

    14:56 проще же
    from furl import furl
    f = furl("/abc?def=ghi")
    print f.args['def']

  • @alexander5597
    @alexander5597 7 років тому

    Спасибо!

  • @РемонтКрупнойБытовойТехникивВо

    Здравствуйте увидел у вас комментарий по поводу ремонтов кофемашин крупс подскажите как с вами связаться уточнить некоторые детали

  • @АндрейХлыбов-н5т
    @АндрейХлыбов-н5т 4 роки тому

    Круть!

  • @Dmitrycheburirtrie
    @Dmitrycheburirtrie 5 років тому

    снимаю шляпу, все очень просто и понятно однозначно лайк

  • @ДиДи-е6б
    @ДиДи-е6б 7 років тому

    Отличный урок. Но пора идти дальше. Вот бы видео о том, какие заголовки возвращают сайты, чтобы идентифицировать клиента. Замена прокси и user-agent не помогают.

  • @user_alex_
    @user_alex_ 10 місяців тому

    👍👍👍👍👍👍👍👍👍👍👍

  • @godlux9272
    @godlux9272 5 років тому +1

    Тут тоже 2 тега только один пустой.... :D

  • @Sergey-cz7ym
    @Sergey-cz7ym Рік тому

    11:53, мне кажется вместо class_='pagination-pages' удобнее использовать {'class': 'pagination-pages'}

    • @zaemiel
      @zaemiel  Рік тому

      дело личного предвочтения

  • @ivan_fvckoff
    @ivan_fvckoff 5 років тому +3

    Забыли сказать, что сначала sudo pip3 install BeautifulSoup4
    Далее 12:30 soup = BeautifulSoup(r.text, 'lxml') вызывает ошибку bs4.FeatureNotFound: тоже надо
    sudo pip3 install lxml
    Для новичков это неразрешимая проблема, а вы кажется про это явно не сказали. И хорошо бы выложить ссылку на гитхаб с текстом урока для ленивых.
    В конце возникла ошибка: in get_total_pages
    pages = soup.find('div', class_='pagination-pages').find_all('a', class_='pagination-page')[-1].get('href')
    AttributeError: 'NoneType' object has no attribute 'find_all'
    Что делать? У вас такой ошибки не возникло, но я много раз проверил код, кажется не ошибся нигде...

  • @28strelok
    @28strelok 4 роки тому

    А у вас есть урок по парсенгу сайтов где данные подгружаются через POST запросы

  • @plus_stick
    @plus_stick 6 років тому +1

    А я начинаю парсить, заранее не зная количества страниц. В каждой итерации цикла проверяю, есть ли ссылка на следующую страницу, если нет, то это последняя. Удобно, когда имеешь дело с разными сайтами объявлений, где разметка разная.

    • @zaemiel
      @zaemiel  6 років тому

      Да, эта схема удобнее.

    • @doniyordjon
      @doniyordjon 2 роки тому

      Случайно нет ли кода? В какой итерации, как дать условия не понимаю

  • @wigust9327
    @wigust9327 7 років тому +9

    Привет. Класс, спасибо. Можешь скрипт куда-нибудь залить?

    • @ilyin_sergey
      @ilyin_sergey 5 років тому

      github.com/israelcode/avito.ru-parser/blob/master/auto/avito-auto.py
      вот человек повторил слово в слово

  • @Sergey-cz7ym
    @Sergey-cz7ym Рік тому

    15:25 мне кажет проще было бы просто взять текст ссылки, он бы вернул количество страниц

    • @zaemiel
      @zaemiel  Рік тому

      тоже вариант

  • @алексейконовалов-е4к

    в конце видео про то как вытащить телефон... очень нада... есть такой урок? в моем случае - так надо даже не картинку вытащить, а просто ссылку , но получается заходя в каждую карточку отдельно, подскажите ссылочку на урок или киньте кусочек кода, буду оч рад, 2 дня уже пытаюсь сделать

  • @МихаилНосаев-и2ю
    @МихаилНосаев-и2ю 4 роки тому

    Респектую!!! Avito все поменял, но методом подбора получилось. writer = csv.writer(f, delimiter=';') для разделения по столбцам, огонь. Как запускать через REPL? Это же можно на Атом поставить?

  • @videocaptain6431
    @videocaptain6431 5 років тому

    Дружище помоги разобраться ) на 12.00 минуте импортирую from bs4 import BeautifulSoup, выдает ошибку Traceback (most recent call last):File "", line 1, in и дальше список файлов. Последняя строка с ошибкой ImportError: cannot import name 'HTMLParseError' from 'html.parser' и путь к файлу

  • @СергейКиреев-ж5я
    @СергейКиреев-ж5я 5 років тому

    люблю ваши уроки очень жду полноценного курса по python. У меня есть вопрос:
    если заказчик заказал скрипт но у заказчика не установлен python и другие библиотеки и он не знает как установить как дальнейшие действия исполнителя ...

    • @zaemiel
      @zaemiel  5 років тому

      вы должны будете написать ему инструкцию - как и что делать и куда тыкать.
      Это если ему скрипт нужен, чаще всего нужны именно данные

  • @yurikfirst
    @yurikfirst 4 роки тому

    Здравствуйте, Олег! Спасибо вам за ваши уроки! Но как быть, если надо скачать картинки и сохранить их в соответствующую папку, путь к которой будет указан в колонке images, в файла csv ? Спасибо, буду благодарен!

  • @РусланКунафин-б4д
    @РусланКунафин-б4д 4 роки тому

    Подскажите, почему у меня через раз ошибка получается: AttributeError: 'NoneType' object has no attribute 'find_all' в функции get_total_pages при определении количества страниц? Кто-то с этим сталкивался?

  • @koljasha_nafman
    @koljasha_nafman 6 років тому

    Спасибо за отличные уроки. Просто великолепны. Есть вопрос - Почему выбираешь парсер "lxml"?

    • @zaemiel
      @zaemiel  6 років тому

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

    • @koljasha_nafman
      @koljasha_nafman 6 років тому

      спасибо за ответ. Почему такой вопрос возник. Посмотрев твои уроки, решил потренировать на сайтах которые использую. На одном торренте столкнулся, что lxml после какого-то тега выдает абракадабру, а вот встроенный html.parser отработал корректно. Еще раз спасибо за уроки и полезный канал.

  • @etiaxil1293
    @etiaxil1293 3 роки тому

    Здравствуйте, подскажите а если мне постоянно раз в неделю нужно в определенной ниши парсить новые объявления и делать рассылку по вновь размещенным а не заново по всей базе, подскажите как быть?

  • @dmax_
    @dmax_ 5 років тому

    начал парсить один сайт, начинаю цикл thigs=... print(things) for thing in things: print(thing) когда я их просматриваю - то получается один и тот же html код. в чем может быть причина?

  • @blackwarrior6015
    @blackwarrior6015 4 роки тому +1

    есть у кого исходник?

  • @dmitrykhomyakov8451
    @dmitrykhomyakov8451 5 років тому +1

    Отличное видео!
    Подскажите почему при попытке записи в файл csv всего листа data выдает ошибку, а когда указываешь записывать только data['title'] , то записывает все символы через запятую? Код совпадает с кодом автора.

    • @СергейКурилов-з9г
      @СергейКурилов-з9г 5 років тому +2

      Там ошибка при работе с price из-за значка рубля (когда снималось видео на avito его не было). Попробуй заменить строчку price на это:
      price = ad.find('div', class_='about').find('span', class_='price').findAll(text = True)[0].strip()
      У меня работает :)

    • @evgenyplyusnin4633
      @evgenyplyusnin4633 5 років тому

      @@СергейКурилов-з9г Спасибо, очень помог. Были подозрения, что это именно из-за символа

    • @evgenyplyusnin4633
      @evgenyplyusnin4633 5 років тому +1

      @@СергейКурилов-з9г я только до такого сократил её
      price = ad.find('span', class_='price').text.strip().split(' ₽')[0]

  • @Tribunall
    @Tribunall 7 років тому

    Зачем проверять результат в консоле, а не в Sublime, теряется ведь время на те же самые операции?
    И почему не используешь какую то специализированую IDE под python?

  • @hotjupiter
    @hotjupiter 3 роки тому

    скажите, а что делать если сайт прогружается не сразу а постепенно во время прокручивания страницы?

  • @alexanderpadalka5708
    @alexanderpadalka5708 3 роки тому

  • @sergijtolmeros
    @sergijtolmeros 6 років тому

    Лучше urllib.parse.parse_qs urllib.parse.parse_qsl для разбора параметров в URL используйте. Вдруг сайт немного поменяется, или ещё что-то, и нужный параметр уйдёт на другую позици.

    • @zaemiel
      @zaemiel  6 років тому

      порядок передачи параметров не имеет значения

  • @tihon4979
    @tihon4979 5 років тому +1

    Почему не делать сразу как надо? Таким парсером словишь бан по IP! Нужно добавлять headers.

    • @DontMansion
      @DontMansion 5 років тому

      как это сделать

  • @andriitretynko1530
    @andriitretynko1530 7 років тому +1

    Спасибо за видео! У меня возникла проблема: данные записываются через строку, не подскажете как исправить?

    • @РишатФайзуллин-ц3х
      @РишатФайзуллин-ц3х 4 роки тому +1

      Тем, у кто ищет ответ на данный вопрос.
      Пропишите в строчку:
      with open("avito.csv", "a") as f
      параметр newline="" внутри скобок.
      Должно получиться так:
      with open("avito.csv", "a", newline="") as f

  • @СергейПономарев-ф7с

    Вот данные что получил:
    {'title': 'Телефон HTC', 'price': '750 ₽', 'metro': 'Выхино', 'url': 'avito.ru/moskva/telefony/telefon_htc_1948659152'}
    {'title': 'HTC One E9s dual sim(16Gb)', 'price': '4 000 ₽', 'metro': 'Домодедовская', 'url': 'avito.ru/moskva/telefony/htc_one_e9s_dual_sim16gb_1925935026'}
    {'title': 'HTC Sensation XE', 'price': '2 000 ₽', 'metro': 'Новогиреево', 'url': 'avito.ru/moskva/telefony/htc_sensation_xe_1607588962'}
    Дает ошибку:
    File "C:\Users\Администратор\AppData\Local\Programs\Python\Python38\lib\encodings\cp1251.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
    UnicodeEncodeError: 'charmap' codec can't encode character '\u20bd' in position 17: character maps to
    оказалось, что это при записи "data['price']". не дает записать значения с "₽"
    убирать из записи или есть другие варианты?

  • @ВладимирЗадорожный-е2у

    Осмеюсь ещё раз потревожить. При вызове в консоли:
    r = requests.get(url)
    и далее
    r.text
    в ответе содержатся только теги, без текста.
    В инспекторе кода Хрома, текст присутствует!

    • @zaemiel
      @zaemiel  5 років тому

      допускаю, что текст подгружается в эти теги через ajax.
      Смотрите в Инспекторе вкладку Сеть - XHR. Какое содержание вам возвращает сервер.

  • @fiesta3653
    @fiesta3653 6 років тому

    Я конечно в большом восторге от того что дошла до конца видео и все в последовательности получалось, за этого огромная благодарность автору, но к сожалению в самом конце я встала в тупик, я не понимаю, что не так, но csv файл волшебным образом не появляется, код еще раз перепроверила, правда было бы хорошо если бы он был где-то в целом виде, видео проблематично перематывать на нужные части, но бог с ним, так как ошибок у меня никаких не выходит единственно мысль, которая меня сейчас посещает - что именно автор нажимает в конце перед тем как появляется файл csv или может он в каком то особенном месте появляется? Ай нид ю хелп люди!!!!! (Python 3.6.4. Win 10-64, Sublime Text 3++)

    • @zaemiel
      @zaemiel  6 років тому

      Я просто нажимаю комбинацию клавиш для запуска скрипта.
      Выложите куда-нибудь ваш код, пожалуйста.
      Например, можно на pastebin.com/

    • @zaemiel
      @zaemiel  6 років тому

      ок, а что значит не работает?
      Что он вам пишет?

    • @fiesta3653
      @fiesta3653 6 років тому

      Нажимаю комбинацию ctrl+f11, показывает - ***Repl Closed***. И ничего нигде не появляется...(

    • @zaemiel
      @zaemiel  6 років тому

      запустите из консоли:
      python ваш_скрипт.py
      или
      python3 ваш_скрипт.py
      Зависит от вашей ОС

    • @fiesta3653
      @fiesta3653 6 років тому

      попробовала, ничего...

  • @emrc5085
    @emrc5085 5 років тому +11

    36:40 ))

    • @Keriokutori
      @Keriokutori 4 роки тому

      думал показалось :D

    • @mikakost
      @mikakost 3 роки тому

      Он сказал "ссылка", но послышалось "сука"

  • @TrueLordBarrington
    @TrueLordBarrington 3 роки тому

    Сейчас актуально? На джабе попробую сделать

  • @ВладДубинин-ь2ш
    @ВладДубинин-ь2ш 6 років тому +2

    При записи в CSV выдает ошибку:
    UnicodeEncodeError: 'charmap' codec can't encode character '\u20bd' in position 52: character maps to
    Попробовал указать кодировку файла utf-8
    def write_csv(data):
    with open('avito.csv', 'a', encoding='utf-8') as f:
    В консоли выводится корректно, а в CSV некорректно отображаются некоторые символы:
    HTC Sensation SE в отличном состоянии,3 000 ₽,
    Не подскажете как можно нормально записать в CSV?
    ОС Windows

    • @zaemiel
      @zaemiel  6 років тому

      Посмотрите здесь p-notes.ru/ в разделе FAQ.
      Если не помогает, то я не знаю.

    • @godlux9272
      @godlux9272 5 років тому +1

      Возможно это проблемы той программы в которой вы пытаетесь прочесть файл CSV, попробуйте сравнить с convertcsv.com/csv-viewer-editor.htm

    • @IrelandKing-q4v
      @IrelandKing-q4v 5 років тому +1

      with open('avito.csv', 'a', encoding='utf-8') as f: # укажите вид кодировки

    • @MrNovenkij
      @MrNovenkij 5 років тому

      Такие файлы можно открывать в Excel не напрямую, а через команду - Данные - Из текста. В этом случае Excel правильно определит кодировку

  • @DJIndigo
    @DJIndigo 7 років тому

    Привет спасибо большое за уроки)
    у меня вопрос, в строке кода
    pages = soup.find('div', class_='pagination-pages').find_all('a', class_='pagination-page')[-1].get('href')
    выдает такую ошибку
    File "C:/Users/Admin/PycharmProjects/game/game.py", line 15, in get_total_pages
    pages = soup.find('div', class_='pagination-pages').find.all('a', class_='pagination-page')[-1].get('href')
    AttributeError: 'NoneType' object has no attribute 'find'
    как это не может найти атрибут find?(

    • @Kindly_Otter
      @Kindly_Otter 2 роки тому +1

      У тебя там опечатка - точка вместо подчеркивания в find_all
      :) Вдруг ещё актуально))

  • @ЩедрыйДобряк
    @ЩедрыйДобряк 7 років тому

    Олег, приветствую
    Спасибо
    Как можем пообщаться лично ?

    • @zaemiel
      @zaemiel  7 років тому

      Сложный вопрос.
      Можно попытаться через почту - molchanov.o.o@gmail.com

  • @kbchertila
    @kbchertila 3 роки тому

    ads = soup.find('div', class_='catalog-list').find_all('div', class_='item_table')
    AttributeError: 'NoneType' object has no attribute 'find_all'
    С чем может быть связано?? подскажите пожалуйста. сам авито изменился и этого атрибута не находит??

    • @schtv3990
      @schtv3990 3 роки тому

      потому ччто у них там сейчас динамические классы везде. сам я пока не знаю есть ли инструменты для работы с ними или через регулярки делать. сам учусь )

  • @MrEzoterik
    @MrEzoterik 5 років тому +1

    Парсит в таблицу через строку. В чем может быть причина?

    • @РишатФайзуллин-ц3х
      @РишатФайзуллин-ц3х 4 роки тому +1

      В строчку:
      with open("avito.csv", "a") as f
      добавьте параметр newline="" в скобки, получится так:
      with open("avito.csv", "a", newline="") as f

  • @houspi
    @houspi 6 років тому +1

    Изучаю питон третий день.
    Мне кажется, что будет гораздо проще и наглядней количество страниц выдернуть не последовательностью сплитов, а регуляркой.
    что-то типа такого
    re.search('p=(\d+)', pages).group(1)

    • @zaemiel
      @zaemiel  6 років тому +1

      Вы не поняли основного посыла это видео.
      Это не рецепт аля "делай так и никак по-другому", это больше похоже на принцип, где детали реализации могут отличаться.
      Если вы хотите изымать количество страниц регулярными выражениями - ради бога,
      Нравится парсить весь HTML сайта только регулярными выражениями - пожалуйста.
      Это не имеет никакого значения. Абсолютно.

    • @doniyordjon
      @doniyordjon 2 роки тому

      Подскади плиз, что написать вместо pages, у меня парсинг новостного сайта, блок скажем финансы, но на некст url, номера страницы не по порядку и 8 значные цифры идут каждый раз

  • @Oberst3001
    @Oberst3001 4 роки тому

    Чисто для интереса сделал весьма продвинутый парсер, но в итоге через день страницы возвращают код 403 forbidden, опять же заморочился, менял юзер агенты и прочие headers, применял proxy. все равно такая ошибка. Причем обычная, браузерная версия работает. Если кто то знает в чем все таки прикол, было бы интересно узнать.

    • @motor2298
      @motor2298 3 роки тому

      Победил 403 ошибку?

  • @romanbond1060
    @romanbond1060 2 роки тому

    жаль, не работает так уже, авито проверку браузера по js добавил

  • @MrCkalolaz
    @MrCkalolaz 7 років тому

    Спасибо, Вам, за Ваш труд. Хочу научиться писать на Python. Просмотрел этот ролик 2 раза, во время второго делал все за Вами один в один(только на авито ссылка чуть-чуть другая). При запуске получаю следующее: Process finished with exit code 0
    Debug:
    pydev debugger: process 11656 is connecting
    Connected to pydev debugger (build 171.3780.115)
    Process finished with exit code 0
    Как можно понять что именно я не правильно сделал?

    • @MrCkalolaz
      @MrCkalolaz 7 років тому

      Разобрался. Причина была в отсутствии lxml и в кириллице в ссылке. Еще раз спасибо за предоставленный материал.
      Всем добра!

    • @zaemiel
      @zaemiel  7 років тому

      Спасибо за ваш отзыв. Мне нравится, что вам нравится.
      Но мне не очень понятно, зачем вы берете IDE, которые вам не помогают, а, скорее, мешают?
      PyCharm если не ошибаюсь...
      Фишка в том, что это не ошибка. Это дополнительная информация, которую вам показывает Debuger.
      Строка "Process finished with exit code 0" говорит о том, что у вас все ок и код выполнился без ошибок.
      Позволю себе небольшой комментарий.
      Вам будет удобнее если во время написания кода вы определите для себя критерии его работоспособности, хотя бы в голове.
      Т.е. вы должны четко представлять, когда ваш скрипт работает так как нужно, независимо от того, где вы этот код пишите.

  • @sergeykulchitskiy2554
    @sergeykulchitskiy2554 7 років тому

    Огромное спасибо за качественные уроки. Подскажите, пожалуйста, как извлечь вторую цену: 3 131 грн2 150 грн. Заранее благодарю.

    • @zaemiel
      @zaemiel  7 років тому

      1. вызываете свойство .text
      2. Смотрите что получилось.
      Получилось что-то вроде:
      "3 131 грн2 150 грн"
      3. Как видите это строка. Режем ее в список по 'грн'
      prices = soup.text.split('грн')
      4. Получаем список:
      ['3 131 ', '2 150 ', '']
      5. Берем второй элемент списка.

    • @sergeykulchitskiy2554
      @sergeykulchitskiy2554 7 років тому

      Благодарю за оперативный ответ, цена берется без грн. Можно исправить?
      sale = soup.find('div', class_='catalog-item__price catalog-item__price--special').text
      sale = soup.text.split('грн')[1]

    • @zaemiel
      @zaemiel  7 років тому

      я вопрос не понял.
      вы берете цену в гривнах. Нужно обозначение? Добавьте ' грн.'

    • @sergeykulchitskiy2554
      @sergeykulchitskiy2554 7 років тому

      верно поняли. добавлю. Благодарю.

  • @benneric408
    @benneric408 3 роки тому

    Код 1 в 1 только у меня total_pages = pages.split('=')[2].split('&')[0] и ошибка в этом.... Почему?

    • @nikitazhmurko8059
      @nikitazhmurko8059 3 роки тому

      возможно отсутствуют данные разделители. посмотри на актуальную ссылку сайта. В процессе написания того что выше, я заметил у тебя индекс "2" при разделителе равно "=". Попробуй [1], ведь там их всего два знака равно, не три!

    • @benneric408
      @benneric408 3 роки тому

      @@nikitazhmurko8059 У меня 3 знака, и все ровно я менял уже на идентичный код

  • @Нячанг
    @Нячанг 7 років тому +1

    Олег подскажи плиз почему у меня таблица не как у тебя.. А все в 1 линию?

    • @esthetik_life
      @esthetik_life 6 років тому +1

      office-guru.ru/excel/preobrazovyvaem-csv-v-excel-kak-importirovat-faily-csv-v-elektronnye-tablicy-excel-368.html

    • @prosto_komputer
      @prosto_komputer 6 років тому +1

      Мне помог )))

  • @sergeisumarokov
    @sergeisumarokov 7 років тому

    Спасибо за подробный разбор!
    Пара вопросов:
    1. Простая склейка ссылок ничем не отличается от: urljoin(ulr, href) ?
    2. Как декодировать полученные результат, я ставил .decode('utf-8') после каждого title=ad.find(...), но все равно получаю иероглифы вместо русского?

    • @zaemiel
      @zaemiel  7 років тому

      Мой каст - это просто иллюстрация к тому, как можно спарсить сайт. Это
      один из тысячи способов. Если вы парсите по-другому, то это прекрасно.
      1. Вы хотите использовать специальный метод urljoin() для того, чтобы объединить 2 строки? Вообще-то urljoin() решает другую задачу - он не объединяет 2 строки.
      "Простое лучше, чем сложное"
      2. Как видите, я не использовал .decode() и все данные получил на русском. Какой у вас python?

    • @sergeisumarokov
      @sergeisumarokov 7 років тому +1

      Я только учусь, не принимайте вопросы на свой счет, возможно они имеют очевидные решения :)
      Использую я python 3.5.1 и на системе mac
      Кстати еще где мы задавали диапазон для парсинга range(1, total_pages) нужно total_pages+1, что бы не забыть последнюю страницу.
      И я из вашего видео про многопоточность прикрутил Pool и запустил на 15 потоках, в итоге мне начало выдавать ошибку при обращении к сайту, хотя в браузере он открывался. А выдавал он ошибку: AttributeError: 'NoneType' object has no attribute 'find_all' - по всей видимости он выдал страницу, где нет уже списка всех страниц.
      Запишите пожалуйста, по возможности, видео - как работать с такого вида ошибками и не получить капчу или бан от сайта

    • @zaemiel
      @zaemiel  7 років тому

      про +1 к range - это вы верно заметили. Получился диапазон ДО последней страницы. Но уже было поздно.
      AttributeError: 'NoneType' object has no attribute 'find_all'
      Говорит о том, что тот объект супа, который вызвал find_all пустой. Т.е. там ничего нет. Т.е. та страница, которая парсилась не имела этого элемента.
      Вы правы, скорее всего это временный бан.
      Я иногда ставлю в get_html проверки типа
      if r.ok:
      ....return r.text
      print(r.status_code)
      return None
      Типа такого.
      Как-нибудь запишу.

    • @kisli3000
      @kisli3000 7 років тому

      И автору отдельное спасибо, за урок, очень помогло!

    • @ИванЛавренюк-и5д
      @ИванЛавренюк-и5д 7 років тому

      мне помогли .encode('utf-8') перед .strip()

  • @Karkas38
    @Karkas38 2 роки тому +1

    УМЕНЯ ОШИБК Response [403]

  • @tigran6838
    @tigran6838 6 років тому

    Очень хорошее видео! Но у меня не получилось сохранить все в csv, подумал из за кодировки и прописал encoding='utf-8' и сохранилось но когда открыл через excel сначала вылезла ошибка а потом оказалось что цена метро и остальные записаны в одном яйчейке а не как в видео в столбцах. Помогите решить если не сложно

    • @zaemiel
      @zaemiel  6 років тому

      p-notes.ru
      там есть раздел FAQ и там вашу проблему я описал

  • @ВиталийПопов-д8ю
    @ВиталийПопов-д8ю 4 роки тому

    Кто-нибудь проходил курс автора канала по парсингу сайтов, появляются вопросы в процессе прохождения, имеет смысл организовать форум для обсуждения. Откликнитесь.

  • @provseiobovseh
    @provseiobovseh 4 роки тому

    ругается на for i in range(1, total_pages) что total_pages не существует. И импорт from bs4 нет такого имени говорит

  • @johny2308
    @johny2308 6 років тому

    Строчка pages = soup.find('div', class_='pagination-pages').find_all('a', class_='pagination-pages')[-1].get('href') выдает ошибку Traceback (most recent call last):
    File "", line 1, in
    IndexError: list index out of range что делать? еще пишет по функции get_total_pages NameError: name 'html' is not defined

    • @zaemiel
      @zaemiel  6 років тому

      NameError: name 'html' is not defined - означает, что вы использовали имя переменной html, но нигде ее не определили. Проверьте еще раз код.
      IndexError: list index out of range - означает, что вы обратились к элементу списка, которого в нем нет. Т.е. есть некий список из 3-х элементов, а вы обратились к 4-му - some_list[3].
      Проверьте код. Проверьте, какие объекты вам возвращает .find_all() - я считаю, что .find_all() вернул по какой-то причине пустой список, поэтому при обращении к последнему элементу этого списка получилось это исключение IndexError: list index out of range

    • @zaemiel
      @zaemiel  6 років тому

      find() - не возвращает список. Он возвращает объект Tag. Убедитесь в этом сами - type(ваша_переменная)
      find().find() - лишено смысла, потому, что не понятно что вы ищите. Можно использовать запись такого рода:
      soup.body.h1 - это аналогично этой записи: soup.find('body').find('h1')
      Про выпадающие списки - я не понял ничего.

  • @ВладимирЗадорожный-е2у

    Олег, добрый день. Помогите разобраться. Нужно спарсить из: "@Fernand91018279 " текст : "Fernand91018279". Пишу код: ads = soup.find('span', class_='username u-dir').text, выдаёт "@". Далее: ads = soup.find('span', class_='username u-dir').find('b', class_='u-linkComplex-targe').text, ругается, что нет текста. В чём косяк?

    • @zaemiel
      @zaemiel  5 років тому

      нет текста в том смысле, что нет такого атрибута?
      Посмотрите, что возвращает вам find('b', class_='u-linkComplex-targe') - какой объект, какое у него содержание. Если опять ничего - сдвигайтесь влево до следующего find

    • @ВладимирЗадорожный-е2у
      @ВладимирЗадорожный-е2у 5 років тому

      @@zaemiel Следующий find, влево возвращает '"@'

    • @ВладимирЗадорожный-е2у
      @ВладимирЗадорожный-е2у 5 років тому

      @@zaemiel Пробовал на других сайтах парсить. Всё прекрасно! А вот, на твитере - ни в какую!

    • @alangonzalez2869
      @alangonzalez2869 5 років тому +1

      @@ВладимирЗадорожный-е2у А твиттер, ютюб и другие акулы интернета, всё делают для того что-бы их не парсили, их бизнес это реклама на их сайтах, а вы хотите их "пирожки" (контент) бесплатно, да ещё и в первую очередь и без нагрузки (рекламы), стоит тренироваться на сайтах попроще, а по мере опыта переходить к акулам, к тому же без полноценного разбора JavaScript на таких сайтах спарсить почти ничего не получится, например у ютюба контент подтягивается (инкапсулируется) с помощью AJAX запроса, в котором каждая ссылка генерируется с помощью токена и если вы ее вытяните через отладчик, то она вам ничего не даст, при следующем обращении вы получите пустой ответ (фигу в кармане)... Но способы побороть есть, ключевое слово для гугла "Selenium"... Время бесплатного (дешевого) хлеба закончилось, пришло время подбирать крошки за...

  • @galymzhankenesbekov2924
    @galymzhankenesbekov2924 4 роки тому

    блин, у меня ничего не получается. я делаю на Jupyter и не могу понять, у меня установлен Суп или нет

    • @vladislavshevtsov143
      @vladislavshevtsov143 4 роки тому

      Это легко проверить через консоль, импортируешь Суп если его нет строка выдаст ошибку

  • @user-jm1qf4li7g
    @user-jm1qf4li7g 5 років тому

    Привет Олег) возникла такая проблема у меня, сайт выдает ошибку 403 Fobbian, на сколько я знаю то нужно передать сайту отпечаток браузера, иначе он блокирует все попытки получить html( Не подскажешь как это сделать? пока что в этом деле я новичок, перерыл множество информации по этому поводу, но так и не смог найти то что мне подойдет.

    • @alangonzalez2869
      @alangonzalez2869 5 років тому

      посмотри в сторону "User-agent" спроси у гугла если не знаешь что это, почитай документацию о методах "requests", в частности как она работает с заголовками.

  • @yyyyyyyyyyyyyyyyy592
    @yyyyyyyyyyyyyyyyy592 6 років тому

    как ты учился?

  • @xx113355
    @xx113355 4 роки тому

    Видео как и все другие очень понятное. Единственно - звук некачественный, шипение достает(

    • @zaemiel
      @zaemiel  4 роки тому

      Что ж поделать... это одно из первых моих видео.

  • @КириллСоколов-м1д
    @КириллСоколов-м1д 6 років тому

    День добрый , скажу честно новичек самоучка учусь сам по литературе видео и форумам попался на глаза твой код решил разобрать. честно круто все рассказал все понятно я повторил код кое где ошибся исправил, файлик получил но по окончанию скрипта получаю вот это
    python Parser.py
    Traceback (most recent call last):
    File "Parser.py", line 75, in
    main()
    File "Parser.py", line 72, in main
    get_page_data(html)
    File "Parser.py", line 33, in get_page_data
    ads = soup.find('div', class_='catalog-list').find_all('div', class_='item_table')
    AttributeError: 'NoneType' object has no attribute 'find_all'
    подскажи где я ошибся в твоем коде
    p.s. win10 x64 VScode py3.6.4

    • @zaemiel
      @zaemiel  6 років тому

      ads = soup.find('div', class_='catalog-list').find_all('div', class_='item_table')
      ads = soup.find('div', class_='catalog-list') - вот это выражение вернуло вам None.
      Вот о чем это исключение

    • @КириллСоколов-м1д
      @КириллСоколов-м1д 6 років тому

      получается скрипт отработал 3 страницы со списками а потом получил запрет от сервера????? вопрос а если не работать в url а сохранять страницы в изменяемом файле парсить необходимую информацию, ну примерно как в во второй части вашего видео???

    • @ДанилЧерепухин
      @ДанилЧерепухин 5 років тому

      @@zaemiel мне тоже почему-то возвращает None... не могу понять почему

  • @mikhailsirotkin667
    @mikhailsirotkin667 7 років тому

    pages = soup.find('div', class_='pagination-pages').find_all('a')[-1].get('href') bez dublirovaniya class_

  • @Andy-kl1ry
    @Andy-kl1ry 5 років тому

    Подскажите пожалуйста, как сделать, чтобы после выполнения программы в sublimetext Можно было ввести команды, например, чтобы проверить переменные?

    • @zaemiel
      @zaemiel  5 років тому

      В саблайме раньше это работало плохо. Лучше запускать скрипты в интерактивном режиме:
      python -i ваш_скрипт.py

    • @Andy-kl1ry
      @Andy-kl1ry 5 років тому

      т.е. чтобы поработать в интерактивном режиме, единственный путь, через стандартный IDLE? Не хотелось бы... я только от него ушел на subleme :(

    • @zaemiel
      @zaemiel  5 років тому

      консоль

    • @Andy-kl1ry
      @Andy-kl1ry 5 років тому

      @@zaemiel, простите, не понимаю о чем речь :( в win10 видимо нужно что-то сделать, чтобы sublime работал с консолью. Сейчас, я использую саблайм для написания кода, а когда нужно отладить код и посмотреть переменные, приходится запускать стандартную интерактивную оболочку :(

    • @zaemiel
      @zaemiel  5 років тому

      вы можете запускать скрипты из консоли - cmd.
      Просмотреть переменные вы можете, расставив print()-ы там, где нужно.

  • @VitalySem
    @VitalySem 4 роки тому

    У мене парсить з проміжком у один рядок. Між кожним рядком один порожній рядок.

  • @АлексейДударев-м1ы
    @АлексейДударев-м1ы 7 років тому

    Подскажите, пжлст, почему после того, как я свожу полученную инфу в csv таблицу информация у меня не разделяется на столбцы, как в вашем примере, а идёт в одну строчку через запятую? Excel+Win

    • @zaemiel
      @zaemiel  7 років тому

      Очевидно, что что-то неправильно делаете.
      Код - в студию!

    • @zaemiel
      @zaemiel  7 років тому

      только не весь, а обработчика csv

    • @maksimvasiunin8179
      @maksimvasiunin8179 7 років тому +3

      Можно попробовать напрямую указать delimiter на свой вкус
      csv.register_dialect('customcsv', delimiter=';', quoting=csv.QUOTE_NONE, quotechar='',escapechar='\\')
      with open("avito.csv", "w", encoding='cp1251', newline='') as f:
      writer = csv.writer(f, 'customcsv')

    • @АндрейДубоделов-п1г
      @АндрейДубоделов-п1г 7 років тому +6

      У меня тоже самое на Excel+Win. К тому же еще через строку все выводило. Разобрался с этим вопросом. Отредактировал строку:
      Было writer = csv.writer(f)
      Стало writer = csv.writer(f, delimiter=';', lineterminator='
      ')
      delimiter=';' расставляет все по отдельным столбцам
      lineterminator='
      ' убирает вывод через строку.
      Причина - какие то особенности русскоязычного офиса Win.

  • @АлексейСапицкий-э4щ

    Я вот столкнулся с такой проблемой если парсить названия в которых есть недопустимые символы, например квадратный метр, то срабатывает исключение, и title мы не получаем. Как это можно пофиксить?

    • @zaemiel
      @zaemiel  7 років тому

      Вы знаете, я буквально сейчас проверил - название с квадратными метрами
      (двойка в верхнем индексе) спарсилось нормально и нормально записалось в
      текстовый файл - также двойка в верхем индексе.
      Я под линуксом - тут Unicode по дефолту. Если вы используете виндос, то у них может быть своя кодировка и может быть поэтому у вас пустота.
      Либо как вариант - ошибка в другом месте.

    • @АлексейСапицкий-э4щ
      @АлексейСапицкий-э4щ 7 років тому

      Олег Молчанов Да я под виндой выкидывало исключение charmap о том что не может обработать символ \xb2, но я вроде разобрался.

  • @ывапвапваплдвоаипжаыволп

    Не могу понять, код ошибок не выдает, но при этом ничего не выводит

    • @zaemiel
      @zaemiel  6 років тому

      значит где-то что-то забыли вызвать или прописать. Очевидно же.

    • @metrodon171783
      @metrodon171783 4 роки тому

      У тебя в коде должно быть прописано вместо main - name. Советую поменять
      if __name__ == '__main__':
      main()
      Хотя ты явно уже всё сделал сам =_=