Glassdoor — еще один популярный портал вакансий, где многие соискатели могут найти работу своей мечты. Зачистка стеклянной двери может дать вам некоторое представление, например, о том, какую зарплату следует ожидать при приеме на работу. Работодатели могут парсить Glassdoor, чтобы улучшить свою стратегию найма, сравнивая данные со своими конкурентами.

В этой статье мы собираемся использовать Python для извлечения сообщений о вакансиях из Glassdoor. В конце этого руководства вы сможете извлечь данные из Glassdoor и сохранить их в файле CSV.

Настройка предварительных условий

Для этой статьи нам понадобится python 3.x, и я предполагаю, что вы уже установили его на свой компьютер. Наряду с этим нам необходимо загрузить сторонние библиотеки, такие как BeautifulSoup, Selenium и хромовый драйвер.

  • BeautifulSoup — Это поможет нам разобрать необработанный HTML и извлечь нужные данные. Он также известен как BS4.
  • Selenium — Это поможет нам отображать веб-сайты Javascript.
  • Chromium — это веб-драйвер, используемый Selenium для управления браузером Chrome.

Вот как вы будете их устанавливать

pip install selenium
pip install beautifulsoup4

Наряду с этим вам нужно будет создать специальную папку, в которой вы будете хранить файл сценария. Кроме того, создайте файл python внутри этой папки. Я назову его glassdoor.py

mkdir glass

Что мы соскоблим с Glassdoor?

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

  1. Название компании
  2. Должность
  3. Расположение
  4. Зарплата

Сначала мы собираемся извлечь необработанный HTML с веб-сайта с помощью Selenium, а затем мы собираемся использовать методы .find() и .find_all() BS4 для анализа этих данных из необработанного HTML.

Chromium будет использоваться совместно с Selenium для загрузки веб-сайта.

Выскабливание стеклянной двери

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

from bs4 import BeautifulSoup
from selenium import webdriver
import time

PATH = 'C:\Program Files (x86)\chromedriver.exe'


l=list()
o={}

target_url = "https://www.glassdoor.com/Job/new-york-python-jobs-SRCH_IL.0,8_IC1132348_KO9,15.htm?clickSource=searchBox"

driver=webdriver.Chrome(PATH)

driver.get(target_url)

driver.maximize_window()
time.sleep(2)

resp = driver.page_source

driver.close()

Теперь позвольте мне объяснить вам, что мы сделали здесь шаг за шагом.

  1. Мы импортировали библиотеки, которые были установлены ранее в этой статье.
  2. Затем мы объявили PATH, где установлен наш драйвер хрома.
  3. Также объявляются пустой список и пустой объект для хранения данных задания.
  4. target_url содержит URL-адрес целевой страницы Glassdoor.
  5. Затем мы создали экземпляр, используя метод .Chrome.
  6. Используя метод .get(), мы пытаемся подключиться к целевой веб-странице. Chromium загрузит эту страницу.
  7. Используя .maximize_window(), мы увеличиваем размер хромированного окна до максимального размера.
  8. Затем мы используем метод .sleep(), чтобы дождаться закрытия экземпляра chrome. Это поможет нам полностью загрузить сайт.
  9. Затем с помощью .page_source мы собираем весь необработанный HTML-код страницы.
  10. Затем, наконец, мы закрываем экземпляр хрома, используя метод .close(), предоставляемый Selenium API.

После запуска этого кода он должен открыть экземпляр Chrome, загрузить страницу и закрыть браузер. Если это тоже произойдет с вашим сценарием, тогда мы можем двигаться дальше. Наша основная установка готова.

Одна вещь, которую вы заметите, это то, что все эти задания находятся под ul tag с классом hover p-0 my-0 css-7ry9k1 exy0tjh5. Итак, мы должны сначала найти этот класс. Мы будем использовать метод .find() BS4, чтобы найти этот тег внутри нашего DOM.

allJobsContainer = soup.find("ul",{"class":"css-7ry9k1"})

allJobs = allJobsContainer.find_all("li")

Используя метод .find(), мы ищем ul tag, а затем, используя метод .find_all(), мы ищем все li tags внутри ul tag.

Теперь мы можем использовать цикл for для доступа ко всем 30 вакансиям, доступным на странице.

Одна вещь, которую вы можете заметить, это то, что иногда Glassdoor показывает вам страницу без вакансий. Все, что вам нужно сделать, это очистить файлы cookie и повторить попытку.

Теперь давайте найдем расположение каждого целевого элемента один за другим.

Как видите, название компании можно найти под div tag с классом d-flex justify-content-between align-items-start. Давайте выделим его из необработанного HTML с помощью BS4.

for job in allJobs:
    try:
        o["name-of-company"]=job.find("div",{"class":"d-flex justify-content-between align-items-start"}).text
    except:
        o["name-of-company"]=None

    l.append(o)

    o={}

Теперь давайте найдем название работы.

Вы можете найти этот тег в a tag с классом jobLink css-1rd3saf eigr9kq2. Давайте используем ту же технику, чтобы найти это.

try:
    o["name-of-job"]=job.find("a",{"class":"jobLink css-1rd3saf eigr9kq2"}).text
except:
    o["name-of-job"]=None

На изображении выше вы можете видеть, что местоположение хранится в div tag с классом d-flex flex-wrap css-11d3uq0 e1rrn5ka2.

try:
    o["location"]=job.find("div",{"class":"d-flex flex-wrap css-11d3uq0 e1rrn5ka2"}).text
except:
    o["location"]=None

Последнее, что осталось, это зарплата, а это самая важная часть по понятным причинам😜.

Вы можете видеть на изображении выше, что информацию о зарплате можно найти в разделе div tag с классом css-3g3psg pr-xxsm.

try:
    o["salary"]=job.find("div",{"class":"css-3g3psg pr-xxsm"}).text
except:
    o["salary"]=None


l.append(o)
o={}

В конце концов, мы вставили object o внутрь list l. Затем мы объявили объект o empty.

Как только вы запустите и напечатаете list l, вы получите эти результаты.

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

Давайте сохраним эти данные в файл CSV

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

Во-первых, давайте установим pandas.

pip install pandas

Затем импортируйте это в наш основной файл сценария glassdoor.py.

import pandas as pd

Теперь, используя метод DataFrame, мы собираемся преобразовать наш list l в формат строки и столбца. Затем, используя метод .to_csv(), мы собираемся преобразовать DataFrame в файл CSV.

df = pd.DataFrame(l)
df.to_csv('jobs.csv', index=False, encoding='utf-8')

Вы можете добавить эти две строки, как только ваш list l будет готов со всеми данными. После запуска программы вы получите CSV-файл с именем jobs.csv в своей корневой папке.

Разве это не просто? Вы смогли быстро очистить данные и сохранить их в CSV-файл.

Полный код

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

from bs4 import BeautifulSoup
from selenium import webdriver
import time
import pandas as pd

PATH = 'C:\Program Files (x86)\chromedriver.exe'


l=list()
o={}

target_url = "https://www.glassdoor.com/Job/new-york-python-jobs-SRCH_IL.0,8_IC1132348_KO9,15.htm?clickSource=searchBox"

driver=webdriver.Chrome(PATH)

driver.get(target_url)

driver.maximize_window()
time.sleep(2)

resp = driver.page_source
driver.close()

soup=BeautifulSoup(resp,'html.parser')

allJobsContainer = soup.find("ul",{"class":"css-7ry9k1"})

allJobs = allJobsContainer.find_all("li")

for job in allJobs:
    try:
        o["name-of-company"]=job.find("div",{"class":"d-flex justify-content-between align-items-start"}).text
    except:
        o["name-of-company"]=None

    try:
        o["name-of-job"]=job.find("a",{"class":"jobLink css-1rd3saf eigr9kq2"}).text
    except:
        o["name-of-job"]=None


    try:
        o["location"]=job.find("div",{"class":"d-flex flex-wrap css-11d3uq0 e1rrn5ka2"}).text
    except:
        o["location"]=None


    try:
        o["salary"]=job.find("div",{"class":"css-3g3psg pr-xxsm"}).text
    except:
        o["salary"]=None

    l.append(o)

    o={}

print(l)

df = pd.DataFrame(l)
df.to_csv('jobs.csv', index=False, encoding='utf-8')

Код простой, аккуратный и понятный.

Что делать, если вы хотите очистить все страницы?

Если вы хотите собрать все задания со всех страниц из Glassdoor, вы сначала заметите шаблоны URL.

Первая страница — https://www.glassdoor.com/Job/new-york-python-jobs-SRCH_IL.0,8_IC1132348_KO9,15.htm?includeNoSalaryJobs=true

Вторая страница — https://www.glassdoor.com/Job/new-york-python-jobs-SRCH_IL.0,8_IC1132348_KO9,15_IP2.htm?includeNoSalaryJobs=true&pgc=AB4AAYEAHgAAAAAAAAAAAAAAAAfkQ90AAUgEBAQgW%2Fr3vuIzCm5wwBSi I3WKjWOqbueSQvnI%2BGizAAsjV8NiAL80nAjkvw3vucgztbs4IIrkoqerQ462C14jLJVNRIV0ihlakU7p20hMXIG4AAA%3D%3D

Третья страница — https://www.glassdoor.com/Job/new-york-python-jobs-SRCH_IL.0,8_IC1132348_KO9,15_IP3.htm?includeNoSalaryJobs=true&pgc=AB4AAoEAPAAAAAAAAAAAAAAAAAAAfkQ90AAdwEBAQtEzo8VunEQLF8uBoWr%2BRn CsnMFj0JNOLbRUXIkLkFAzjjZlKDW1axVwiTVV%2BbXo8%2BX471WNF8IEWPMdAwCPhbzQe1T1HHMEVPYFwQLM8h1NnGMDPcEwo7tpQ7XL65R7DMDR26n0NhBU7lFGCODAwxNTsJRAAA%3D

Как видите, в приведенных выше URL-адресах нет общего шаблона, кроме этой части — https://www.glassdoor.com/Job/new-york-python-jobs-SRCH_IL.0,8_IC1132348_KO9,15 . Но это бесполезно, если вы хотите очистить другие страницы. Итак, единственное решение — использовать метод .click(), предоставляемый Selenium API. Используя метод .click(), мы собираемся нажать следующую кнопку, прокручивая вниз.

Сначала прокрутите, а затем нажмите.

Итак, вот как вы собираетесь прокручивать страницу вниз на любой странице Glassdoor.

scrolling_element= driver.find_element_by_xpath("//*[@id='MainCol']")
driver.execute_script('arguments[0].scrollTop = arguments[0].scrollHeight', scrolling_element)

С помощью .find_element_by_xpath() мы находим столбец, в котором хранятся все задания.

После того, как вы прокрутите этот элемент вниз, вы должны найти кнопку и нажать на нее.

Вы должны найти его, используя тот же метод селена .find_element_by_xpath(). И, наконец, вы должны использовать метод .click(), чтобы щелкнуть его. Это приведет вас к следующей странице.

time.sleep(3)
driver.find_element_by_xpath('//*[@id="MainCol"]/div[2]/div/div[1]/button[7]').click()
time.sleep(3)

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

Но при парсинге Glassdoor может ограничить ваш поиск и ограничить ваш IP-адрес. В этом случае вы должны использовать Web Scraping API. Давайте посмотрим, как вы можете избежать блокировки с помощью API веб-скрейпинга, такого как Scrapingdog.

Избегайте блокировки с помощью Scrapingdog

Вы должны зарегистрировать бесплатную учетную запись, чтобы начать ее использовать. Вам понадобится всего 10 секунд, чтобы начать работу со Scrapingdog.

После того, как вы зарегистрируетесь, вы будете перенаправлены на вашу панель управления. Приборная панель будет выглядеть примерно так.

Вы должны использовать свой собственный ключ API.

Теперь вы можете вставить ссылку на целевую страницу Glassdoor слева, а затем выбрать JS Rendering как Нет. После этого нажмите Копировать код справа. Теперь используйте этот API в своем скрипте Python для очистки Glassdoor.

Вы заметите, что код останется таким же, как и выше. Нам просто нужно изменить одну вещь, и это наш целевой URL.

from bs4 import BeautifulSoup
from selenium import webdriver
import time
import pandas as pd

PATH = 'C:\Program Files (x86)\chromedriver.exe'

l=list()
o={}

target_url = "https://api.scrapingdog.com/scrape?api_key=xxxxxxxxxxxxxxxxxxxxxxxx&url=https://www.glassdoor.com/Job/new-york-python-jobs-SRCH_IL.0,8_IC1132348_KO9,15_IP3.htm?includeNoSalaryJobs=true&pgc=AB4AAoEAPAAAAAAAAAAAAAAAAfkQ90AAdwEBAQtEzo8VunEQLF8uBoWr%2BRnCsnMFj0JNOLbRUXIkLkFAzjjZlKDW1axVwiTVV%2BbXo8%2BX471WNF8IEWPMdAwCPhbzQe1T1HHMEVPYFwQLM8h1NnGMDPcEwo7tpQ7XL65R7DMDR26n0NhBU7lFGCODAwxNTsJRAAA%3D&dynamic=false"

driver=webdriver.Chrome(PATH)

driver.get(target_url)

driver.maximize_window()
time.sleep(2)

resp = driver.page_source
driver.close()

soup=BeautifulSoup(resp,'html.parser')

allJobsContainer = soup.find("ul",{"class":"css-7ry9k1"})

allJobs = allJobsContainer.find_all("li")

for job in allJobs:
    try:
        o["name-of-company"]=job.find("div",{"class":"d-flex justify-content-between align-items-start"}).text
    except:
        o["name-of-company"]=None

    try:
        o["name-of-job"]=job.find("a",{"class":"jobLink css-1rd3saf eigr9kq2"}).text
    except:
        o["name-of-job"]=None

    try:
        o["location"]=job.find("div",{"class":"d-flex flex-wrap css-11d3uq0 e1rrn5ka2"}).text
    except:
        o["location"]=None

    try:
        o["salary"]=job.find("div",{"class":"css-3g3psg pr-xxsm"}).text
    except:
        o["salary"]=None

    l.append(o)

    o={}

print(l)

df = pd.DataFrame(l)
df.to_csv('jobs.csv', index=False, encoding='utf-8')

Как видите, мы заменили целевой URL-адрес Glassdoor на URL-адрес API Scrapingdog. Вы должны использовать свой собственный ключ API, чтобы успешно запустить этот скрипт.

С помощью этого скрипта вы сможете очищать Glassdoor с молниеносной скоростью, не будучи заблокированным.

Заключение

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

Конечно, я бы порекомендовал Web Scraping API, если вы планируете парсить его в больших масштабах. С обычным скриптом без ротации прокси вы будете заблокированы в кратчайшие сроки, и ваш конвейер данных застрянет. Для извлечения миллионов таких сообщений вы всегда можете использовать Scrapingdog.

Надеюсь, вам понравился этот небольшой урок, и если да, то не забудьте поделиться им с друзьями и в социальных сетях.

Дополнительные ресурсы

Вот несколько дополнительных ресурсов, которые могут оказаться полезными во время изучения веб-страниц: