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 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.
@@ -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)