CoderCastrov logo
CoderCastrov
NLP

Парсинг Bright Network и сопоставление описаний вакансий с вашим резюме на Python

Парсинг Bright Network и сопоставление описаний вакансий с вашим резюме на Python
просмотров
5 мин чтение
#NLP
Table Of Content

Используйте парсинг веб-страниц и обработку естественного языка для поиска наиболее подходящих вакансий на сайте Bright Network.

Введение

Поиск работы может быть ошеломляющим процессом, так как количество вакансий часто огромно и требует больших затрат времени на просмотр. В этой статье представлен проект на языке Python, который позволяет сделать этот процесс более эффективным путем автоматизации извлечения описаний вакансий с веб-сайта Bright Network и сопоставления их с заданным резюме. Используя техники парсинга веб-страниц и обработки естественного языка, вы можете найти наиболее подходящие вакансии, соответствующие вашему опыту и навыкам.

Предоставив ссылку на список вакансий с сайта Bright Network и вставив текст своего резюме в скрипт, пользователи могут загрузить файл CSV, содержащий вакансии, отсортированные по степени соответствия. Это позволяет соискателям работы сосредоточиться на наиболее подходящих возможностях и оптимизировать процесс поиска работы.

Вот ссылка на соответствующий блокнот Colab.

Пошаговое руководство

В этом руководстве мы продемонстрируем, как:

Предварительные требования

Для выполнения инструкций вам нужно установить Python 3.8+ и иметь базовое понимание парсинга веб-страниц, обработки естественного языка и BERT. Но вы также можете просто загрузить свое резюме с помощью ссылки от Bright Network и позволить работать конвейеру.

Используемые библиотеки

Мы будем использовать следующие библиотеки в этом проекте:

  • pandas: для манипулирования и анализа данных.
  • requests: для выполнения HTTP-запросов.
  • BeautifulSoup: для парсинга и обработки HTML-контента.
  • sentence_transformers: для загрузки предобученных моделей векторного представления предложений.
  • torch: для вычисления косинусной схожести.
  • matplotlib и seaborn: для визуализации данных.

Шаг 1: Установка и импорт необходимых библиотек

import pandas as pd
import numpy as np
import requests
from bs4 import BeautifulSoup
import torch
from sentence_transformers import SentenceTransformer
from torch.nn.functional import cosine_similarity
import matplotlib.pyplot as plt
import seaborn as sns
import re
pip install -U sentence-transformers

Шаг 2: Определение URL для парсинга объявлений о вакансиях и предоставление резюме для сравнения

# Пример ссылки
url='https://www.brightnetwork.co.uk/search/?content_types=jobs&location=london'
cv = """<текст_вашего_резюме_здесь>"""

Шаг 3: Определение серии функций для разбора веб-страницы и извлечения соответствующей информации

def parse_page(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.content, 'html.parser')
    
    # Получение описания вакансии
    job_section = soup.find('section', class_='section__description mt-5')
    job_description = job_section.get_text(strip=True) if job_section else None

    # Получение названия компании
    company_name_tag = soup.find('a', href=re.compile(r"/graduate-employer-company/"))
    company_name = company_name_tag.get_text(strip=True) if company_name_tag else None

    # Получение срока подачи заявки
    deadline_tag = soup.find('div', class_='col-md-6 field field-deadline')
    deadline = deadline_tag.find('div', class_='field-value').get_text(strip=True) if deadline_tag else None

    # Получение названия роли
    role_name_tag = soup.find('h1')
    role_name = role_name_tag.get_text(strip=True) if role_name_tag else None

    return job_description, company_name, deadline, role_name


def get_next_page_url(soup):
    pagination_container = soup.find('div', class_='pagination-container')
    if pagination_container:
        next_button = pagination_container.find_all('a')[-1]
        if "Следующая" in next_button.text and next_button['href'] != "None":
            return f"{base_url}{next_button['href']}"
    return None

def get_job_links(soup):
    job_links = []
    for link in soup.find_all('a', class_='result-link result-link-text js-ga-search-event card-link'):
        job_links.append(f"{base_url}{link['href']}")

    return job_links

Шаг 4: Парсинг информации о вакансиях со всех страниц сайта и сохранение извлеченной информации в списках

current_url = url
original_url = url
base_url = original_url.split("/search")[0]

# Парсинг информации о вакансиях со всех страниц
job_texts = []
companies=[]
roles=[]
links=[]
deadlines=[]
page = 1

while current_url:
    response = requests.get(current_url)
    soup = BeautifulSoup(response.content, 'html.parser')

    job_links = get_job_links(soup)

    for job_link in job_links:
      # Сохранение описаний вакансий
        job_texts.append(parse_page(job_link)[0])
        roles.append(parse_page(job_link)[3])
        deadlines.append(parse_page(job_link)[2])
        companies.append(parse_page(job_link)[1])
        links.append(job_link)
      
        time.sleep(1)  # Добавление задержки между запросами для избежания перегрузки сервера

    print(f"Парсинг страницы {page}")

    current_url = get_next_page_url(soup)
    
    page += 1
    time.sleep(1)  # Добавление задержки между запросами для избежания перегрузки сервера

Шаг 5: Вычисление схожести между резюме и каждым описанием вакансии с использованием косинусной схожести

# Загрузка модели BERT
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')

# Добавление функции compute_similarity() и цикла, который вычисляет оценки схожести
def compute_similarity(embedding1, embedding2):
    # Убедитесь, что векторы имеют размерность 2D тензоров
    embedding1 = embedding1.view(1, -1)
    embedding2 = embedding2.view(1, -1)
    
    # Вычисление косинусной схожести
    similarity = cosine_similarity(embedding1, embedding2)
    return similarity.item()
scores=[]
your_profile = cv
your_profile_embedding = torch.tensor(model.encode(your_profile))

for post in job_texts:
  # Определение вашего профиля и описания вакансии
  job_description_embedding = torch.tensor(model.encode(post))
  # Вычисление и вывод оценки схожести
  similarity_score = compute_similarity(your_profile_embedding, job_description_embedding)
  scores.append(similarity_score)

Шаг 6: Построение распределения оценок сходства с использованием гистограммы

# Установка темы и стиля seaborn для лучшей эстетики
sns.set_theme(style="whitegrid")
sns.set(font_scale=1.5)

# Установка размера фигуры
plt.figure(figsize=(12, 8))

# Создание гистограммы
sns.histplot(scores, bins=20, kde=True, color='royalblue', edgecolor='black')

# Установка подписей и заголовка
plt.xlabel('Оценка сходства', fontsize=16)
plt.ylabel('Частота', fontsize=16)
plt.title('Распределение оценок сходства', fontsize=20)

# Показать график
plt.show()

Шаг 7: Создание DataFrame, содержащего описания вакансий, URL-адреса, названия компаний, названия ролей, крайние сроки и оценки сходства

final_df = pd.DataFrame({'Описание вакансии': job_texts, 'URL': links,'Компания':companies,'Роль':roles,'Крайний срок':deadlines,'Оценка': scores})

Шаг 8: Сортировка DataFrame по оценкам сходства в убывающем порядке и сохранение его в виде CSV-файла

final_df = final_df.sort_values(by=['Оценка'], ascending=False)
final_df.to_csv('jobs.csv')

Шаг 9: Вывод 10 лучших описаний вакансий на основе их оценок сходства

for i in range(10):
    print(f"{i+1}. {final_df.iloc[i]['Описание вакансии']}\n")

Улучшение в будущем: использование распознавания именованных сущностей для улучшения сопоставления резюме и описания вакансии

Несмотря на мощность нашего текущего решения по сопоставлению вакансий, всегда есть место для улучшений. Многообещающим направлением для усовершенствования нашего алгоритма сопоставления является внедрение техник распознавания именованных сущностей (NER), которые могут помочь нам извлекать конкретную информацию из описаний вакансий и резюме. Таким образом, мы сможем лучше выравнивать нашу стратегию сопоставления с ключевыми факторами, такими как образование, опыт и навыки.

Вот несколько bewst practices для использования NER в сопоставлении резюме и описания вакансии:

  1. Использование предварительно обученных моделей NER: Мы можем использовать предварительно обученные модели NER, такие как SpaCy или NLTK, чтобы извлечь именованные сущности из текста резюме и описания вакансии. Это позволит нам точно определить образование, опыт работы и навыки кандидата.

  2. Создание собственных правил NER: Мы можем разработать собственные правила NER, основанные на специфических требованиях нашей платформы. Например, мы можем определить ключевые слова или фразы, связанные с требуемыми навыками, и использовать их для извлечения соответствующей информации из текста.

  3. Учет контекста: При использовании NER важно учитывать контекст, чтобы избежать неправильного определения именованных сущностей. Например, слово "Java" может быть именованной сущностью, связанной с языком программирования, или просто общим словом, описывающим остров.

  4. Комбинирование NER с семантическим сопоставлением: Мы можем комбинировать результаты NER с семантическим сопоставлением, чтобы получить более точные рекомендации по вакансиям. Например, мы можем сопоставлять не только семантическую близость между резюме и описанием вакансии, но и учитывать конкретный опыт и навыки каждого кандидата.

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