Current collected state Current
Observed since 20 Oct, 17:50 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
academic-phd-scraper
A Python module to scrape PhD offers from academicpositions.com
A Python module to scrape PhD offers from academicpositions.com.
# Clone or navigate to the project directory
cd PhDFinder
# Install dependencies
pip install -e .
# Or install dependencies directly
pip install requests beautifulsoup4
from phd_scraper import AcademicPositionsScraper, PhDPosition
# Create scraper instance
scraper = AcademicPositionsScraper()
# Get PhD positions (basic usage)
positions = scraper.get_phd_positions(max_pages=2)
# Print results
for pos in positions:
print(f"{pos.title} at {pos.university}")
print(f" Location: {pos.location}")
print(f" Deadline: {pos.deadline}")
print(f" URL: {pos.url}")
print()
# Get Computer Science PhDs in Germany
positions = scraper.get_phd_positions(
max_pages=3,
country="germany",
field="computer-science"
)
# Get Physics PhDs in Switzerland
positions = scraper.get_phd_positions(
country="switzerland",
field="physics"
)
# Search for specific keywords
positions = scraper.search_positions(
keywords=["machine learning", "deep learning", "AI"],
country="germany",
max_pages=5
)
from phd_scraper.utils import export_to_json, export_to_csv, export_to_markdown
# Get positions
positions = scraper.get_phd_positions(max_pages=2)
# Export to different formats
export_to_json(positions, "phd_positions.json")
export_to_csv(positions, "phd_positions.csv")
export_to_markdown(positions, "phd_positions.md")
# Process positions one at a time (good for large datasets)
for position in scraper.iter_positions(country="sweden"):
print(position.summary())
# Process each position without loading all into memory
# Basic usage - get 2 pages of positions
python -m phd_scraper --pages 2
# Filter by country and field
python -m phd_scraper --country germany --field computer-science
# Export to JSON
python -m phd_scraper --output positions.json --format json --pages 3
# Export to CSV
python -m phd_scraper --output positions.csv --format csv
# Search with keywords
python -m phd_scraper --keywords "machine learning" "neural networks" --pages 5
# List available filters
python -m phd_scraper --list-filters
# Fast mode (skip detailed info)
python -m phd_scraper --no-details --pages 10
# Verbose output
python -m phd_scraper --verbose --pages 1
Each PhDPosition object contains:
| Field | Description |
|---|---|
title | Position title |
university | University/employer name |
location | Full location (city, country) |
country | Country name |
city | City name |
deadline | Application deadline |
published_date | When the position was published |
job_type | Type of position (PhD) |
fields | Research fields/disciplines |
description | Full job description |
requirements | Qualifications needed |
benefits | What the position offers |
url | Link to the job posting |
apply_url | Direct application link |
scraper = AcademicPositionsScraper(
request_delay=1.5, # Delay between requests (seconds)
timeout=30, # Request timeout (seconds)
max_retries=3, # Number of retry attempts
user_agent="Custom UA" # Custom user agent string
)
from phd_scraper.utils import (
filter_positions,
deduplicate_positions,
sort_positions
)
# Filter positions
filtered = filter_positions(
positions,
keywords=["AI", "robotics"],
countries=["germany", "switzerland"],
has_deadline=True
)
# Remove duplicates
unique = deduplicate_positions(positions)
# Sort by field
sorted_pos = sort_positions(positions, by="deadline")
[1] PhD Position in AI and Strategy
University: ETH Zürich
Location: Zurich, Switzerland
Deadline: Unspecified
Fields: Business Administration, Management, Artificial Intelligence
URL: https://academicpositions.com/ad/eth-zurich/2026/...
[2] Doctoral student in Radiofrequency ranging for Lunar orbits
University: KTH Royal Institute of Technology
Location: Stockholm, Sweden
Deadline: 2026-01-31 (Europe/Stockholm)
Fields: Physics, Space Science
URL: https://academicpositions.com/ad/kth-royal-institute-of-technology/2025/...
MIT License
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
requestsEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | requests>=2.28.0 | runtime |
beautifulsoup4Environment{
"extras": "",
"marker": null,
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | beautifulsoup4>=4.11.0 | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | pytest>=7.0.0; extra == "dev" | runtime |
pytest-covEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | pytest-cov>=4.0.0; extra == "dev" | runtime |
blackEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | black>=23.0.0; extra == "dev" | runtime |
ruffEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.8",
"evaluation": "NOT_EVALUATED"
} | ruff>=0.1.0; extra == "dev" | runtime |
bdist_wheel · 14.12 KB · Python py3
sdist · 12.43 KB · Python source
Observed since 20 Oct, 17:50 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:a7fbfc6cf62dbc50a9c53c458118af71d6205faac3e21c87eef06bb6314d74cc