seolens 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- seolens-0.1.0/LICENSE +21 -0
- seolens-0.1.0/PKG-INFO +129 -0
- seolens-0.1.0/README.md +102 -0
- seolens-0.1.0/pyproject.toml +43 -0
- seolens-0.1.0/seolens/__init__.py +7 -0
- seolens-0.1.0/seolens/analyze.py +1032 -0
- seolens-0.1.0/seolens/app.py +309 -0
- seolens-0.1.0/seolens/audit.py +73 -0
- seolens-0.1.0/seolens/checks.py +733 -0
- seolens-0.1.0/seolens/cli.py +117 -0
- seolens-0.1.0/seolens/crawler.py +619 -0
- seolens-0.1.0/seolens/data/rules.json +1060 -0
- seolens-0.1.0/seolens/data/site_map.html +273 -0
- seolens-0.1.0/seolens/htmltools.py +363 -0
- seolens-0.1.0/seolens/net.py +259 -0
- seolens-0.1.0/seolens/overview.py +164 -0
- seolens-0.1.0/seolens/renderer.py +187 -0
- seolens-0.1.0/seolens/report.py +498 -0
- seolens-0.1.0/seolens/sitehealth.py +286 -0
- seolens-0.1.0/seolens/store.py +154 -0
- seolens-0.1.0/seolens/throttle.py +91 -0
- seolens-0.1.0/seolens/workbook.py +577 -0
- seolens-0.1.0/seolens/worker.py +101 -0
- seolens-0.1.0/seolens.egg-info/PKG-INFO +129 -0
- seolens-0.1.0/seolens.egg-info/SOURCES.txt +31 -0
- seolens-0.1.0/seolens.egg-info/dependency_links.txt +1 -0
- seolens-0.1.0/seolens.egg-info/entry_points.txt +2 -0
- seolens-0.1.0/seolens.egg-info/requires.txt +11 -0
- seolens-0.1.0/seolens.egg-info/top_level.txt +1 -0
- seolens-0.1.0/setup.cfg +4 -0
- seolens-0.1.0/tests/test_crawl.py +100 -0
- seolens-0.1.0/tests/test_throttle.py +67 -0
- seolens-0.1.0/tests/testsite.py +74 -0
seolens-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Supriyo Mallick
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
seolens-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: seolens
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Free, open-source SEO crawler and audit tool (up to 10,000 URLs) with a Streamlit dashboard.
|
|
5
|
+
Author: Supriyo Mallick
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/growthlab-supriyo/seolens
|
|
8
|
+
Keywords: seo,crawler,seo-audit,technical-seo,streamlit
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Classifier: Environment :: Web Environment
|
|
12
|
+
Classifier: Intended Audience :: Information Technology
|
|
13
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: requests<3,>=2.31
|
|
18
|
+
Requires-Dist: regex>=2023.0
|
|
19
|
+
Requires-Dist: openpyxl<4,>=3.1
|
|
20
|
+
Requires-Dist: pandas<4,>=2
|
|
21
|
+
Requires-Dist: streamlit<2,>=1.40
|
|
22
|
+
Provides-Extra: js
|
|
23
|
+
Requires-Dist: playwright<2,>=1.40; extra == "js"
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# 🔎 SEO Lens
|
|
29
|
+
|
|
30
|
+
**A free, open-source SEO crawler and site audit tool.** It crawls up to 10,000 URLs per run and gives you a health dashboard, an Excel report and a site architecture map. It runs on your own computer, so there's no account, no subscription and no tracking.
|
|
31
|
+
|
|
32
|
+
Made by [Supriyo Mallick](https://www.linkedin.com/in/s-mallick) for SEOs, freelancers and small teams who can't justify a paid crawler licence.
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
You need Python 3.10 or newer.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pipx install seolens
|
|
40
|
+
seolens
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The app opens in your browser at `http://localhost:8501`. (`pip install seolens` works too.)
|
|
44
|
+
|
|
45
|
+
**Optional JavaScript rendering**, for sites built with React, Vue and similar frameworks:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pipx install "seolens[js]"
|
|
49
|
+
playwright install chromium
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
JavaScript rendering uses Microsoft Edge or Google Chrome if one is installed, and Chromium otherwise.
|
|
53
|
+
|
|
54
|
+
**From source:**
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
git clone https://github.com/growthlab-supriyo/seolens && cd seolens
|
|
58
|
+
pip install -e ".[dev]"
|
|
59
|
+
seolens
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## What it checks
|
|
63
|
+
|
|
64
|
+
| Area | Checks |
|
|
65
|
+
|---|---|
|
|
66
|
+
| Crawlability & indexing | Status codes, redirect chains and loops, noindex, X-Robots-Tag, canonicals (missing, conflicting, broken, chained), robots.txt, XML sitemaps and sitemap indexes |
|
|
67
|
+
| On-page | Titles, meta descriptions, H1–H3, heading levels, title vs H1, viewport, word count |
|
|
68
|
+
| Content | Thin pages, exact duplicates, near-duplicates (MinHash), placeholder text, date consistency |
|
|
69
|
+
| Internal linking | Inlinks and outlinks, anchors, broken links, click depth, orphan pages, Link Score (PageRank-style) |
|
|
70
|
+
| Markup | JSON-LD, Microdata, RDFa, missing schema properties, Open Graph, Twitter cards |
|
|
71
|
+
| International | hreflang (return links, codes, targets), `html lang`, og:locale |
|
|
72
|
+
| Performance signals | Heavy images, render-blocking scripts, third-party scripts, page weight |
|
|
73
|
+
|
|
74
|
+
**Dashboard tabs:** Overview (health score, crawled-pages breakdown, errors, warnings and notices, thematic scores, top issues, click depth), Issues, All pages (filter and export CSV), Response codes, Blocked & failed, Broken links and Site health. The **Excel report** has the same data plus a Summary sheet with quick wins.
|
|
75
|
+
|
|
76
|
+
## Fast, and polite
|
|
77
|
+
|
|
78
|
+
- **Adaptive speed (AIMD).** It starts at 10 pages at a time on Medium. It speeds up while the site answers quickly and slows down gradually only when the site *stays* slow. A few slow pages don't change anything.
|
|
79
|
+
- When a site says it is overloaded (HTTP 429 or 503), the crawler halves its speed and waits for the `Retry-After` time the site asks for.
|
|
80
|
+
- It follows robots.txt, including `Crawl-delay`.
|
|
81
|
+
- **Pause and resume.** Every queued URL and crawled page is saved to SQLite as the crawl runs. You can pause a crawl, close the app, and resume it later. **Finish now** builds the report from the pages crawled so far.
|
|
82
|
+
|
|
83
|
+
## Honest crawling: what it does with Cloudflare and firewalls
|
|
84
|
+
|
|
85
|
+
SEO Lens **does not bypass** Cloudflare, CAPTCHAs or other bot protection, and it never disguises itself as a person's browser. It sends `SEOLens/<version>` in its User-Agent so site owners can see who is crawling them. What it does instead:
|
|
86
|
+
|
|
87
|
+
- **Detects and labels** each blocked page: Cloudflare challenge, bot check or CAPTCHA, 403, rate limiting (429), server busy (503), timeouts and connection errors. Blocked pages appear in the **Blocked & failed** tab and the Excel summary, never silently missing, so an incomplete crawl can't pass for a complete audit.
|
|
88
|
+
- **Doesn't hammer a blocked page.** A challenge page is not retried. A 403 is retried once, and only if the site was serving pages normally until then.
|
|
89
|
+
- **Authorized access for sites you own.** In Cloudflare, add a WAF custom rule that skips security checks for a secret request header (or for the `SEOLens` User-Agent). Then add that header under *Authorized access* in the app. HTTP Basic login is supported too. Credentials are sent **only** to the site being audited, never to external links, images or redirects to other hosts. They are stored in the local database on your computer.
|
|
90
|
+
|
|
91
|
+
## Command line
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
seolens crawl example.com --max 2000 --speed Medium --render off
|
|
95
|
+
seolens crawl --list urls.txt
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Where your data lives
|
|
99
|
+
|
|
100
|
+
The database and reports are stored in `~/.seolens/` (`C:\Users\<you>\.seolens\` on Windows). To use another folder, set `SEOLENS_HOME`. Nothing is sent anywhere else.
|
|
101
|
+
|
|
102
|
+
## Limits
|
|
103
|
+
|
|
104
|
+
- 10,000 URLs per crawl.
|
|
105
|
+
- Performance checks are signals from the HTML, not measured Core Web Vitals. PageSpeed Insights integration is planned.
|
|
106
|
+
- Word count is approximate on pages with a lot of interface text.
|
|
107
|
+
|
|
108
|
+
## Development
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pip install -e ".[dev]"
|
|
112
|
+
pytest -q tests
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The tests run a small local website with redirects, a 404, a slow page, a rate-limited page, a Cloudflare-style challenge and a protected page.
|
|
116
|
+
|
|
117
|
+
| File | What it does |
|
|
118
|
+
|---|---|
|
|
119
|
+
| `seolens/crawler.py` | Discovery, fetch loop, blocked-page classification, saving and resuming |
|
|
120
|
+
| `seolens/throttle.py` | The adaptive concurrency controller |
|
|
121
|
+
| `seolens/analyze.py`, `checks.py`, `sitehealth.py` | Per-page analysis, cross-page checks, site-wide checks |
|
|
122
|
+
| `seolens/report.py` | Excel report and site architecture map |
|
|
123
|
+
| `seolens/store.py` | SQLite (WAL) |
|
|
124
|
+
| `seolens/worker.py` | Runs the crawl in its own process |
|
|
125
|
+
| `seolens/app.py`, `overview.py` | Streamlit dashboard |
|
|
126
|
+
|
|
127
|
+
**Public demo:** set `SEOLENS_DEMO=1` to cap crawls at 500 URLs and turn off JavaScript rendering (for example on Hugging Face Spaces).
|
|
128
|
+
|
|
129
|
+
MIT licence.
|
seolens-0.1.0/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# 🔎 SEO Lens
|
|
2
|
+
|
|
3
|
+
**A free, open-source SEO crawler and site audit tool.** It crawls up to 10,000 URLs per run and gives you a health dashboard, an Excel report and a site architecture map. It runs on your own computer, so there's no account, no subscription and no tracking.
|
|
4
|
+
|
|
5
|
+
Made by [Supriyo Mallick](https://www.linkedin.com/in/s-mallick) for SEOs, freelancers and small teams who can't justify a paid crawler licence.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
You need Python 3.10 or newer.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pipx install seolens
|
|
13
|
+
seolens
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The app opens in your browser at `http://localhost:8501`. (`pip install seolens` works too.)
|
|
17
|
+
|
|
18
|
+
**Optional JavaScript rendering**, for sites built with React, Vue and similar frameworks:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pipx install "seolens[js]"
|
|
22
|
+
playwright install chromium
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
JavaScript rendering uses Microsoft Edge or Google Chrome if one is installed, and Chromium otherwise.
|
|
26
|
+
|
|
27
|
+
**From source:**
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
git clone https://github.com/growthlab-supriyo/seolens && cd seolens
|
|
31
|
+
pip install -e ".[dev]"
|
|
32
|
+
seolens
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## What it checks
|
|
36
|
+
|
|
37
|
+
| Area | Checks |
|
|
38
|
+
|---|---|
|
|
39
|
+
| Crawlability & indexing | Status codes, redirect chains and loops, noindex, X-Robots-Tag, canonicals (missing, conflicting, broken, chained), robots.txt, XML sitemaps and sitemap indexes |
|
|
40
|
+
| On-page | Titles, meta descriptions, H1–H3, heading levels, title vs H1, viewport, word count |
|
|
41
|
+
| Content | Thin pages, exact duplicates, near-duplicates (MinHash), placeholder text, date consistency |
|
|
42
|
+
| Internal linking | Inlinks and outlinks, anchors, broken links, click depth, orphan pages, Link Score (PageRank-style) |
|
|
43
|
+
| Markup | JSON-LD, Microdata, RDFa, missing schema properties, Open Graph, Twitter cards |
|
|
44
|
+
| International | hreflang (return links, codes, targets), `html lang`, og:locale |
|
|
45
|
+
| Performance signals | Heavy images, render-blocking scripts, third-party scripts, page weight |
|
|
46
|
+
|
|
47
|
+
**Dashboard tabs:** Overview (health score, crawled-pages breakdown, errors, warnings and notices, thematic scores, top issues, click depth), Issues, All pages (filter and export CSV), Response codes, Blocked & failed, Broken links and Site health. The **Excel report** has the same data plus a Summary sheet with quick wins.
|
|
48
|
+
|
|
49
|
+
## Fast, and polite
|
|
50
|
+
|
|
51
|
+
- **Adaptive speed (AIMD).** It starts at 10 pages at a time on Medium. It speeds up while the site answers quickly and slows down gradually only when the site *stays* slow. A few slow pages don't change anything.
|
|
52
|
+
- When a site says it is overloaded (HTTP 429 or 503), the crawler halves its speed and waits for the `Retry-After` time the site asks for.
|
|
53
|
+
- It follows robots.txt, including `Crawl-delay`.
|
|
54
|
+
- **Pause and resume.** Every queued URL and crawled page is saved to SQLite as the crawl runs. You can pause a crawl, close the app, and resume it later. **Finish now** builds the report from the pages crawled so far.
|
|
55
|
+
|
|
56
|
+
## Honest crawling: what it does with Cloudflare and firewalls
|
|
57
|
+
|
|
58
|
+
SEO Lens **does not bypass** Cloudflare, CAPTCHAs or other bot protection, and it never disguises itself as a person's browser. It sends `SEOLens/<version>` in its User-Agent so site owners can see who is crawling them. What it does instead:
|
|
59
|
+
|
|
60
|
+
- **Detects and labels** each blocked page: Cloudflare challenge, bot check or CAPTCHA, 403, rate limiting (429), server busy (503), timeouts and connection errors. Blocked pages appear in the **Blocked & failed** tab and the Excel summary, never silently missing, so an incomplete crawl can't pass for a complete audit.
|
|
61
|
+
- **Doesn't hammer a blocked page.** A challenge page is not retried. A 403 is retried once, and only if the site was serving pages normally until then.
|
|
62
|
+
- **Authorized access for sites you own.** In Cloudflare, add a WAF custom rule that skips security checks for a secret request header (or for the `SEOLens` User-Agent). Then add that header under *Authorized access* in the app. HTTP Basic login is supported too. Credentials are sent **only** to the site being audited, never to external links, images or redirects to other hosts. They are stored in the local database on your computer.
|
|
63
|
+
|
|
64
|
+
## Command line
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
seolens crawl example.com --max 2000 --speed Medium --render off
|
|
68
|
+
seolens crawl --list urls.txt
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Where your data lives
|
|
72
|
+
|
|
73
|
+
The database and reports are stored in `~/.seolens/` (`C:\Users\<you>\.seolens\` on Windows). To use another folder, set `SEOLENS_HOME`. Nothing is sent anywhere else.
|
|
74
|
+
|
|
75
|
+
## Limits
|
|
76
|
+
|
|
77
|
+
- 10,000 URLs per crawl.
|
|
78
|
+
- Performance checks are signals from the HTML, not measured Core Web Vitals. PageSpeed Insights integration is planned.
|
|
79
|
+
- Word count is approximate on pages with a lot of interface text.
|
|
80
|
+
|
|
81
|
+
## Development
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install -e ".[dev]"
|
|
85
|
+
pytest -q tests
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The tests run a small local website with redirects, a 404, a slow page, a rate-limited page, a Cloudflare-style challenge and a protected page.
|
|
89
|
+
|
|
90
|
+
| File | What it does |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `seolens/crawler.py` | Discovery, fetch loop, blocked-page classification, saving and resuming |
|
|
93
|
+
| `seolens/throttle.py` | The adaptive concurrency controller |
|
|
94
|
+
| `seolens/analyze.py`, `checks.py`, `sitehealth.py` | Per-page analysis, cross-page checks, site-wide checks |
|
|
95
|
+
| `seolens/report.py` | Excel report and site architecture map |
|
|
96
|
+
| `seolens/store.py` | SQLite (WAL) |
|
|
97
|
+
| `seolens/worker.py` | Runs the crawl in its own process |
|
|
98
|
+
| `seolens/app.py`, `overview.py` | Streamlit dashboard |
|
|
99
|
+
|
|
100
|
+
**Public demo:** set `SEOLENS_DEMO=1` to cap crawls at 500 URLs and turn off JavaScript rendering (for example on Hugging Face Spaces).
|
|
101
|
+
|
|
102
|
+
MIT licence.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "seolens"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Free, open-source SEO crawler and audit tool (up to 10,000 URLs) with a Streamlit dashboard."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [{ name = "Supriyo Mallick" }]
|
|
13
|
+
keywords = ["seo", "crawler", "seo-audit", "technical-seo", "streamlit"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Operating System :: OS Independent",
|
|
17
|
+
"Environment :: Web Environment",
|
|
18
|
+
"Intended Audience :: Information Technology",
|
|
19
|
+
"Topic :: Internet :: WWW/HTTP :: Site Management",
|
|
20
|
+
]
|
|
21
|
+
dependencies = [
|
|
22
|
+
"requests>=2.31,<3",
|
|
23
|
+
"regex>=2023.0",
|
|
24
|
+
"openpyxl>=3.1,<4",
|
|
25
|
+
"pandas>=2,<4",
|
|
26
|
+
"streamlit>=1.40,<2",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
js = ["playwright>=1.40,<2"]
|
|
31
|
+
dev = ["pytest>=8"]
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
seolens = "seolens.cli:main"
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
Homepage = "https://github.com/growthlab-supriyo/seolens"
|
|
38
|
+
|
|
39
|
+
[tool.setuptools]
|
|
40
|
+
packages = ["seolens", "seolens.data"]
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.package-data]
|
|
43
|
+
seolens = ["data/*"]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"""SEO Lens: a free, open-source SEO crawler and audit tool (up to 10,000 URLs per crawl)."""
|
|
2
|
+
__version__ = "0.1.0"
|
|
3
|
+
|
|
4
|
+
# Change this to the project's GitHub page before the first release: it is sent in the User-Agent so site owners can see who crawls them.
|
|
5
|
+
PROJECT_URL = "https://github.com/growthlab-supriyo/seolens"
|
|
6
|
+
MAX_URLS = 10000
|
|
7
|
+
DEMO_MAX_URLS = 500 # when SEOLENS_DEMO=1 (the public online demo)
|