Bagi para pencari kerja, pemberi kerja, atau siapa pun yang memantau tren di pasar kerja, mengais daftar pekerjaan yang tersedia di Indeed dapat memberikan informasi yang bermanfaat. Dalam tutorial khusus ini, kita akan menggabungkan Playwright untuk scraping web dan lxml untuk penguraian konten HTML untuk mengumpulkan detail pekerjaan termasuk judul, nama perusahaan yang merekrut, lokasi, deskripsi pekerjaan, tautan lowongan pekerjaan, dan akhirnya menyajikan temuan dengan menyimpan informasi dalam file CSV.
Agar berhasil melakukan scraping, pustaka Python berikut ini perlu diinstal.
Playwright untuk otomatisasi peramban:
pip install playwright
lxml untuk mengurai HTML:
pip install lxml
panda untuk menyimpan data ke file CSV:
pip install pandas
Instal browser Playwright:
Setelah menginstal Playwright, jalankan perintah ini untuk menginstal binari peramban yang diperlukan:
playwright install
Playwright memungkinkan Anda untuk mengotomatisasi dan berinteraksi dengan peramban web. Kita mulai dengan menyiapkan Playwright untuk meluncurkan peramban Chromium, mengunjungi halaman web, dan mengekstrak kontennya. Di sini kita juga dapat memberikan proksi melalui Playwright.
Mengapa menggunakan proksi?
Situs web sering kali memiliki tindakan pembatasan kecepatan atau anti-scraping untuk memblokir permintaan berulang dari alamat IP yang sama. Proksi memungkinkan Anda untuk melakukannya:
import asyncio
from playwright.async_api import async_playwright
async def get_page_content(url):
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False,
proxy = {
'server': '',
'username': '',
'password': ''
}
) # Browser berkepala
page = await browser.new_page()
await page.goto(url)
# Mengekstrak konten halaman
content = await page.content()
await browser.close() # Tutup browser setelah selesai
return content
Dalam kode ini, async_playwright meluncurkan peramban yang dituju, menavigasi ke URL yang ditentukan, dan mengambil konten halaman.
Selanjutnya, kita akan mem-parsing konten halaman untuk mengekstrak data yang berarti. lxml digunakan untuk tujuan ini karena lxml menyediakan dukungan yang kuat untuk mem-parsing dan melakukan kueri terhadap konten HTML dengan menggunakan XPath.
from lxml import html
def parse_job_listings(content):
# Mengurai konten HTML
parser = html.fromstring(content)
# Mengekstrak setiap lowongan pekerjaan menggunakan XPath
job_posting = parser.xpath('//ul[@class="css-zu9cdh eu4oa1w0"]/li')
jobs_data = []
for element in job_posting[:-1]: # Lewati elemen terakhir jika itu adalah iklan atau tidak relevan
title = ''.join(element.xpath('.//h2/a/span/@title'))
if title:
link = ''.join(element.xpath('.//h2/a/@href'))
location = ''.join(element.xpath('.//div[@data-testid="text-location"]/text()'))
description = ', '.join(element.xpath('.//div[@class="css-9446fg eu4oa1w0"]/ul//li/text()'))
company_name = ''.join(element.xpath('.//span[@data-testid="company-name"]/text()'))
# Tambahkan data yang diekstrak ke daftar jobs_data
jobs_data.append({
'Title': title,
'Link': f"https://www.indeed.com{link}",
'Location': location,
'Description': description,
'Company': company_name
})
return jobs_data
Sekarang kita telah menyiapkan otomatisasi peramban dan langkah penguraian, mari kita gabungkan keduanya untuk mengikis daftar lowongan kerja dari halaman Indeed.
Penjelasan:
import pandas as pd
async def scrape_indeed_jobs(url):
# Langkah 1: Dapatkan konten halaman menggunakan Playwright
content = await get_page_content(url)
# Langkah 2: Mengurai HTML dan mengekstrak detail pekerjaan
jobs_data = parse_job_listings(content)
return jobs_data
# URL untuk dikikis
url = 'https://www.indeed.com/q-usa-jobs.html'
# Mengikis dan menyimpan data
async def main():
# Mengikis data pekerjaan dari URL yang ditentukan
jobs = await scrape_indeed_jobs(url)
# Langkah 3: Menyimpan data ke CSV menggunakan panda
df = pd.DataFrame(jobs)
df.to_csv('indeed_jobs.csv', index=False)
print("Data saved to indeed_jobs.csv")
# Menjalankan fungsi utama
asyncio.run(main())
Memang paginasi daftar pekerjaannya, dan Anda dapat dengan mudah memperluas scraper untuk menangani beberapa halaman. URL halaman disesuaikan dengan menggunakan parameter kueri mulai, yang bertambah 10 untuk setiap halaman baru.
Untuk meningkatkan fungsionalitas scraper Anda dalam mengumpulkan data dari beberapa halaman, Anda dapat mengimplementasikan fungsi yang disebut scrape_multiple_pages. Fungsi ini akan memodifikasi URL dasar dengan menyesuaikan parameter awal secara bertahap, sehingga memungkinkan akses ke halaman-halaman berikutnya. Dengan secara sistematis menelusuri setiap halaman, Anda dapat memperluas cakupan dan jumlah data yang dikumpulkan, seperti lowongan kerja, untuk memastikan kumpulan data yang lebih komprehensif.
async def scrape_multiple_pages(base_url, pages=3):
all_jobs = []
for page_num in range(pages):
# Perbarui URL untuk penomoran halaman
url = f"{base_url}&start={page_num * 10}"
print(f"Scraping page: {url}")
# Mengikis data pekerjaan dari setiap halaman
jobs = await scrape_indeed_jobs(url)
all_jobs.extend(jobs)
# Simpan semua pekerjaan ke CSV
df = pd.DataFrame(all_jobs)
df.to_csv('indeed_jobs_all_pages.csv', index=False)
print("Data saved to indeed_jobs_all_pages.csv")
# Mengikis beberapa halaman daftar pekerjaan
asyncio.run(scrape_multiple_pages('https://www.indeed.com/jobs?q=usa', pages=3))
Untuk menargetkan jabatan atau kata kunci pekerjaan tertentu dalam upaya pengikisan Anda, Anda perlu mengonfigurasi parameter pencarian kueri di URL yang digunakan oleh Indeed. Kustomisasi ini memungkinkan scraper untuk mengumpulkan data yang spesifik untuk pekerjaan atau sektor tertentu. Misalnya, jika Anda mencari posisi pengembang Python di http://www.indeed.com, Anda dapat menyesuaikan parameter kueri untuk menyertakan "Python+developer" atau kata kunci yang relevan.
query = "python+developer"
base_url = f"https://www.indeed.com/jobs?q={query}"
asyncio.run(scrape_multiple_pages(base_url, pages=3))
Dengan memodifikasi parameter ini sesuai dengan kebutuhan pengumpulan data Anda, Anda dapat memfokuskan penggalian pada pekerjaan tertentu, sehingga meningkatkan fleksibilitas dan efisiensi proses pengumpulan data Anda. Pendekatan ini sangat berguna untuk beradaptasi dengan permintaan pasar kerja yang dinamis.
import asyncio
from playwright.async_api import async_playwright
from lxml import html
import pandas as pd
# Langkah 1: Mengambil konten halaman menggunakan Playwright
async def get_page_content(url):
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=False
proxy = {
'server': '',
'username': '',
'password': ''
}
) # Jalankan browser dalam mode menuju
page = await browser.new_page()
await page.goto(url, wait_until='networkidle')
# Mengekstrak konten halaman
content = await page.content()
await browser.close() # Tutup browser setelah digunakan
return content
# Langkah 2: Mengurai konten HTML menggunakan lxml
def parse_job_listings(content):
# Mengurai HTML menggunakan lxml
parser = html.fromstring(content)
# Pilih lowongan pekerjaan individual menggunakan XPath
job_posting = parser.xpath('//ul[@class="css-zu9cdh eu4oa1w0"]/li')
# Ekstrak data pekerjaan
jobs_data = []
for element in job_posting[:-1]:
title = ''.join(element.xpath('.//h2/a/span/@title'))
if title:
link = ''.join(element.xpath('.//h2/a/@href'))
location = ''.join(element.xpath('.//div[@data-testid="text-location"]/text()'))
description = ', '.join(element.xpath('.//div[@class="css-9446fg eu4oa1w0"]/ul//li/text()'))
company_name = ''.join(element.xpath('.//span[@data-testid="company-name"]/text()'))
# Tambahkan data yang diekstrak ke daftar jobs_data
jobs_data.append({
'Title': title,
'Link': f"https://www.indeed.com{link}",
'Location': location,
'Description': description,
'Company': company_name
})
return jobs_data
# Langkah 3: Mengikis pekerjaan Indeed untuk satu halaman
async def scrape_indeed_jobs(url):
# Dapatkan konten halaman menggunakan Playwright
content = await get_page_content(url)
# Mengurai HTML dan mengekstrak data pekerjaan
jobs_data = parse_job_listings(content)
return jobs_data
# Langkah 4: Menangani penomoran halaman dan mengikis beberapa halaman
async def scrape_multiple_pages(base_url, query, pages=3):
all_jobs = []
for page_num in range(pages):
# Perbarui URL untuk menangani pagination dan tambahkan kueri penelusuran
url = f"{base_url}?q={query}&start={page_num * 10}"
print(f"Scraping page: {url}")
# Mengikis pekerjaan untuk halaman saat ini
jobs = await scrape_indeed_jobs(url)
all_jobs.extend(jobs)
# Menyimpan semua pekerjaan ke file CSV
df = pd.DataFrame(all_jobs)
df.to_csv(f'indeed_jobs_{query}.csv', index=False)
print(f"Data saved to indeed_jobs_{query}.csv")
# Berfungsi untuk menjalankan scraper dengan input kueri dinamis
async def run_scraper():
# Langkah 5: Minta pengguna untuk memasukkan kueri masukan dan jumlah halaman yang akan di-scraping
query = input("Enter the job title or keywords to search (e.g., python+developer): ")
pages = int(input("Enter the number of pages to scrape: "))
# Mengikis pekerjaan di beberapa halaman berdasarkan kueri
base_url = 'https://www.indeed.com/jobs'
await scrape_multiple_pages(base_url, query, pages)
# Jalankan pengikis
asyncio.run(run_scraper())
Untuk memastikan proses scraping yang lancar dan mengurangi risiko pemblokiran dan kemunculan CAPTCHA, sangat penting untuk memilih server proxy yang tepat. Pilihan paling optimal untuk scraping adalah proxy ISP, yang memberikan kecepatan tinggi dan stabilitas koneksi, serta faktor kepercayaan yang tinggi, sehingga jarang diblokir oleh platform. Jenis proxy ini bersifat statis, jadi untuk scraping skala besar, Anda perlu membuat kumpulan proxy ISP dan mengonfigurasi rotasi IP untuk perubahan reguler mereka. Pilihan alternatifnya adalah proxy perumahan, yang dinamis dan memiliki cakupan geografis terluas dibandingkan dengan jenis server proxy lainnya.
Komentar: 0