Код для этого проекта можно найти в репозитории Github https://github.com/klameer/jobscrape.git вместе с инструкциями о том, как быстро приступить к работе.

Как ИТ-подрядчик и фрилансер, я провожу много времени, следя за досками объявлений о вакансиях на случай, если появится подходящая возможность. А бирж с вакансиями очень много. Я составил список из 10 мест, которые мне нужно посещать хотя бы раз в неделю. Это в основном ручной процесс. Вы можете ускорить его с помощью ниндзюцу браузера и сочетаний клавиш, но мне повезет, если я посещу все 10 сайтов за один раз.

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

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

Это решение будет извлекать данные с двух основных сайтов вакансий: Monster.com и Total Jobs. Затем этот процесс можно использовать для создания дополнительных рабочих мест в будущем. Решение будет искать роли аналитика данных и объединять всю эту информацию на одной странице, которую можно просматривать на досуге.

Цель — одна страница, на которой есть все данные, которые вы ищете.

Библиотеки

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

  1. Запросы Python. Простой способ загрузки веб-страниц. Поскольку доступ к веб-страницам может быть закодирован, это отлично подходит для нашего требования доступа к нескольким веб-страницам и сбора их содержимого.
  2. Красивый суп. HTML-текст на веб-страницах длинный и беспорядочный, и не существует элегантного способа обхода HTML-файла. Так было до тех пор, пока не появился Beautiful Soup. Он дает вам полезный набор функций, которые превращают страницу в иерархию объектов, доступную в коде.
  3. Питонская колба. Минималистичный веб-фреймворк, который гордится тем, что он максимально легкий. Нам нужно отобразить результаты нашего консолидированного набора данных в интерактивном формате. Flask — самый быстрый способ сделать это.
  4. TinyDB. Решение объединяет данные, которые нужно где-то хранить. В Python есть несколько способов сделать это. TinyDB — это база данных документов, которая хорошо работает с объектами словаря Python.
  5. Начальная загрузка. Популярный фреймворк для разработки внешнего интерфейса веб-приложений. Вы можете быстро приступить к работе с хорошо оформленными веб-страницами.
  6. Таблицы данных jQuery. Отличный способ отображения табличных данных на веб-странице. Он превращает обычную таблицу в нечто удивительное с готовыми функциями табуляции и поиска.
  7. Регулярные выражения (повторно). Регулярные выражения — это способ поиска закономерностей в тексте. Как только шаблоны найдены, ими можно манипулировать, например заменять и удалять значения. Регулярные выражения отлично подходят для очистки данных в нужный вам формат.
  8. дата и время. Модуль datetime — это комплексное решение для работы с датами. Это полезно при попытке выяснить последние вакансии, размещенные на сайте.

Загрузка данных

Двумя самыми популярными досками объявлений в Великобритании являются Monster и Total Jobs. Во многих случаях вакансии, размещенные на этих досках, не уникальны и могут одновременно находиться на нескольких досках. Здесь агентства публикуют вакансии на нескольких сайтах или вакансии на одних сайтах размещаются на других. Решение ищет определенные рабочие места (аналитики данных), и причина, по которой были выбраны эти два сайта, заключается в том, что между ними не так много дублирования рабочих мест.

И Monster, и Total Jobs выполняют свои запросы о работе как ссылку. Это известно как запрос GET, где ссылка определяет список отображаемых заданий. Рабочий процесс для загрузки данных будет заключаться в создании ссылки для отображения интересующего типа вакансий и использовании содержимого этой страницы для создания сводного списка вакансий. Ссылки, как правило, не меняются со временем, поэтому это разовый процесс, который необходимо выполнять для каждой доски объявлений.

Вывод веб-страницы осуществляется в формате HTML, и без библиотеки Beautiful Soup Python трудно найти, какие элементы вы ищете, и извлечь из них текст. Monster и Total Jobs построены по-разному, поэтому HTML-элементы для каждого из них будут отличаться друг от друга.

Начните с загрузки библиотек, общих для обоих сайтов.

import requests
import bs4 as bs
import re
import datetime
today = datetime.datetime.now().strftime("%Y-%m-%d")

Монстр

Зайдите на сайт Монстр и выполните поиск нужной роли. Что я обычно ищу, так это роли анализа данных контракта. Роли контракта, как правило, имеют другой URL-адрес.

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

url = 'https://www.monster.co.uk/jobs/search/Contract_8?q=Data-Analyst&where=london&sort=dt.rv.di'
final = []
resp = requests.get(url)
soup = bs.BeautifulSoup(resp.text, "lxml")
jobs = soup.find("section", {"id":"resultsWrapper"}).find_all("article", {"class":"js_result_row"})
for job in jobs:
    job_title = job.find("div", {"class":"jobTitle"}).find("a").text
    job_link = job.find("div", {"class":"jobTitle"}).find("a").get("href")
    job_title = re.sub("\n|\r", "", job_title)
    job_date = job.find("time").get("datetime")
    job_date = datetime.datetime.strptime(job_date, "%Y-%m-%dT%H:%M").strftime("%Y-%m-%d")
    row = {"source":"monster", "title": job_title, "link": job_link, "time":job_date}
    if job_date == today:
        final.append(row)

Всего рабочих мест

То же самое относится и к Total Jobs. Разница в том, что нет конкретной даты, по которой вы можете фильтровать. Глядя на веб-страницу, вакансии, опубликованные в текущий день, говорят, что они были опубликованы «Сегодня». Это то, что будет фильтроваться.

url = "https://www.totaljobs.com/jobs/contract/data-analyst"
resp = requests.get(url)
soup = bs.BeautifulSoup(resp.text, "lxml")
jobs = []
results  = soup.find_all("div", {"class":"job-title"})
for result in results:
    job_title = result.find("a").text
    job_title = re.sub("\n", "", job_title)
    job_link = result.find("a").get("href")
    job = {"source":"totaljobs", "title":job_title, "link":job_link}
    jobs.append(job)
results  = soup.find_all("div", {"class":"detail-body"})
i = 0
for result in results:
    job_date = result.find("li", {"class", "date-posted"}).text
    job_date = re.sub(" +|\n", "", job_date)
    jobs[i]["time"] = job_date
    i += 1
final = []
for job in jobs:
    if job['time'] == 'Today':
        final.append(job)

Объединить наборы данных

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

db = TinyDB("myfile.json")
db.purge()
for job in get_monster():
    db.insert(job)
for job in get_total_jobs():
    db.insert(job)

TinyDB — удобная база данных документов. Это отличный способ управления неструктурированными данными, такими как объекты, свойства которых отличаются друг от друга. Сериализация объектов — это процесс преобразования объектов в формат, который можно сохранить. В Python есть много способов сделать это, наиболее популярным из которых является Pickle, где вы можете сохранять и извлекать объекты любого типа. Pickle можно использовать для решения проблем с хранилищем, но TinyDB отлично подходит для документов JSON. Веб-страницы и их ссылки будут храниться в виде документов JSON, поскольку их легко отображать в этом формате.

Отображать на веб-странице

Как упоминалось ранее, самый быстрый способ начать работу с веб-приложением на Python — это использовать Flask. Микрофреймворк дает вам базовую функциональность, и вы можете решить, какие другие библиотеки вы хотите подключить к своему решению. Приложение Flask будет иметь две функции. Один для отображения главной страницы, а другой для извлечения данных и их отображения в виде API.

from flask import Flask
from flask import render_template
from tinydb import TinyDB
import json
app = Flask(__name__)
@app.route("/")
def index():
    return render_template("index.html")
@app.route("/data")
def data():
    db = TinyDB("myfile.json")
    data = db.all()
    ret_val = {"data" : data}
    return json.dumps(ret_val)

Начальная загрузка

В Bootstrap есть стартовый шаблон. Как только это будет вставлено в ваш файл index.html, у вас будут все стили Bootstrap. Стандартные стили Bootstrap для большинства элементов HTML, включая таблицу, в которой отображаются консолидированные данные.

Таблицы данных JavaScript

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

Библиотека DataTables зависит от библиотеки jQuery, что означает, что ее необходимо загрузить после загрузки jQuery. Шаблон Bootstrap уже загружает библиотеку jQuery, что делает ее доступной на странице.

<table id="table_id" class="table table-striped table-bordered" style="width:100%">
    <thead>
        <tr>
            <th>source</th>
            <th>title</th>
        </tr>
    </thead>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.js"></script>
$(document).ready( function () {
    $('#table_id').DataTable({
      "ajax":"/data",
      "columns":[
        {"data":"source"},
        {"data": "title",
          "fnCreatedCell": function(nTd, sData, oData, iRow, iCol){
            $(nTd).html("<a href='" + oData.link + "'>" + oData.title + "</a>");
          }}]});});

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

Следующие шаги

Это простое решение, которое можно использовать в качестве шаблона, на котором можно строить. Что я хотел бы добавить в будущем, так это следующую функциональность.

  1. Обязательно привлеките другие сайты вакансий к использованию того же процесса, чтобы обеспечить более широкий охват вакансий.
  2. Уметь вводить несколько условий поиска. В настоящее время он ищет только аналитиков данных, но тот же процесс можно адаптировать для поиска любых других типов вакансий, отображаемых на веб-сайте.
  3. Создайте облако слов из наиболее часто используемых релевантных слов в описаниях вакансий. Это может помочь настроить ваше резюме, чтобы убедиться, что оно включает слова, которые ищут работодатели.

[Эта статья была опубликована в блоге findpatterns.]