Skip to main content

ResuMesh Scrapers Banner

resumesh-scrapers

Enterprise-Grade, Standalone, and Decoupled Web Scraping Engines for Portfolio Building

PyPI version Python versions License CI Status


resumesh-scrapers is a clean, modular, and robust Python library containing standalone scraping services for GitHub, Dev.to, Medium, Substack, Behance, NPM, PyPI, and YouTube platforms. Originally developed as part of the ResuMesh ecosystem, it has been decoupled to serve as a reusable package for any resume, portfolio, or profile aggregator project.

🚀 Key Features

  • Robust Core Network Engine: Centralized HTTP request handling with standard retry mechanisms powered by tenacity and structured logging.
  • Fully Decoupled Models: Independent, clean data validation using pydantic v2, keeping data structures separated from database constraints.
  • Extensible Architecture: Platform scrapers are isolated in a plug-and-play layout under platforms/ allowing quick addition of new integrations (e.g. LinkedIn, GitLab).
  • Detailed Exceptions: Standardized exceptions hierarchy inheriting from ScraperError with HTTP status code details.

🛠️ Installation

pip install resumesh-scrapers

For Local Development (Editable mode)

git clone https://github.com/AtaCanYmc/resumesh-scrapers.git
cd resumesh-scrapers
pip install -e .

💡 Quick Start

Here is a simple example showing how to scrape your repository, blog statistics, and YouTube videos:

import asyncio
from resumesh_scrapers import (
    GitHubScraper,
    DevToScraper,
    MediumScraper,
    SubstackScraper,
    BehanceScraper,
    YouTubeScraper,
    GitHubRepositoryModel,
    GitHubCommitModel,
    GitHubUserModel,
    DevToArticleModel,
    MediumEntryModel,
    SubstackEntryModel,
    BehanceProjectModel,
    YouTubeVideoModel,
)

async def main():
    # 1. Scraping GitHub Repositories, README Repos, Commits, and User Lists
    github = GitHubScraper()
    repos: list[GitHubRepositoryModel] = await github.fetch_data(
        username="octocat",
        pat="ghp_...",  # optional PAT token to bypass rate limit
        include_forks=False
    )
    print(f"Fetched {len(repos)} repositories.")

    # Fetch profile README repository details
    readme_repo = await github.fetch_readme_repo("octocat")
    if readme_repo:
        print(f"Profile README Repository: {readme_repo.html_url}")

    # Fetch recent commits (default since: last 7 days)
    commits: list[GitHubCommitModel] = await github.fetch_commits("octocat")
    print(f"Fetched {len(commits)} commits.")

    # Fetch followers and following list
    followers: list[GitHubUserModel] = await github.fetch_followers("octocat", per_page=10)
    print(f"Fetched {len(followers)} followers.")


    # 2. Scraping Dev.to Articles
    devto = DevToScraper()
    devto_posts: list[DevToArticleModel] = await devto.fetch_data("atacanymc")
    print(f"Fetched {len(devto_posts)} Dev.to articles.")

    # 3. Scraping Substack Publications
    substack = SubstackScraper()
    substack_posts: list[SubstackEntryModel] = await substack.fetch_data("atacan")
    print(f"Fetched {len(substack_posts)} Substack posts.")

    # 4. Scraping Behance Projects
    behance = BehanceScraper()
    behance_projects: list[BehanceProjectModel] = await behance.fetch_data(
        username="atacanymc",
        api_key="your_behance_api_key"  # optional, falls back to HTML scraping if not provided
    )
    print(f"Fetched {len(behance_projects)} Behance projects.")

    # 5. Scraping YouTube Video Metadata
    youtube = YouTubeScraper()
    video_data: YouTubeVideoModel = await youtube.fetch_video("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
    print(f"Fetched YouTube video: {video_data.title} ({video_data.view_count:,} views)")

if __name__ == "__main__":
    asyncio.run(main())

🗺️ Clean Architecture

The codebase has been refactored to enforce separation of concerns, decoupling models, platforms, and network layers:

src/resumesh_scrapers/
├── core/                       # Shared network and utility systems
│   ├── client.py               # Central HTTP requester with tenacity retries
│   └── __init__.py
├── platforms/                  # Individual platform scrapers
│   ├── github.py
│   ├── devto.py
│   ├── medium.py
│   ├── substack.py
│   ├── behance.py
│   ├── npm.py
│   ├── pypi.py
│   ├── youtube.py
│   └── __init__.py
└── models/                     # Platform-specific Pydantic validation schemas
    ├── github.py
    ├── devto.py
    ├── medium.py
    ├── substack.py
    ├── behance.py
    ├── npm.py
    ├── pypi.py
    ├── youtube.py
    └── __init__.py

📊 Models & Capabilities

Platform Scraper Class Response Model Captured Data Features
GitHub GitHubScraper GitHubRepositoryModel
GitHubCommitModel
GitHubUserModel
Repos: Stars, Forks, languages, watchers.
Commits: author, message, sha, repo, date, HTML link.
Users: login, avatar URL, HTML link (followers/following).
Dev.to DevToScraper DevToArticleModel Title, URL, Tags, Reading time, Publishing date
Medium MediumScraper MediumEntryModel Title, RSS Summary, UTM-stripped link, Category tags
Substack SubstackScraper SubstackEntryModel Title, RSS Summary, link, tags
Behance BehanceScraper BehanceProjectModel Project title, gallery URL, appreciation count, publication dates (supports API client keys)
NPM NpmScraper NpmSearchResultModel Maintainer packages, keywords, version history, publisher metadata
PyPI PyPIScraper PyPiPackageModel Releases, download statistics, license, project metadata
YouTube YouTubeScraper YouTubeVideoModel Video title, duration, view count, like count, comment count, channel info, thumbnail, tags, categories (via yt-dlp)

⚠️ Exception Handling

All scraper exceptions inherit from ScraperError to simplify integration errors:

from resumesh_scrapers.exceptions import ScraperError, GitHubScraperError

try:
    repos = await github_scraper.fetch_data("some_username")
except GitHubScraperError as e:
    print(f"GitHub API Error: {e.message} (HTTP {e.status_code})")
except ScraperError as e:
    print(f"Generic Scraping Exception: {e}")

🤝 Contributing

We welcome contributions to add more platforms (such as LinkedIn, GitLab, or Dribbble) or optimize parsers. Please open a Pull Request or file an issue to discuss your ideas!

  1. Fork the Project.
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature).
  3. Commit your Changes (git commit -m 'Add some AmazingFeature').
  4. Push to the Branch (git push origin feature/AmazingFeature).
  5. Open a Pull Request.

📄 License

Distributed under the Apache 2.0 License. See LICENSE for more information.

Metadata

Release files for resumesh-scrapers 0.9.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for resumesh-scrapers 0.9.0
File Size Uploaded Provenance Actions
resumesh_scrapers-0.9.0.tar.gz 37.9 kB With provenance Details for resumesh_scrapers-0.9.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for resumesh-scrapers 0.9.0
File Interpreter ABI Platform Actions
resumesh_scrapers-0.9.0-py3-none-any.whl Python 3 none any Details for resumesh_scrapers-0.9.0-py3-none-any.whl

Total release size: 71.3 kB

Release files / resumesh_scrapers-0.9.0.tar.gz

Download URL resumesh_scrapers-0.9.0.tar.gz
Size 37.9 kB
Tags Source
SHA-256 checksum
How to use checksums
ba4df0809cd9249a078f1f54b097a622201c9de2d25ab17010c4896e7f6cefa1
BLAKE2b-256 checksum
How to use checksums
af1d97309994e6e441fb79440df46679c93f8a9ad3dc0d959e896b84bd8447f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.

Transparency log

Release files / resumesh_scrapers-0.9.0-py3-none-any.whl

Download URL resumesh_scrapers-0.9.0-py3-none-any.whl
Size 33.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2cff284c87ecc46b89170d6d9302d5c3cc9c7346ea11b50abd8721eb0a88c5a5
BLAKE2b-256 checksum
How to use checksums
264af463f55812f4180798475c7c7a24b70ea096111bda44172c4f6e3b860e8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.

Transparency log

Security for resumesh-scrapers 0.9.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for resumesh_scrapers-0.9.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page