Форум сайта python.su
Доброго времени суток!
Решил сменить работу, а заодно изучить хвалённый python.
Посмотрел видео о парсинге Avito и т.п. сайтов.
Вроде всё понятно и доступно. Решил спарсить praca.by.
Дошёл до карточки вакансии.
Что бы получить все параметры вакансии, имеющиеся в карточке,
использовал несколько способов, дающих приблизительно одинаковый результат.
import requests
>>> from bs4 import BeautifulSoup
>>> url = 'https://praca.by/vacancy/499310/'
>>> resp = requests.get(url)
>>> resp.status_code
200
>>> soup = BeautifulSoup(resp.content, ‘lxml’)
>>> salary = soup.find('div', attrs={“class”: “vacancy__salary”}).text.strip()
>>> salary
'1\xa0000 - 1\xa0100 руб. на руки'
>>> print(salary)
1 000 - 1 100 руб. на руки
И далее
1)способ.
Мне он нравится из-за доступности к пониманию даже для новичка
>>> all_harakt = soup.find_all('div', attrs={“class”: “vacancy__item”})
>>> for element in all_harakt:
print(element)
2)способ. Результат аналогичен 1-му способу
>>> all_harakt = soup.select('div.vacancy__item')
>>> all_harakt
3)способ. Аналогичен 2-му, но выборка с фильтром по двум тегам div
Один с классом vacancy__item, второй div без класса
>>> all_harakt = soup.select('div.vacancy__item div')
>>> all_harakt
Результат по 3-му способу:
[<div>
<b>Характер работы:</b>
На территории работодателя </div>, <div>
<b>График работы:</b>
Фиксированный / полный рабочий день </div>, <div>
<b>Занятость:</b>
Полная </div>, <div class=“vacancy__term”>Опыт работы</div>, <div class=“vacancy__desc”>
<p class=“vacancy__experience”>
Опыт работы от 1 года </p>
</div>, <div class=“vacancy__term”>Образование</div>, <div class=“vacancy__desc”>
<p class=“vacancy__education”>
Высшее образование </p>
</div>]
Хочу получить в переменные значения:
a='На территории работодателя'
b='Фиксированный / полный рабочий день'
c='Полная'
d='Опыт работы от 1 года'
e='Высшее образование'
Пытался использовать
1)
>>> for each in all_harakt:
print (str(each.get_text()))
2)
>>> for each in all_harakt:
string = str(each.get_text())
string = string.replace(“\r”,“”)
string = string.replace(“\n”,“”)
string = string.replace(“ ”,“ ”)
print (string)
3)
>>> import re
>>> for each in all_harakt:
string = str(each.get_text())
string = re.sub(“^\s+|\n|\r|\s+$”, '', string)
print (string)
Самые большие надежды я возлагал на метод .decompose(),
расчитывая избавиться от тега <b>, а потом от <div class=“vacancy….
И здесь я глухо застрял.
>>> for item in all_harakt:
#print(item)
try:
all_harakt.b.decompose()
except:
print(”error“)
Очевидно, что я не понимаю некого базового принципа и ”копаю“ не в ту сторону.
Поэтому я привел ход моих мыслей, что бы профи увидели этот изъян
и помогли мне не только решением, но и взглянуть на решение
задачи ”глазами питона".
Заранее спасибо всем откликнувшимся.
Отредактировано 123ksn (Ноя. 26, 2022 12:37:19)
Офлайн
123ksnТак питона-то для этого недостаточно. Он необходим, но при этом достаточным не является, потому что вместе с питоном ещё кое-что надо и не одно.
Решил сменить работу, а заодно изучить хвалённый python.
123ksnТам надо брать сначала весь тег
Дошёл до карточки вакансии.
Что бы получить все параметры вакансии, имеющиеся в карточке,
использовал несколько способов, дающих приблизительно одинаковый результат.
<div class="vacancy-required">
123ksnДа, ты пытаешься попроще сделать всё сразу. А надо, наоборот, всё структурировать до мельчайших деталей и делать всё постепенно, поэтапно, шаг за шагом, скрупулёзно.
Очевидно, что я не понимаю некого базового принципа
123ksnФункции знаешь вообще? Что это такое? Что такое сигнатура? Что такое императивные имена? Определение? Вызов? Формальные аргументы? Фактические аргументы? Передача по значению? Передача по ссылке? Рекурсивный вызов?
Решил сменить работу, а заодно изучить хвалённый python.
Посмотрел видео о парсинге Avito и т.п. сайтов.
Отредактировано py.user.next (Ноя. 26, 2022 14:46:01)
Офлайн
py.user.nextСпасибо за столько времени, которое Вы мне уделили, написав столько текста.
Так питона-то для этого недостаточно. Он необходим, но при этом достаточным не является, потому что вместе с питоном ещё кое-что надо и не одно.
py.user.next3)Это Вы точно подметили. Но не из-за того, что я ленив, а из-за того, что знаю про метод .decompose() и про него же задаю вопрос.
ты пытаешься попроще сделать всё сразу.
Офлайн
123ksn
Хочу получить в переменные значения:
a='На территории работодателя'
b='Фиксированный / полный рабочий день'
c='Полная'
d='Опыт работы от 1 года'
e='Высшее образование'
import requests from bs4 import BeautifulSoup import re URL = 'https://praca.by/vacancy/499310/' def get_html(url): try: resp = requests.get(url) if resp.status_code == 200: return 0, resp.content.decode('utf-8') else: return 1, (url, resp.status_code) except Exception as e: return 2, (url, e) def get_key_value_from_text(text): return re.split('\t+', re.sub('[\n:]', '', text.strip())) def get_data_from_block(block): out = dict.fromkeys(['Характер работы', 'График работы', 'Занятость', 'Опыт работы', 'Образование']) items = block.find_all('div', class_='vacancy__item') for i in items: data = get_key_value_from_text(i.text) if data[0] in out: out[data[0]] = data[1] return out def get_data_from_html(html): soup = BeautifulSoup(html, 'html.parser') block = soup.find('div', class_='vacancy-required') if block: return 0, get_data_from_block(block) else: return 1, 'error: block not found' def main(): html = get_html(URL) if html[0]: print(html[1]) return data = get_data_from_html(html[1]) if data[0]: print(data[1]) return print(data[1]) if __name__ == '__main__': main()
{'Характер работы': 'На территории работодателя', 'График работы': 'Фиксированный / полный рабочий день', 'Занятость': 'Полная', 'Опыт работы': 'Опыт работы от 1 года', 'Образование': 'Высшее образование'}
Process finished with exit code 0
Отредактировано xam1816 (Ноя. 27, 2022 10:43:43)
Офлайн
123ksnДа нет же. Ты как раз спарсил данные с мусором, а после этого не знаешь, как очистить от этого мусора данные. А классифицировать этот мусор можно как раз через поэтапный разбор. В зависимости от того, из какого отсека этот мусор изначально появляется, таким способом он и очищается. Он по-разному должен удаляться, а ты же сбросил его в одно ведро, а потом думаешь, то ли жечь его, то ли в унитаз смывать. Там для одних частей мусора надо сделать одно, а для других - другое. Но когда они смешаны, для них ни то, ни другое делать нельзя. Если у тебя лежит в одном ведре одновременно ртуть, жир, бензин и макароны, ты будешь поджигать их? а смывать их в раковину? а выливать на улицу? Они по-разному утилизируются и для этого их сначала нужно отделить из одного ведра по разным ёмкостям. На самом деле, их и не надо было складывать в одно ведро. От них надо было избавляться подходящими способами по мере их появления во всей этой истории.
И я это сделал, но не так красиво как хотелось бы.
123ksnТы ищешь волшебную палочку. Типа я сейчас взмахну волшебной палочкой (методом decompose(), регуляркой какой-нибудь, ещё чем-то) и вжух! у меня всё само очистится и результат получится точным и правильным. А в программировании-то оно так не работает. Фактически надо провести действия, обратные тем действиям, которые делал программист этого сайта. Он составлял эту структуру страницы так-то и так-то, а ты должен разобрать эту страницу обратно тем же образом, выполняя как бы действия того программиста в обратном порядке. Тогда у тебя всё получится и ты точно разберёшь всё. В этом и есть секрет.
что знаю про метод .decompose() и про него же задаю вопрос
123ksnЛинукс не мог такого говаривать, потому что Линукс - это операционная система. А написал её Линус.
Как говаривал Линукс, не надо слов, покажите код.
123ksnТут ошибка в том, что all_harakt уже неправильно сформирован, поэтому его нельзя перебирать. Элементы в нём не единообразны, поэтому применять к ним ко всем одинаковый алгоритм просто нельзя, а детерминировать их по типам уже поздно, потому что они потеряли информацию о своих источниках и ты просто не можешь узнать, откуда и какой элемент происходит и, соответственно, каким именно способом нужно разбирать конкретно его мусор. Можно, конечно, гулять до родителей из них, но это такая бредятина получается вроде той построенной зачем-то стены, которая потом только мешает и к которой потом всё время приставляют лестницу, чтобы преодолевать эту стену. Фактически это и есть то ведро, в котором ты решил перебрать все компоненты и сжечь каждый из них одним и тем же образом. В итоге, понимаешь ли, макароны гореть не будут, а бензин вообще даст такой эффект, что мало не покажется; ртуть же не загорится, а ты просто ею надышишься во время всего этого и она вызовет сбой в твоей нервной системе. Надо было ещё на предыдущем этапе действовать по-другому, чтобы просто даже не прийти к этой неправильной ситуации, в которой ты ничего не можешь сделать.
Может проще пояснить где здесь ошибка?for item in all_harakt: #print(item) try: all_harakt.b.decompose() except: print("error")
Отредактировано py.user.next (Ноя. 28, 2022 00:46:46)
Офлайн
py.user.nextУважаемый py.user.next! Это не сарказм! Я действительно очень ценю Ваше участие в моём вопросе! Но есть большое “НО”. Вам не жалко собственного времени на нравоучения? На другом форуме мне НЕ “полоскали” мозг, а предложили пару решений. От одного из них я готов был застрелиться, настолько оно красивое, лаконичное, я бы сказал - гениальное!
Линукс не мог такого говаривать, потому что Линукс - это операционная система. А написал её Линус.
py.user.next
сейчас взмахну волшебной палочкой (методом decompose(), регуляркой какой-нибудь, ещё чем-то) и вжух! у меня всё само очистится и результат получится точным и правильным
url = 'https://praca.by/vacancy/499310/' resp = requests.get(url) soup = BeautifulSoup(resp.content, 'lxml') all_harakt = soup.select('div.vacancy__item') all_harakt = [elem.text.strip().split('\t')[-1] for elem in all_harakt] print(*all_harakt, sep='\n')
Отредактировано 123ksn (Ноя. 28, 2022 12:14:33)
Офлайн
123ksnПонимаешь, если я буду сидеть и всем писать тут коды, то я себе не смогу писать коды, потому что всё моё время будет занято чужими кодами, а в данный момент я каждый день разрабатываю себе приложение для смартфона на языке Java и мне нужно себе коды писать. На каждый кусочек этого небольшого, но полезного и нужного приложения уходит часа по два, а таких кусочков надо написать где-то штук тридцать, и я уже написал примерно двадцать. Естественно, я не буду тебе код писать, потому что ты тут не один, и придётся им всем писать коды. Я вчера поставил это приложение в смартфон, а сегодня надо будет в нём делать экраны, чтобы при переворачивании смартфона всё правильно расставлялось на экране и кнопки приложения не вылазили за края экрана. Но я даю тебе удочку, чтобы ты научился сам писать себе всё. В этом и есть функция форума. Человек приходит нулём, а уходит наученным. Поэтому есть смысл тебе вообще писать. Ты научишься и будешь делать всё сам. Если я напишу тебе код, то 1) я впустую потеряю своё время, 2) ты ничему из него не научишься, 3) а потом у тебя возникнет следующая подобная задача и ты снова, как желторотый цыплёнок, придёшь на форум и попросишь снова для тебя код написать, червячка тебе положить, потому что сам ты не можешь это сделать, так как надо учиться сначала делать это.
Если честно, то я надеялся всё же увидеть реальный вариант решения через .decompose()
123ksnЭто не грамматическая ошибка. Это ты, не зная как и что называется и кто и что когда говорил, выступил таким знатоком типа. То же самое касается этих кодов. Ты не понимаешь, что тебе говнокод написали, но ты радуешься и называешь его гениальным. Ладно, допустим код подходит тебе как-то каким-то там образом, но завтра у тебя возникнет следующая задача по парсингу (они, знаешь, всегда парами ходят; где одна, там и вторая), и этот говнокод, естественно, к ней не подойдёт, потому что у него нулевая переиспользуемость, и ты что сделаешь? Естественно, топик создашь, здесь, там, повсюду, везде будут эти топики.
Я попытался перевести тему разговора в конструктивное русло, “прикрывшись” Линусом, но и здесь, к сожалению, Вы смогли увидеть только грамматическую ошибку.
123ksnУчиться надо по книжкам. А там и код есть обычно, но не в виде говнокода, а отточенный и проверенный кучей людей, которые понимают в этом. Ты, наверное, не в курсе, но говнокод тоже бывает и комментированным вдоль и поперёк, и таким типа умным на вид. Новичок такой говнокод не поймёт и не распознает его качество. Но вот качество его даст о себе знать рано или поздно. Когда он будет где-то использоваться, вдруг выяснится, что в нём есть баг. Только вот баг этот исправить будет нельзя, потому что код сформирован так, что баги в нём исправляются только путём переписывания этого кода полностью с самого начала.
Я, например, люблю учиться по сложному, но хорошо и правильно комментированному коду.
123ksnНу, он вообще никакой. Там другой парень Skryp хоть что-то вменяемое выдал. Но и его вариант мне не нравится. Кусок html-кода, относящийся к вакансии целиком, он нашёл, но дальше-то надо разбивать этот блок на большие части, а не пытаться сократить путь. Не состоит она только из vacancy__item'ов, там данные вперемешку идут, поэтому и надо сначала провести разделение на данные вакансии и описание вакансии, а данные вакансии надо потом снова делить. И функций у него нет, поэтому всё это быстро превратится в свалку в скором времени.
Приведу его здесь (автор Gdez).
123ksnПонимаешь, если я потратил желание помочь впустую, то это плохо не для меня, я-то всё своё взял при этом, но вот для тебя это, действительно, плохо будет, так как ты провозился с этим кодом и ничему не научился, ничего не вынес из этого всего. Потом ты попробуешь сделать такое же что-то, повторить то же самое, а оно у тебя не получится, потому что ты не научился. А кто тебя будет учить? Вот эти ребята тебя не научат, так как они сами не умеют. Я по их кодам вижу их уровень, что они изучали, докуда они это изучали и так далее.
Понимаете, я новичок и многие Ваши аналогии не могу понять. Т.е., по факту, всё своё красноречие и желание помочь, Вы потратили впустую.
Отредактировано py.user.next (Ноя. 28, 2022 14:12:54)
Офлайн
py.user.nextЕщё раз спасибо, что уделили мне столько времени. Но я думаю, что не буду серьезно заниматься питоном. Просто мне потребовалось получить в удобном виде информацию и теперь могу получать все вакансии за последние сутки (около 45стр*20~900). Да, через некоторое время может всё измениться. Но что вечно? Поэтому Вы ошибаетесь, что я ничему не научился. Я быстро, минимальными знаниями, с помощью ютуба и форумов “на сейчас” решил задачу и “прикоснулся к хвосту” питона. Если бы мне нужны были фундаментальные знания, то конечно же я использовал Ваш подход к решению задачи.
Понимаешь, если я потратил желание помочь впустую, то это плохо не для меня, я-то всё своё взял при этом, но вот для тебя это, действительно, плохо будет, так как ты провозился с этим кодом и ничему не научился, ничего не вынес из этого всего.
Офлайн
123ksn
ТРИ строчки на решение!!! А суть, пожалуй, в одной!
import requests, re from bs4 import BeautifulSoup print('\n'.join(re.findall('(?<=\t)[^\t\n]+', BeautifulSoup(requests.get('https://praca.by/vacancy/499310/').content.decode(), 'html.parser').find('div', class_='vacancy-required').text)))
На территории работодателя
Фиксированный / полный рабочий день
Полная
Опыт работы от 1 года
Высшее образование
Process finished with exit code 0
Офлайн
xam1816Уважаемый xam1816! Мне было проще понять и доработать решение от Gdez под себя чем Ваше. Возможно, предложенное Вами решение более академическое что ли, но , как всегда злосчастное “НО”, Вы не предложили решение, которое нужно было мне. Вы предложили ПОЧТИ такое. Аргументирую:
Потом сюда приходят после такого кода, с темами типа - я оставил гениальный скрипт работать на ночь, а у меня вылетело, в чем может быть причина, помогите пожалуйста разобраться в одной строке !
all_harakt = [elem.text.strip().split('\t')[-1] for elem in all_harakt]
all_harakt = soup_k.find_all('div', attrs={"class": "vacancy__item"}) #.text.strip() aaa=[] for elem in all_harakt: aa = [elem.text.strip().split('\t')[-1]] aaa.append(aa) # print(*aa, sep='\n')#* Распаковывает итерируемый объект в аргументы функции region=aaa[0]# На территории работодателя time_work=aaa[1]# Фиксированный / полный рабочий день full_partial_load=aaa[2]# Полная experience=aaa[3]# Опыт работы от 1 года education=aaa[4]# Высшее образование
py.user.nextЕсли я Вас как-то задел за живое, то прошу прощения. Мне никто ничем не обязан. И я Вам очень признателен за помощь. Просто несколько человек откликнулись на мою проблему и я в порыве восторга высказался об одном из них очень чувственно. Но это никоим образом не унижает Ваш вариант. Надеюсь, что из-за моей ошибки Вы не будете другим новичкам выдавать решения в виде одной строки. Удачи Вам!!!!
Да, ты пытаешься попроще сделать всё сразу. А надо, наоборот, всё структурировать до мельчайших деталей и делать всё постепенно, поэтапно, шаг за шагом, скрупулёзно.
Офлайн