Leaderboard github.com
D4Vinci/Scrapling
🕷️ The BEST Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
AI provenance
1%
explicit
- Confidence
- 95%
- Coverage
- 100%
Estimated share of AI-generated code. Explicit attribution is a lower bound.
Code quality
74/100
adequate
- Confidence
- 90%
- Coverage
- 100%
Complexity, duplication, lint density, tests, CI, docs and review process.
Security
55/100
weak
- Confidence
- 85%
- Coverage
- 100%
Secrets, static analysis, vulnerable dependencies, CI and supply-chain posture.
AI provenance
1% explicit
Explicit AI attribution on 1% of first-party code added; an estimated 1% including velocity signals.
How the score is built
- Explicitly attributed share1%
- Unattributed share in AI-pace bursts19%
- Estimated AI-generated share1%
- AI tool configuration files0
- Work sessions at AI pace5
- Releases at AI pace0
- Coding-style index (1.0+ means possible)0.00
Attributed AI tools
| Tool | Commits | Lines added | First seen | Last seen |
|---|---|---|---|---|
| Claude Code | 8 | 430 | 2026-03-15 | 2026-09-24 |
| OpenAI Codex | 10 | 43 | 2026-10-16 | 2026-11-02 |
Lines added per month all AI-attributed share
- 2024-103,157 · 0% AI
- 2024-112,449 · 0% AI
- 2024-121,954 · 0% AI
- 2025-01292 · 0% AI
- 2025-02123 · 0% AI
- 2025-03609 · 0% AI
- 2025-043,110 · 0% AI
- 2025-051,993 · 0% AI
- 2025-063,313 · 0% AI
- 2025-071,795 · 0% AI
- 2025-083,085 · 0% AI
- 2025-092,216 · 0% AI
- 2025-102,360 · 0% AI
- 2025-111,378 · 0% AI
- 2025-12691 · 0% AI
- 2026-014,479 · 0% AI
- 2026-022,810 · 0% AI
- 2026-031,952 · 18% AI
- 2026-046,187 · 1% AI
- 2026-051,476 · 0% AI
- 2026-06534 · 5% AI
- 2026-072,044 · 0% AI
- 2026-083,382 · 0% AI
- 2026-0910,334 · 0% AI
- 2026-1010,543 · 0% AI
- 2026-111,318 · 3% AI
Findings in AI-attributed lines vs the rest
From git blame: 15 lines trace to AI-attributed commits, 16,646 to others. Too few lines in one group for a fair comparison. Reported, not scored.
| Findings per 1,000 lines | AI-attributed | Other | Ratio |
|---|---|---|---|
| Code quality | 0.00 | 0.54 | — |
| Security | 0.00 | 0.42 | — |
Evidence by analyzer
Explicit AI attributionok20 items
- OpenAI Codex: 10 attributed commits, 43 lines added
- Claude Code: 8 attributed commits, 430 lines added
- OpenAI Codex: PR branch 'codex/fix-template-gzip-errors'
- OpenAI Codex: trailer 'Co-authored-by: Codex'
- OpenAI Codex: trailer 'Co-authored-by: Codex'
- OpenAI Codex: trailer 'Co-authored-by: Codex'
- OpenAI Codex: trailer 'Co-authored-by: Codex'
- OpenAI Codex: trailer 'Co-authored-by: Codex'
- OpenAI Codex: trailer 'Co-authored-by: Codex'
- OpenAI Codex: trailer 'Co-authored-by: Codex'
- OpenAI Codex: trailer 'Co-authored-by: Codex'
- OpenAI Codex: trailer 'Co-authored-by: Codex'
- Claude Code: PR description attribution
- Claude Code: trailer 'Co-Authored-By: Claude'
- Claude Code: trailer 'Co-Authored-By: Claude'
- Claude Code: trailer 'Co-Authored-By: Claude'
- Claude Code: trailer 'Co-Authored-By: Claude'
- Claude Code: trailer 'Co-Authored-By: Claude'
- Claude Code: trailer 'Co-Authored-By: Claude'
- Claude Code: trailer 'Co-Authored-By: Claude'
- attributed_commit_share
- 1.1%
- attributed_commits
- 18
- attributed_loc
- 473
- attributed_loc_share
- 0.6%
- commits
- 1,580
- effective_loc
- 73,584
- tools_detected
- 2
AI tool configurationok
- artifacts
- 0
- tools_configured
- 0
- workflow_agents
- 0
Commit velocityok5 items
- 3,169 lines of first-party code in ~1.7h (1,816 lines/hour, 3 commit session)
- 1,841 lines of first-party code in ~2.2h (845 lines/hour, 4 commit session)
- 3,731 lines of first-party code in ~4.8h (777 lines/hour, 5 commit session)
- 2,683 lines of first-party code in ~4.0h (663 lines/hour, 2 commit session)
- 2,297 lines of first-party code in ~4.0h (574 lines/hour, 1 commit session)
- excluded_import_loc
- 2,158
- flagged_loc
- 13,721
- flagged_loc_share
- 19.2%
- flagged_units
- 5
- max_loc_per_hour
- 1,815.76
- measured_loc
- 71,426
- median_loc_per_hour
- 86.52
- pr_timed_units
- 44
- pre_ai_era_burst_loc
- 0
- pre_ai_era_bursts
- 0
- pre_ai_era_measured_loc
- 0
- work_units
- 472
Release velocityok
- flagged_releases
- 0
- max_loc_per_day
- 601.20
- releases
- 54
Coding styleok
- count:assistant_voice
- 0
- count:emoji_in_code
- 0
- count:narrated_steps
- 0
- count:placeholder
- 0
- files:assistant_voice
- 0
- files:emoji_in_code
- 0
- files:narrated_steps
- 0
- files:placeholder
- 0
- index
- 0
- lines_scanned
- 16,661
- per_kloc:assistant_voice
- 0
- per_kloc:emoji_in_code
- 0
- per_kloc:narrated_steps
- 0
- per_kloc:placeholder
- 0
Findings in AI-written linesok
- ai_lines
- 15
- blame_failures
- 0
- files_blamed
- 69
- other_lines
- 16,646
- quality:ai_findings
- 0
- quality:ai_per_kloc
- 0
- quality:other_findings
- 9
- quality:other_per_kloc
- 0.54
- security:ai_findings
- 0
- security:ai_per_kloc
- 0
- security:other_findings
- 7
- security:other_per_kloc
- 0.42
Code quality
74 adequate
Code quality is adequate: test-to-source ratio 1.63, CI runs tests; 21% of function code in complex or long functions; 10% duplicated lines. Weakest area: type safety.
How the score is built
- Complexity53
- Duplication54
- Lint and smells85
- Tests and CI100
- Documentation100
- Type safety0
- Review processnot measured
Evidence by analyzer
Complexity (lizard)ok10 items
- _cloudflare_solver in scrapling/engines/_browsers/_stealth.py: complexity 37, 95 lines
- _cloudflare_solver in scrapling/engines/_browsers/_stealth.py: complexity 37, 100 lines
- _run_actions in scrapling/core/ai/_browser_actions.py: complexity 35, 91 lines
- parse in scrapling/core/shell.py: complexity 34, 115 lines
- find_all in scrapling/parser.py: complexity 33, 67 lines
- from_playwright_response in scrapling/engines/toolbelt/convertor.py: complexity 27, 74 lines
- from_async_playwright_response in scrapling/engines/toolbelt/convertor.py: complexity 27, 74 lines
- fetch in scrapling/engines/_browsers/_stealth.py: complexity 22, 78 lines
- fetch in scrapling/engines/_browsers/_stealth.py: complexity 22, 78 lines
- crawl in scrapling/spiders/engine.py: complexity 22, 72 lines
- complex_functions
- 22
- function_nloc
- 6,952
- functions
- 580
- long_functions
- 2
- many_param_functions
- 22
- mean_ccn
- 3.78
- p90_ccn
- 8
- risky_nloc_share
- 21.2%
Duplication (jscpd)ok10 items
- 6+ duplicated lines: agent-skill/Scrapling-Skill/examples/01_fetcher_session.py:20 and agent-skill/Scrapling-Skill/examples/02_browser_session.py:20
- 6+ duplicated lines: agent-skill/Scrapling-Skill/examples/02_browser_session.py:18 and agent-skill/Scrapling-Skill/examples/03_stealthy_session.py:18
- 6+ duplicated lines: scrapling/__init__.py:26 and scrapling/fetchers/__init__.py:35
- 6+ duplicated lines: scrapling/cli.py:241 and scrapling/cli.py:295
- 6+ duplicated lines: scrapling/core/ai/server.py:288 and scrapling/core/ai/server.py:818
- 6+ duplicated lines: scrapling/core/custom_types.py:127 and scrapling/core/custom_types.py:138
- 6+ duplicated lines: scrapling/core/custom_types.py:246 and scrapling/parser.py:1314
- 6+ duplicated lines: scrapling/engines/_browsers/_base.py:49 and scrapling/engines/_browsers/_base.py:258
- 6+ duplicated lines: scrapling/engines/_browsers/_network.py:48 and scrapling/engines/_browsers/_network.py:60
- 6+ duplicated lines: scrapling/engines/_browsers/_remote.py:25 and scrapling/engines/_browsers/_remote.py:54
- compared_lines
- 13,663
- duplicated_lines
- 1,418
- duplicated_share
- 10.4%
- files
- 69
Lintok
- category:best-practice
- 5
- category:maintainability
- 4
- findings
- 9
- scanned_lines
- 16,661
- weighted_findings
- 11
Tests and CIok7 items
- CI config: .github/workflows/code-quality.yml
.github/workflows/code-quality.yml - CI config: .github/workflows/docker-build.yml
.github/workflows/docker-build.yml - CI config: .github/workflows/release-and-publish.yml
.github/workflows/release-and-publish.yml - CI config: .github/workflows/stale.yml
.github/workflows/stale.yml - CI config: .github/workflows/tests.yml
.github/workflows/tests.yml - CI runs tests (tox)
- CI runs linters (ruff, mypy, pyright, pre-commit)
- check:ci_present
- yes
- check:ci_runs_lint
- yes
- check:ci_runs_tests
- yes
- check:has_tests
- yes
- check:test_ratio
- yes
- check:tests_cochange
- yes
- ci_files
- 5
- cochange_commits
- 158
- cochange_share
- 75.3%
- source_lines
- 16,661
- test_lines
- 27,193
- test_ratio
- 1.63
Documentationok4 items
- README.md
README.md - LICENSE
LICENSE - CONTRIBUTING.md
CONTRIBUTING.md - docs/changelog.md
docs/changelog.md
- check:changelog
- yes
- check:contributing
- yes
- check:license
- yes
- check:readme
- yes
- readme_lines
- 527
Type safetyok
- check:low_escape_density
- no
- check:strict_config
- no
- escapes
- 233
- escapes_per_kloc
- 14.00
Security
55 weak
Security posture is weak: 3 known vulnerabilities in 1 dependencies; 5 high-severity SAST findings; 22 high-severity workflow issues. Weakest area: posture.
How the score is built
- Secrets67
- Static analysis (SAST)85
- Vulnerable dependencies78
- CI workflows1
- Security posture0
- OpenSSF Scorecardnot measured
Evidence by analyzer
OpenSSF Scorecardskipped
no published OpenSSF Scorecard result for this repo
Package registriesok
- checked
- 26
- declared
- 26
- lookup_errors
- 0
- missing
- 0
- recent
- 0
Secrets (gitleaks)ok
- secrets_current
- 0
- secrets_history
- 0
- secrets_low_confidence
- 0
- secrets_nonprod
- 12
Static analysis (opengrep)ok
- findings
- 9
- findings_high
- 5
- findings_low
- 0
- findings_medium
- 4
- parse_errors
- 1
- scanned_lines
- 16,661
- weighted_findings
- 7.55
Dependencies (osv-scanner)ok
- penalty
- 15
- vulnerabilities
- 3
- vulnerable_packages
- 1
- vulns_critical
- 1
- vulns_high
- 2
- vulns_low
- 0
- vulns_medium
- 0
- vulns_unknown
- 0
CI workflows (zizmor)ok
- findings
- 33
- findings_high
- 22
- findings_low
- 9
- findings_medium
- 2
- penalty
- 270
- workflows
- 5
Security postureok
- check:dependency_updates
- no
- check:lockfiles
- yes
- check:security_policy
- no
- check:signed_commits
- no
- signed_commit_share
- 20.5%
- unpinned_manifests
- 0
Release downloadsok
- binary_assets
- 0
- signals
- 0
- suspicious
- 0
Findings
1 critical30 high14 medium16 low5 info
| Severity | Rule | Location | Message | Tool |
|---|---|---|---|---|
| critical | osv/PYSEC-2026-2120 |
docs/requirements.txt | [email protected] (PyPI) is affected by PYSEC-2026-2120 | Dependencies (osv-scanner) |
| high | opengrep/python.lang.maintainability.useless-inner-function |
scrapling/spiders/engine.py:468 | function `run` is defined inside a function but never used | Lint |
| high | zizmor/unpinned-uses |
.github/workflows/code-quality.yml:186 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/code-quality.yml:46 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/code-quality.yml:51 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/docker-build.yml:29 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/docker-build.yml:48 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/docker-build.yml:53 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/docker-build.yml:60 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/docker-build.yml:68 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/docker-build.yml:90 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/release-and-publish.yml:21 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/template-injection |
.github/workflows/release-and-publish.yml:27 | code injection via template expansion [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/release-and-publish.yml:30 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/release-and-publish.yml:49 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/release-and-publish.yml:60 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/release-and-publish.yml:74 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/stale.yml:11 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/tests.yml:110 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/tests.yml:128 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/tests.yml:138 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/tests.yml:62 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/tests.yml:65 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | zizmor/unpinned-uses |
.github/workflows/tests.yml:87 | unpinned action reference [confidence high] | CI workflows (zizmor) |
| high | opengrep/dockerfile.security.missing-user-entrypoint |
Dockerfile:38 | By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile... | Static analysis (opengrep) |
| high | opengrep/dockerfile.security.missing-user |
Dockerfile:41 | By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile... | Static analysis (opengrep) |
| high | osv/GHSA-3936-cmfr-pm3m |
docs/requirements.txt | [email protected] (PyPI) is affected by PYSEC-2026-2121, GHSA-3936-cmfr-pm3m | Dependencies (osv-scanner) |
| high | osv/GHSA-cg8m-r9f2-5wm2 |
docs/requirements.txt | [email protected] (PyPI) is affected by GHSA-cg8m-r9f2-5wm2 | Dependencies (osv-scanner) |
| high | opengrep/python.lang.security.audit.dangerous-subprocess-use-audit |
scrapling/cli.py:27 | Detected subprocess function 'check_output' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an... | Static analysis (opengrep) |
| high | opengrep/javascript.lang.security.detect-insecure-websocket |
scrapling/engines/_browsers/_validators.py:44 | Insecure WebSocket Detected. WebSocket Secure (wss) should be used for all WebSocket connections. [confidence low] | Static analysis (opengrep) |
| high | opengrep/javascript.lang.security.detect-insecure-websocket |
scrapling/engines/_browsers/_validators.py:45 | Insecure WebSocket Detected. WebSocket Secure (wss) should be used for all WebSocket connections. [confidence low] | Static analysis (opengrep) |
| medium | opengrep/python.requests.best-practice.use-raise-for-status |
benchmarks.py:138 | There's an HTTP request made with requests, but the raise_for_status() utility method isn't used. This can result in request errors going unnoticed and your code behaving in unexpected ways, such as if your authorization API returns a... | Lint |
| medium | opengrep/python.requests.best-practice.use-timeout |
benchmarks.py:138 | Detected a 'requests' call without a timeout set. By default, 'requests' calls wait until the connection is closed. This means a 'requests' call without a timeout will hang the program if a response is never received. Consider setting a... | Lint |
| medium | opengrep/python.lang.best-practice.pass-body-fn |
scrapling/cli.py:664 | `pass` is the body of function main. Consider removing this or raise NotImplementedError() if this is a TODO | Lint |
| medium | opengrep/python.lang.maintainability.return-not-in-function |
scrapling/core/ai/server.py:160 | `return` only makes sense inside a function | Lint |
| medium | opengrep/python.lang.best-practice.unspecified-open-encoding |
scrapling/core/shell.py:424 | Missing 'encoding' parameter. 'open()' uses device locale encodings by default, corrupting files with special characters. Specify the encoding to ensure cross-platform support when opening files in text mode (e.g. encoding="utf-8"). | Lint |
| medium | opengrep/python.lang.best-practice.unspecified-open-encoding |
scrapling/core/shell.py:729 | Missing 'encoding' parameter. 'open()' uses device locale encodings by default, corrupting files with special characters. Specify the encoding to ensure cross-platform support when opening files in text mode (e.g. encoding="utf-8"). | Lint |
| medium | opengrep/python.lang.maintainability.is-function-without-parentheses |
scrapling/parser.py:327 | Is "is_tail" a function or an attribute? If it is a function, you may have meant text_node.is_tail() because text_node.is_tail is always true. | Lint |
| medium | opengrep/python.lang.maintainability.is-function-without-parentheses |
scrapling/spiders/engine.py:419 | Is "is_empty" a function or an attribute? If it is a function, you may have meant self.scheduler.is_empty() because self.scheduler.is_empty is always true. | Lint |
| medium | zizmor/excessive-permissions |
.github/workflows/stale.yml:8 | overly broad permissions [confidence medium] | CI workflows (zizmor) |
| medium | zizmor/excessive-permissions |
.github/workflows/tests.yml:37 | overly broad permissions [confidence medium] | CI workflows (zizmor) |
| medium | opengrep/python.lang.security.deserialization.avoid-pickle |
scrapling/spiders/checkpoint.py:49 | Avoid using `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar... | Static analysis (opengrep) |
| medium | opengrep/python.lang.security.deserialization.avoid-pickle |
scrapling/spiders/checkpoint.py:74 | Avoid using `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar... | Static analysis (opengrep) |
| medium | opengrep/python.lang.security.insecure-hash-algorithm-sha1 |
scrapling/spiders/request.py:126 | Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. [confidence medium] | Static analysis (opengrep) |
| medium | opengrep/python.lang.security.insecure-hash-algorithm-sha1 |
scrapling/spiders/templates/site_to_markdown.py:91 | Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead. [confidence medium] | Static analysis (opengrep) |
| low | zizmor/artipacked |
.github/workflows/code-quality.yml:45 | credential persistence through GitHub Actions artifacts [confidence low] | CI workflows (zizmor) |
| low | zizmor/artipacked |
.github/workflows/docker-build.yml:28 | credential persistence through GitHub Actions artifacts [confidence low] | CI workflows (zizmor) |
| low | zizmor/artipacked |
.github/workflows/release-and-publish.yml:21 | credential persistence through GitHub Actions artifacts [confidence low] | CI workflows (zizmor) |
| low | zizmor/artipacked |
.github/workflows/tests.yml:62 | credential persistence through GitHub Actions artifacts [confidence low] | CI workflows (zizmor) |
| low | gitleaks/generic-api-key |
agent-skill/Scrapling-Skill/references/mcp-server.md:252 | Possible generic-api-key secret in the current tree (test/docs/example file) | Secrets (gitleaks) |
| low | gitleaks/generic-api-key |
docs/ai/mcp-server.md:264 | Possible generic-api-key secret in the current tree (test/docs/example file) | Secrets (gitleaks) |
| low | gitleaks/generic-api-key |
docs/locales/ar/ai/mcp-server.md:294 | Possible generic-api-key secret in the current tree (test/docs/example file) | Secrets (gitleaks) |
| low | gitleaks/generic-api-key |
docs/locales/de/ai/mcp-server.md:271 | Possible generic-api-key secret in the current tree (test/docs/example file) | Secrets (gitleaks) |
| low | gitleaks/generic-api-key |
docs/locales/es/ai/mcp-server.md:271 | Possible generic-api-key secret in the current tree (test/docs/example file) | Secrets (gitleaks) |
| low | gitleaks/generic-api-key |
docs/locales/fr/ai/mcp-server.md:271 | Possible generic-api-key secret in the current tree (test/docs/example file) | Secrets (gitleaks) |
| low | gitleaks/generic-api-key |
docs/locales/ja/ai/mcp-server.md:264 | Possible generic-api-key secret in the current tree (test/docs/example file) | Secrets (gitleaks) |
| low | gitleaks/generic-api-key |
docs/locales/ko/ai/mcp-server.md:264 | Possible generic-api-key secret in the current tree (test/docs/example file) | Secrets (gitleaks) |
| low | gitleaks/generic-api-key |
docs/locales/pt-BR/ai/mcp-server.md:271 | Possible generic-api-key secret in the current tree (test/docs/example file) | Secrets (gitleaks) |
| low | gitleaks/generic-api-key |
docs/locales/ru/ai/mcp-server.md:264 | Possible generic-api-key secret in the current tree (test/docs/example file) | Secrets (gitleaks) |
| low | gitleaks/generic-api-key |
docs/locales/zh/ai/mcp-server.md:270 | Possible generic-api-key secret in the current tree (test/docs/example file) | Secrets (gitleaks) |
| low | gitleaks/generic-api-key |
tests/ai/test_browser_fill_fields.py:664 | Possible generic-api-key secret in the current tree (test/docs/example file) | Secrets (gitleaks) |
| info | zizmor/template-injection |
.github/workflows/docker-build.yml:103 | code injection via template expansion [confidence low] | CI workflows (zizmor) |
| info | zizmor/template-injection |
.github/workflows/release-and-publish.yml:39 | code injection via template expansion [confidence low] | CI workflows (zizmor) |
| info | zizmor/superfluous-actions |
.github/workflows/release-and-publish.yml:49 | action functionality is already included by the runner [confidence high] | CI workflows (zizmor) |
| info | zizmor/template-injection |
.github/workflows/tests.yml:100 | code injection via template expansion [confidence low] | CI workflows (zizmor) |
| info | zizmor/template-injection |
.github/workflows/tests.yml:101 | code injection via template expansion [confidence low] | CI workflows (zizmor) |
Tools and coverage
Every analyzer that ran on this commit. A failed or skipped tool is a coverage gap: its share of the score is left out and the coverage figure drops.
| Analyzer | Pillar | Status | Version | Findings | Note |
|---|---|---|---|---|---|
| AI tool configuration | AI provenance | ok | signatures-v1 | 0 | |
| Explicit AI attribution | AI provenance | ok | signatures-v1 | 0 | |
| Release velocity | AI provenance | ok | prov-5 | 0 | |
| Coding style | AI provenance | ok | — | 0 | |
| Commit velocity | AI provenance | ok | prov-5 | 0 | |
| Findings in AI-written lines | AI provenance | ok | git-blame | 0 | |
| Complexity (lizard) | Code quality | ok | lizard 1.25.1 | 0 | |
| Documentation | Code quality | ok | — | 0 | |
| Duplication (jscpd) | Code quality | ok | repotrust-dup-w6 | 0 | |
| Lint | Code quality | ok | opengrep 1.33.1; rules f1d2b562b414 | 9 | |
| Tests and CI | Code quality | ok | — | 0 | |
| Type safety | Code quality | ok | — | 0 | |
| CI workflows (zizmor) | Security | ok | zizmor 1.32.0 | 33 | |
| Dependencies (osv-scanner) | Security | ok | osv-scanner version: 2.7.1 | 3 | |
| Release downloads | Security | ok | — | 0 | |
| Security posture | Security | ok | — | 0 | |
| Package registries | Security | ok | — | 0 | |
| Static analysis (opengrep) | Security | ok | opengrep 1.33.1; rules f1d2b562b414 | 9 | |
| OpenSSF Scorecard | Security | skipped | — | 0 | no published OpenSSF Scorecard result for this repo |
| Secrets (gitleaks) | Security | ok | gitleaks 8.30.1 | 12 |
Score history
| Scored | Commit | Scoring | AI provenance | Quality | Security |
|---|---|---|---|---|---|
| 2026-11-14 | bb223f2f5fc8 | prov-5+qual-2+sec-2 | 1% | 74 | 55 |
Full text report
- Repository: https://github.com/D4Vinci/Scrapling
- Commit:
bb223f2f5fc8f743772751a5ce283ef7851ca6be - Generated: 2026-11-14T15:21:06+00:00
- Scorer 0.1.0, scoring prov-5+qual-2+sec-2, report schema v2
Scores
| Pillar | Score | Signal | Confidence | Coverage |
|---|---|---|---|---|
| AI provenance (estimated AI-generated share) | 1 | explicit | 95% | 100% |
| Code quality | 74 | adequate | 90% | 100% |
| Security | 55 | weak | 85% | 100% |
AI provenance
Explicit AI attribution on 1% of first-party code added; an estimated 1% including velocity signals.
- Explicitly attributed share (lower bound): 0.6%
- Unattributed share in AI-consistent velocity bursts: 18.6%
- Estimated AI-generated share: 0.6%
| AI tool | Attributed commits | Lines added |
|---|---|---|
| OpenAI Codex | 10 | 43 |
| Claude Code | 8 | 430 |
Current source lines last changed by AI-attributed commits: 15 of 16,661.
Too few lines in one group to compare finding densities.
| Month | Lines added | Attributed to AI |
|---|---|---|
| 2025-12 | 691 | 0% |
| 2026-01 | 4,479 | 0% |
| 2026-02 | 2,810 | 0% |
| 2026-03 | 1,952 | 18% |
| 2026-04 | 6,187 | 1% |
| 2026-05 | 1,476 | 0% |
| 2026-06 | 534 | 5% |
| 2026-07 | 2,044 | 0% |
| 2026-08 | 3,382 | 0% |
| 2026-09 | 10,334 | 0% |
| 2026-10 | 10,543 | 0% |
| 2026-11 | 1,318 | 3% |
Evidence
- OpenAI Codex: PR branch 'codex/fix-template-gzip-errors' (37950a630437)
- OpenAI Codex: trailer 'Co-authored-by: Codex' (330d2e685ac2)
- OpenAI Codex: trailer 'Co-authored-by: Codex' (2995be75a00a)
- OpenAI Codex: trailer 'Co-authored-by: Codex' (50c99b9b3fc3)
- OpenAI Codex: trailer 'Co-authored-by: Codex' (066d30938ab5)
- OpenAI Codex: trailer 'Co-authored-by: Codex' (a4dcdf346907)
- OpenAI Codex: trailer 'Co-authored-by: Codex' (03221a0f177c)
- OpenAI Codex: trailer 'Co-authored-by: Codex' (d7182358bae6)
- OpenAI Codex: trailer 'Co-authored-by: Codex' (251e884a6d93)
- OpenAI Codex: trailer 'Co-authored-by: Codex' (98f94471d591)
- Claude Code: PR description attribution (80332cf3a7b3)
- Claude Code: trailer 'Co-Authored-By: Claude' (cd4cdc69e622)
- Claude Code: trailer 'Co-Authored-By: Claude' (00897dad2f60)
- Claude Code: trailer 'Co-Authored-By: Claude' (273c8c2fa02d)
- Claude Code: trailer 'Co-Authored-By: Claude' (d3c251c1ab3a)
AI provenance describes how code was produced; it is not a quality judgment. Unless attribution is explicit, these are signals consistent with AI generation, not proof. Squash/rebase workflows, imported code, and rewritten history reduce accuracy.
Code quality
Code quality is adequate: test-to-source ratio 1.63, CI runs tests; 21% of function code in complex or long functions; 10% duplicated lines. Weakest area: type safety.
| Area | Score |
|---|---|
| Complexity (lizard) | 53 |
| Duplication | 54 |
| Code smells (Opengrep) | 85 |
| Tests and CI | 100 |
| Documentation | 100 |
| Type safety | 0 |
| Process (Scorecard review/maintenance) | n/a |
- Functions: 580; mean complexity 3.8, 90th percentile 8; 22 complex and 2 long functions
- Duplicated lines: 10.4% of 13,663 compared
- Tests: 27,193 test lines for 16,661 source lines (ratio 1.63); CI test commands: tox; 75% of recent source commits also change tests
- Docs missing or thin: none
Most complex functions:
- _cloudflare_solver in scrapling/engines/_browsers/_stealth.py: complexity 37, 95 lines
- _cloudflare_solver in scrapling/engines/_browsers/_stealth.py: complexity 37, 100 lines
- _run_actions in scrapling/core/ai/_browser_actions.py: complexity 35, 91 lines
- parse in scrapling/core/shell.py: complexity 34, 115 lines
- find_all in scrapling/parser.py: complexity 33, 67 lines
Security
Security posture is weak: 3 known vulnerabilities in 1 dependencies; 5 high-severity SAST findings; 22 high-severity workflow issues. Weakest area: posture.
| Area | Score |
|---|---|
| Secrets (gitleaks, tree + history) | 67 |
| Static analysis (Opengrep) | 85 |
| Vulnerable dependencies (OSV) | 78 |
| CI workflows (zizmor) | 1 |
| Posture (policy, updates, signing, lockfiles) | 0 |
| OpenSSF Scorecard | n/a |
-
Known vulnerabilities: 3 in 1 packages (critical 1, high 2, medium 0, low 0)
-
Posture checks passed: lockfiles; missing: security policy, dependency updates, signed commits
Top findings
| Severity | Finding | Location |
|---|---|---|
| critical | osv/PYSEC-2026-2120: [email protected] (PyPI) is affected by PYSEC-2026-2120 |
docs/requirements.txt |
| high | opengrep/dockerfile.security.missing-user-entrypoint: By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'. [confidence medium] |
Dockerfile:38 |
| high | opengrep/dockerfile.security.missing-user: By not specifying a USER, a program in the container may run as 'root'. This is a security hazard. If an attacker can control a process running as root, they may have control over the container. Ensure that the last USER in a Dockerfile is a USER other than 'root'. [confidence medium] |
Dockerfile:41 |
| high | opengrep/python.lang.security.audit.dangerous-subprocess-use-audit: Detected subprocess function 'check_output' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'. [confidence low] |
scrapling/cli.py:27 |
| high | opengrep/javascript.lang.security.detect-insecure-websocket: Insecure WebSocket Detected. WebSocket Secure (wss) should be used for all WebSocket connections. [confidence low] |
scrapling/engines/_browsers/_validators.py:44 |
| high | opengrep/javascript.lang.security.detect-insecure-websocket: Insecure WebSocket Detected. WebSocket Secure (wss) should be used for all WebSocket connections. [confidence low] |
scrapling/engines/_browsers/_validators.py:45 |
| high | osv/GHSA-3936-cmfr-pm3m: [email protected] (PyPI) is affected by PYSEC-2026-2121, GHSA-3936-cmfr-pm3m |
docs/requirements.txt |
| high | osv/GHSA-cg8m-r9f2-5wm2: [email protected] (PyPI) is affected by GHSA-cg8m-r9f2-5wm2 |
docs/requirements.txt |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/code-quality.yml:46 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/code-quality.yml:51 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/code-quality.yml:186 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/docker-build.yml:29 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/docker-build.yml:48 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/docker-build.yml:53 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/docker-build.yml:60 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/docker-build.yml:68 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/docker-build.yml:90 |
| high | zizmor/template-injection: code injection via template expansion [confidence high] |
.github/workflows/release-and-publish.yml:27 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/release-and-publish.yml:21 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/release-and-publish.yml:30 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/release-and-publish.yml:49 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/release-and-publish.yml:60 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/release-and-publish.yml:74 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/stale.yml:11 |
| high | zizmor/unpinned-uses: unpinned action reference [confidence high] |
.github/workflows/tests.yml:62 |
Static signals only: the scorer never runs the project's code. Secret findings are pattern matches that were not verified, and secret values are never stored.
Repository profile
- Source lines: 16,661; test lines: 27,193
| Language | Lines |
|---|---|
| Python | 43,841 |
| JavaScript | 13 |