Heim > Artikel > Backend-Entwicklung > So erstellen Sie mit Crawlee einen LinkedIn-Job-Scraper in Python
In diesem Artikel erstellen wir eine Webanwendung, die LinkedIn mit Crawlee und Streamlit nach Stellenausschreibungen durchsucht.
Wir werden mit Crawlee für Python einen LinkedIn-Job-Scraper in Python erstellen, um den Firmennamen, die Berufsbezeichnung, den Zeitpunkt der Veröffentlichung und den Link zur Stellenausschreibung aus dynamisch empfangenen Benutzereingaben über die Webanwendung zu extrahieren.
Hinweis
Eines unserer Community-Mitglieder hat diesen Blog als Beitrag zum Crawlee Blog geschrieben. Wenn Sie solche Blogs zum Crawlee-Blog beitragen möchten, kontaktieren Sie uns bitte auf unserem Discord-Kanal.
Am Ende dieses Tutorials verfügen Sie über eine voll funktionsfähige Webanwendung, mit der Sie Stellenausschreibungen von LinkedIn extrahieren können.
Lasst uns beginnen.
Beginnen wir mit der Erstellung eines neuen Crawlee for Python-Projekts mit diesem Befehl:
pipx run crawlee create linkedin-scraper
Wählen Sie PlaywrightCrawler im Terminal aus, wenn Crawlee danach fragt.
Nach der Installation erstellt Crawlee für Python Boilerplate-Code für Sie. Sie können das Verzeichnis (cd) in den Projektordner ändern und diesen Befehl ausführen, um Abhängigkeiten zu installieren.
poetry install
Wir werden mit der Bearbeitung der uns von Crawlee bereitgestellten Dateien beginnen, damit wir unseren Scraper erstellen können.
Hinweis
Bevor Sie fortfahren, wenn Sie diesen Blog gerne lesen, würden wir uns sehr freuen, wenn Sie Crawlee für Python einen Stern auf GitHub geben würden!Starken Sie uns auf GitHub ⭐️
In diesem Abschnitt erstellen wir den Scraper mit dem Crawlee for Python-Paket. Um mehr über Crawlee zu erfahren, schauen Sie sich die Dokumentation an.
Öffnen Sie LinkedIn in Ihrem Webbrowser und melden Sie sich von der Website ab (wenn Sie bereits über ein Konto angemeldet sind). Sie sollten eine Schnittstelle wie diese sehen.
Navigieren Sie zum Abschnitt „Jobs“, suchen Sie nach einem Job und Standort Ihrer Wahl und kopieren Sie die URL.
Sie sollten so etwas haben:
https://www.linkedin.com/jobs/search?keywords=Backend Developer&location=Canada&geoId=101174742&trk=public_jobs_jobs-search-bar_search-submit&position=1&pageNum=0
Wir konzentrieren uns auf die Suchparameter, das ist der Teil, der nach „?“ steht. Die Schlüsselwort- und Standortparameter sind für uns die wichtigsten.
Die vom Benutzer angegebene Berufsbezeichnung wird in den Schlüsselwortparameter eingegeben, während der vom Benutzer angegebene Standort in den Standortparameter eingegeben wird. Zuletzt wird der geoId-Parameter entfernt, während die anderen Parameter konstant bleiben.
Wir werden Änderungen an unserer main.py-Datei vornehmen. Kopieren Sie den folgenden Code und fügen Sie ihn in Ihre main.py-Datei ein.
from crawlee.playwright_crawler import PlaywrightCrawler from .routes import router import urllib.parse async def main(title: str, location: str, data_name: str) -> None: base_url = "https://www.linkedin.com/jobs/search" # URL encode the parameters params = { "keywords": title, "location": location, "trk": "public_jobs_jobs-search-bar_search-submit", "position": "1", "pageNum": "0" } encoded_params = urlencode(params) # Encode parameters into a query string query_string = '?' + encoded_params # Combine base URL with the encoded query string encoded_url = urljoin(base_url, "") + query_string # Initialize the crawler crawler = PlaywrightCrawler( request_handler=router, ) # Run the crawler with the initial list of URLs await crawler.run([encoded_url]) # Save the data in a CSV file output_file = f"{data_name}.csv" await crawler.export_data(output_file)
Nachdem wir die URL codiert haben, besteht der nächste Schritt für uns darin, den generierten Router für die Verarbeitung von LinkedIn-Stellenausschreibungen anzupassen.
Wir werden zwei Handler für Ihre Anwendung verwenden:
Der default_handler verarbeitet die Start-URL
Der job_listing-Handler extrahiert die einzelnen Jobdetails.
Der Playwright-Crawler durchsucht die Seite mit den Stellenausschreibungen und extrahiert die Links zu allen Stellenausschreibungen auf der Seite.
Wenn Sie die Stellenausschreibungen untersuchen, werden Sie feststellen, dass sich die Links zu Stellenausschreibungen in einer geordneten Liste mit einer Klasse namens jobs-search__results-list befinden. Anschließend extrahieren wir die Links mithilfe des Playwright-Locator-Objekts und fügen sie zur Verarbeitung zur Route „job_listing“ hinzu.
router = Router[PlaywrightCrawlingContext]() @router.default_handler async def default_handler(context: PlaywrightCrawlingContext) -> None: """Default request handler.""" #select all the links for the job posting on the page hrefs = await context.page.locator('ul.jobs-search__results-list a').evaluate_all("links => links.map(link => link.href)") #add all the links to the job listing route await context.add_requests( [Request.from_url(rec, label='job_listing') for rec in hrefs] )
Da wir nun die Stellenausschreibungen haben, besteht der nächste Schritt darin, deren Details zu extrahieren.
Wir extrahieren den Titel jeder Stelle, den Firmennamen, den Zeitpunkt der Veröffentlichung und den Link zur Stellenanzeige. Öffnen Sie Ihre Entwicklungstools, um jedes Element mithilfe seines CSS-Selektors zu extrahieren.
Nachdem wir alle Einträge gelöscht haben, entfernen wir Sonderzeichen aus dem Text, um ihn zu bereinigen, und verschieben die Daten mithilfe der Funktion context.push_data in den lokalen Speicher.
@router.handler('job_listing') async def listing_handler(context: PlaywrightCrawlingContext) -> None: """Handler for job listings.""" await context.page.wait_for_load_state('load') job_title = await context.page.locator('div.top-card-layout__entity-info h1.top-card-layout__title').text_content() company_name = await context.page.locator('span.topcard__flavor a').text_content() time_of_posting= await context.page.locator('div.topcard__flavor-row span.posted-time-ago__text').text_content() await context.push_data( { # we are making use of regex to remove special characters for the extracted texts 'title': re.sub(r'[\s\n]+', '', job_title), 'Company name': re.sub(r'[\s\n]+', '', company_name), 'Time of posting': re.sub(r'[\s\n]+', '', time_of_posting), 'url': context.request.loaded_url, } )
For this project, we will be using Streamlit for the web application. Before we proceed, we are going to create a new file named app.py in your project directory. In addition, ensure you have Streamlit installed in your global Python environment before proceeding with this section.
import streamlit as st import subprocess # Streamlit form for inputs st.title("LinkedIn Job Scraper") with st.form("scraper_form"): title = st.text_input("Job Title", value="backend developer") location = st.text_input("Job Location", value="newyork") data_name = st.text_input("Output File Name", value="backend_jobs") submit_button = st.form_submit_button("Run Scraper") if submit_button: # Run the scraping script with the form inputs command = f"""poetry run python -m linkedin-scraper --title "{title}" --location "{location}" --data_name "{data_name}" """ with st.spinner("Crawling in progress..."): # Execute the command and display the results result = subprocess.run(command, shell=True, capture_output=True, text=True) st.write("Script Output:") st.text(result.stdout) if result.returncode == 0: st.success(f"Data successfully saved in {data_name}.csv") else: st.error(f"Error: {result.stderr}")
The Streamlit web application takes in the user's input and uses the Python Subprocess package to run the Crawlee scraping script.
Before we test the application, we need to make a little modification to the __main__ file in order for it to accommodate the command line arguments.
import asyncio import argparse from .main import main def get_args(): # ArgumentParser object to capture command-line arguments parser = argparse.ArgumentParser(description="Crawl LinkedIn job listings") # Define the arguments parser.add_argument("--title", type=str, required=True, help="Job title") parser.add_argument("--location", type=str, required=True, help="Job location") parser.add_argument("--data_name", type=str, required=True, help="Name for the output CSV file") # Parse the arguments return parser.parse_args() if __name__ == '__main__': args = get_args() # Run the main function with the parsed command-line arguments asyncio.run(main(args.title, args.location, args.data_name))
We will start the Streamlit application by running this code in the terminal:
streamlit run app.py
This is what your application what the application should look like on the browser:
You will get this interface showing you that the scraping has been completed:
To access the scraped data, go over to your project directory and open the CSV file.
You should have something like this as the output of your CSV file.
In this tutorial, we have learned how to build an application that can scrape job posting data from LinkedIn using Crawlee. Have fun building great scraping applications with Crawlee.
You can find the complete working Crawler code here on the GitHub repository..
Follow Crawlee for more content like this.
Thank you!
Das obige ist der detaillierte Inhalt vonSo erstellen Sie mit Crawlee einen LinkedIn-Job-Scraper in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!