Created
March 8, 2025 02:47
-
-
Save sagunsh/28e927c0407dcb26c65c68572b963312 to your computer and use it in GitHub Desktop.
Monitor jobs on seek
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# author: sagunsh | |
# description: monitor jobs on seek.com.au | |
# requires: python 3.6+ | |
# | |
# Usage | |
# help: python seek_monitoring.py --help | |
# print to console: python seek_monitoring.py --keyword="software engineer" | |
# save to csv (50 jobs): python seek_monitoring.py --keyword="software engineer" --max=50 --csv | |
# todo: send email | |
import argparse | |
import json | |
import csv | |
import urllib.parse | |
import urllib.request | |
BASE_URL = 'https://www.seek.com.au/' | |
SEARCH_PATH = '/api/jobsearch/v5/search' | |
def get_response(url, max_retries=10): | |
retry = 0 | |
headers = { | |
'accept': 'application/json, text/plain, */*', | |
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36', | |
} | |
while retry < max_retries: | |
try: | |
req = urllib.request.Request(url, headers=headers) | |
with urllib.request.urlopen(req, timeout=30) as response: | |
return response.read().decode() | |
except: | |
pass | |
retry += 1 | |
def search_jobs(keyword, max_count): | |
if not isinstance(keyword, str) or len(keyword) == 0: | |
return [] | |
if not isinstance(max_count, int) or max_count <= 0 or max_count > 100: | |
max_count = 25 | |
params = { | |
'page': '1', | |
'keywords': keyword, | |
'pageSize': max_count, | |
'sortmode': 'KeywordRelevance', # or 'ListedDate' | |
} | |
search_url = urllib.parse.urljoin(BASE_URL, SEARCH_PATH + '?' + urllib.parse.urlencode(params)) | |
try: | |
response = get_response(search_url) | |
jobs = json.loads(response).get('data', []) | |
except: | |
jobs = [] | |
results = [] | |
for job in jobs: | |
job_dict = { | |
'title': job.get('title'), | |
'url': 'https://www.seek.com.au/job/' + job.get('id'), | |
'company': job.get('advertiser').get('description'), | |
'posted_on': job.get('listingDate').split('T')[0], | |
'salary': job.get('salaryLabel'), | |
} | |
results.append(job_dict) | |
return results | |
def generate_html_table(data): | |
if len(data) == 0: | |
return '<p>No data available</p>' | |
headers = data[0].keys() | |
html = '<table border="1" cellspacing="0" cellpadding="5" style="border-collapse: collapse;">' | |
html += '<tr>' | |
for header in headers: | |
if header != 'url': | |
html += f'<th style="background-color: #f2f2f2; padding: 8px; text-align: left;">{header.title()}</th>' | |
html += '</tr>' | |
for row in data: | |
html += '<tr>' | |
for key in headers: | |
if key == 'title': | |
html += f'<td style="padding: 8px;"><a href="{row["url"]}" target="_blank">{row[key]}</a></td>' | |
elif key == 'url': | |
continue | |
else: | |
html += f'<td style="padding: 8px;">{row[key]}</td>' | |
html += '</tr>' | |
html += '</table>' | |
return html | |
def save_to_csv(data): | |
if len(data) == 0: | |
return False | |
file_name = f'seek_jobs.csv' | |
with open(file_name, 'w') as csvfile: | |
writer = csv.DictWriter(csvfile, fieldnames=jobs[0].keys()) | |
writer.writeheader() | |
writer.writerows(jobs) | |
return file_name | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser(description='Monitor seek jobs') | |
parser.add_argument('--keyword', help='Search keyword', default='python developer') | |
parser.add_argument('--max', help='Max number of jobs', default=25, type=int) | |
parser.add_argument('--csv', help='Save output to CSV file', action='store_true') | |
parser.add_argument('--email', help='Send email', action='store_true') | |
args = parser.parse_args() | |
print(f'searching for {args.keyword} jobs') | |
jobs = search_jobs(keyword=args.keyword, max_count=args.max) | |
if args.csv: | |
file_name = save_to_csv(jobs) | |
if file_name: | |
print(f'Saved to {file_name}') | |
else: | |
print('No data available') | |
if args.email: | |
html_table = generate_html_table(jobs) | |
html = f'<html lang="en"><body style="font-family:Tahoma">{html_table}</body></html>' | |
print(html) | |
print('\n\nTodo: Send email to myself') | |
if not args.csv and not args.email: | |
for job in jobs: | |
print(job) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment