Google Jobs tekee ilmoituksia dynaamisesti ja lokalisoi tulokset, joten naiivit HTTP -pyynnöt palauttavat harvoin käyttökelpoiset tiedot. Luotettavin lähestymistapa on käyttää kaavintasovellusliittymää, joka käsittelee JavaScriptin renderointia ja geokohdistusta, ja jäsentä sitten vain tarvitsemasi kentät CSV: hen.
Mitä rakennat:
- CSV -tiedostot kyselyä kohden ja sijainti työnimike, yritys, sijainti, päivämäärä, palkka, lähde ja jaa URL -osoite.
- Skaalautuva putkilinja, joka suorittaa useita kyselyjä samanaikaisesti useiden geo-paikalla.
Menetelmä 1 - Oxylabs Web Scraper API (asynkroninen, skaalautuva)
Oxylabs 'Web Scraper API (Google Jobs -lähde) suorittaa päättömät selaimet geokohdistuksella ja mukautetulla jäsentäjällä, joten saat jäsennellyt kentät RAW HTML: n sijasta.
Mitä tarvitset
- Oksylabs -tilin ja API -käyttäjän käyttöoikeustiedot (käyttäjänimi/salasana). Luo tili OxyLabs -kojetaulussa, aloita ilmainen kokeilu ja kopioi sovellusliittymän käyttäjä ja salasana kojelaudan käyttöoikeustieto -sivulta.
- Python 3.11+ koneessasi.
Vaihe 1:Luo oksylabs -tili ja kopioi sovellusliittymän käyttäjänimi ja salasana kojelaudasta (oksylabs).
Vaihe 2:Asenna Python 3.11 tai uudempi järjestelmään, jos sitä ei ole vielä asennettu.
Vaihe 3:Asenna vaadittavat kirjastot Async -kaavinta varten.
pip install aiohttp asyncio pandasVaihe 4:Luo tiedosto nimeltäpayload.jsonGoogle -työpaikkojen (oksylabs räätälöity jäsentäjä) sääntöjen jäsenten kanssa.
{
"source": "google",
"url": null,
"geo_location": null,
"user_agent_type": "desktop",
"render": "html",
"parse": true,
"parsing_instructions": {
"jobs": {
"_fns": [
{ "_fn": "xpath", "_args": ["//div[@class="nJXhWc"]//ul/li"] }
],
"_items": {
"job_title": { "_fns": [{ "_fn": "xpath_one", "_args": [".//div[@class="BjJfJf PUpOsf"]/text()"] }] },
"company_name": { "_fns": [{ "_fn": "xpath_one", "_args": [".//div[@class="vNEEBe"]/text()"] }] },
"location": { "_fns": [{ "_fn": "xpath_one", "_args": [".//div[@class="Qk80Jf"][1]/text()"] }] },
"date": { "_fns": [{ "_fn": "xpath_one", "_args": [".//div[@class="PuiEXc"]//span[@class="LL4CDc" and contains(@aria-label, 'Posted')]/span/text()"] }] },
"salary": { "_fns": [{ "_fn": "xpath_one", "_args": [".//div[@class="PuiEXc"]//div[contains(@class,'I2Cbhb') and contains(@class,'bSuYSc')]//span[@aria-hidden='true']/text()"] }] },
"posted_via": { "_fns": [{ "_fn": "xpath_one", "_args": [".//div[@class="Qk80Jf"][2]/text()"] }] },
"URL": { "_fns": [{ "_fn": "xpath_one", "_args": [".//div[@data-share-url]/@data-share-url"] }] }
}
}
}
}Vaihe 5:Luo nimeltä python -tiedostojobs_oxylabs.py.
Vaihe 6:Liitä tuonti ja kuormitustiedot (oksylabs).
import asyncio
import aiohttp
import json
import pandas as pd
from aiohttp import ClientSession, BasicAuth
# Replace with your Oxylabs API username/password from the dashboard
OXY_USER = "USERNAME"
OXY_PASS = "PASSWORD"
credentials = BasicAuth(OXY_USER, OXY_PASS)
# Load parsing payload
with open("payload.json", "r") as f:
PAYLOAD = json.load(f)Vaihe 7:Lisää auttajatoiminnot työn, kyselyn tilan ja noutamisen tulosten (oksylabs push-pull-päätepiste) lähettämiseksi.
async def submit_job(session: ClientSession, payload: dict) -> str:
async with session.post("https://data.oxylabs.io/v1/queries", auth=credentials, json=payload) as resp:
data = await resp.json()
return data["id"]
async def check_status(session: ClientSession, job_id: str) -> str:
async with session.get(f"https://data.oxylabs.io/v1/queries/{job_id}", auth=credentials) as resp:
data = await resp.json()
return data["status"]
async def fetch_jobs(session: ClientSession, job_id: str) -> list:
async with session.get(f"https://data.oxylabs.io/v1/queries/{job_id}/results", auth=credentials) as resp:
data = await resp.json()
return data["results"][0]["content"]["jobs"]Vaihe 8:Lisää toiminto jäsennettyjen työpaikkojen kirjoittamiseen CSV: hen kyselyä kohti ja sijainti.
Liittyvät:Kuinka ajaa python -skripti Dockerin avulla
async def save_csv(query: str, location: str, jobs: list) -> None:
rows = []
for j in jobs:
rows.append({
"Job title": j.get("job_title"),
"Company name": j.get("company_name"),
"Location": j.get("location"),
"Date": j.get("date"),
"Salary": j.get("salary"),
"Posted via": j.get("posted_via"),
"URL": j.get("URL"),
})
df = pd.DataFrame(rows)
filename = f"{query}_jobs_{location.replace(',', '_').replace(' ', '_')}.csv"
await asyncio.to_thread(df.to_csv, filename, index=False)Vaihe 9:Määritä Coroutiini, joka asettaa Google Jobsin URL-osoitteen ja maantieteellisen sijainnin, toimittaa työn, odottaa valmistumista ja säästää tuloksia (oksylabs).
async def scrape_jobs(session: ClientSession, query: str, country_code: str, location: str) -> None:
url = f"https://www.google.com/search?q={query}&ibp=htl;jobs&hl=en&gl={country_code}"
PAYLOAD["url"] = url
PAYLOAD["geo_location"] = location
job_id = await submit_job(session, PAYLOAD)
# Give the backend time to render before polling
await asyncio.sleep(12)
while True:
status = await check_status(session, job_id)
if status == "done":
break
if status == "failed":
print(f"Job {job_id} failed for {query} @ {location}.")
return
await asyncio.sleep(5)
jobs = await fetch_jobs(session, job_id)
await save_csv(query, location, jobs)Vaihe 10:Lisätämain()suorittaa useita kyselyjä ja sijainteja samanaikaisesti.
URL_QUERIES = ["developer", "chef", "manager"]
LOCATIONS = {
"US": ["California,United States", "Virginia,United States", "New York,United States"],
"GB": ["United Kingdom"],
"DE": ["Germany"]
}
async def main():
async with aiohttp.ClientSession() as session:
tasks = []
for cc, locs in LOCATIONS.items():
for loc in locs:
for q in URL_QUERIES:
tasks.append(asyncio.ensure_future(scrape_jobs(session, q, cc, loc)))
await asyncio.gather(*tasks)
if __name__ == "__main__":
asyncio.run(main())
print("Completed.")Vaihe 11:Suorita komentosarja ja tarkista, että CSV -tiedostot luodaan kyselyä ja sijaintia kohti.
Huomautuksia:
- Google Jobs Ostral URL -osoitteet voivat avata vain IP: stä samassa maassa, jota käytetään kaavin aikana; Käytä vastaavaa välityspalvelinta/VPN: tä avaamalla ne.
- Käyttää
Ctrl+Shift+IWindowsissa taiOption+Command+IMacOS: lla tarkastaa valintalaitteet, jos haluat laajentaa jäsentämistä.
Menetelmä 2 - Serpapi Google Jobs API (yksinkertainen lepo, suodattimet ja säde)
Serpapigoogle_jobsMoottorin palauttaa jäsennellyt ilmoitukset valinnaisilla suodattimilla, kuten kieli, maa ja säde.
Mitä tarvitset
- Serpapi -tili ja API -avain. Rekisteröidy osoitteeseen serpapi.com, avaa kojelauta ja kopioi sovellusliittymän avain “API -avain” -sivulta.
- Python 3.9+ ja
requestsjapandaspaketit.
Vaihe 1:Luo SerPAPI -tili ja kopioi sovellusliittymän avain kojelaudasta (SerPAPI).
Vaihe 2:Asenna riippuvuudet.
pip install requests pandasVaihe 3:Lähetä ensimmäinen Google Jobs -pyyntösi ja kirjoita tulokset CSV: lle (SerPAPI).
import requests
import pandas as pd
API_KEY = "YOUR_SERPAPI_KEY"
params = {
"engine": "google_jobs",
"q": "developer new york",
"hl": "en",
"gl": "us",
"api_key": API_KEY,
# Optional: radius in kilometers (Google may not strictly enforce)
"lrad": 25
}
r = requests.get("https://serpapi.com/search.json", params=params)
r.raise_for_status()
data = r.json()
rows = []
for j in data.get("jobs_results", []):
rows.append({
"Job title": j.get("title"),
"Company name": j.get("company_name"),
"Location": j.get("location"),
"Posted via": j.get("via"),
"Share link": j.get("share_link"),
"Description": j.get("description")
})
pd.DataFrame(rows).to_csv("jobs_serpapi.csv", index=False)Vaihe 4:Sivuta käyttämällänext_page_tokenVastauksesta ylimääräisten sivujen hakemiseen (serpapi).
def fetch_all(params):
out = []
while True:
res = requests.get("https://serpapi.com/search.json", params=params).json()
out.extend(res.get("jobs_results", []))
token = res.get("serpapi_pagination", {}).get("next_page_token")
if not token:
break
params["next_page_token"] = token
return out
jobs = fetch_all(params)Vinkit:
- Käyttää
locationtaiuulesimuloida kaupunkitason hakuja; Vältä yhdistämällä molemmat samassa pyynnössä. - Suodattimet voivat saapua
udsjouset JSON: ssa; Käytä suodattimen uudelleenudsarvo uudessa tulosten tarkentamispyynnössä.
Menetelmä 3 - Ilmainen paikallinen kaavin seleenillä (paras pienille testeille)
Päättömä selain voi vierittää Google Jobs -luetteloa ja purkaa kentät vankilla valintalaitteilla. Tämä on käytännöllinen prototyyppien suhteen, mutta vaatii ylläpitoa ja voi lyödä anti-bot-järjestelmiä tilavuudella.
Mitä tarvitset
- Google Chrome ja vastaava Chromedriver binaarinen.
- Python 3.9+
selenium-beautifulsoup4(valinnainen) japandas.
Vaihe 1:Lataa Chromedriver, joka vastaa Chrome -versiota ja lisää sen polullesi.
Vaihe 2:Asenna seleeni ja pandat.
pip install selenium pandasVaihe 3:Käynnistä Chrome vaihtoehto, joka vähentää automaation sormenjälkiä.
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--window-size=1920,1080")
options.add_argument("--disable-blink-features=AutomationControlled")
driver = webdriver.Chrome(options=options)Vaihe 4:Avaa kyselystä ja maakoodista rakennetun Google Jobs -URL -osoitteen.
query = "developer"
country = "us"
url = f"https://www.google.com/search?q={query}&ibp=htl;jobs&hl=en&gl={country}"
driver.get(url)Vaihe 5:Vieritä työluettelon säilöä ladataksesi lisää tuloksia.
import time
from selenium.webdriver.common.by import By
loaded = 0
while True:
cards = driver.find_elements(By.XPATH, "//div[@class="nJXhWc"]//ul/li")
if len(cards) == loaded:
break
loaded = len(cards)
driver.execute_script("arguments[0].scrollIntoView({block: 'end'});", cards[-1])
time.sleep(1.5)Vaihe 6:Uuteta vakaa kentät XPathilla; Käytä kuvakepohjaisia valittajia lähetettyyn päivämäärään ja palkkaan, kun ne ovat saatavilla.
from selenium.common.exceptions import NoSuchElementException
rows = []
for li in driver.find_elements(By.XPATH, "//div[@class="nJXhWc"]//ul/li//div[@role="treeitem"]/div/div"):
def txt(xp):
try:
return li.find_element(By.XPATH, xp).get_attribute("innerText")
except NoSuchElementException:
return None
def attr(xp, name):
try:
return li.find_element(By.XPATH, xp).get_attribute(name)
except NoSuchElementException:
return None
rows.append({
"Job title": txt("./div[2]"),
"Company name": txt("./div[4]/div/div[1]"),
"Location": txt("./div[4]/div/div[2]"),
"Source": txt("./div[4]/div/div[3]"),
"Posted": txt(".//*[name()='path'][contains(@d,'M11.99')]/ancestor::div[1]"),
"Full/Part": txt(".//*[name()='path'][contains(@d,'M20 6')]/ancestor::div[1]"),
"Salary": txt(".//*[name()='path'][@fill-rule="evenodd"]/ancestor::div[1]"),
"Logo src": attr("./div[1]//img", "src")
})Vaihe 7:Tallenna poimitut tiedot CSV: ksi.
import pandas as pd
pd.DataFrame(rows).to_csv("jobs_selenium.csv", index=False)VAROITUS:
- Odottaa asettelun muutoksia; Revalidoi valittajia määräajoin.
- Kaasupyynnöt ja kunnioittavat sivuston ehtoja lohkojen välttämiseksi.
Lähestymistavan valitseminen
Tuotantoa ja mittakaavaa varten Oxylabsin Async -putkilinja palauttaa luotettavasti jäsennettyjä työpaikkoja monien kyselyjen ja paikkojen välillä vähentäen tekniikan aikaa ja vikoja. Serpapi integroidaan nopeasti pienempiin skripteihin ja antaa sinun lisätä säde- ja suodatinmerkkejä. Seleeni on paras nopeisiin kokeisiin tai kun et voi käyttää kolmannen osapuolen sovellusliittymää.
Nopea ylläpitovinkki: Pidä kyselyluetteloita ja sijaintiansanoja erillisissä JSON- tai YAML-tiedostoissa, jotta muut kuin kehittäjät voivat päivittää hakualueita koskettamatta koodia.













