web-scanner 2.1.4__tar.gz → 2.1.5__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.
- {web_scanner-2.1.4 → web_scanner-2.1.5}/PKG-INFO +2 -2
- {web_scanner-2.1.4 → web_scanner-2.1.5}/README.md +1 -1
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/__init__.py +1 -1
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/modules/seo.py +46 -7
- {web_scanner-2.1.4 → web_scanner-2.1.5}/.gitignore +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/LICENSE +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/app.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/pyproject.toml +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/requirements.txt +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/__main__.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/cli.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/colors.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/core/__init__.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/core/context.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/core/models.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/core/module.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/core/scanner.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/helpers.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/modules/__init__.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/modules/dns.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/modules/headers.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/modules/links.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/modules/security.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/modules/sitemap.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/modules/ssl.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/modules/subdomains.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/modules/tech.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/modules/whois.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/net/__init__.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/net/agents.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/net/data/public_suffix_list.dat +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/net/http.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/net/psl.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/ui/__init__.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/ui/activity.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/ui/app.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/ui/app.tcss +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/ui/data/countries.json +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/ui/export.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/ui/tables.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/ui/widgets.py +0 -0
- {web_scanner-2.1.4 → web_scanner-2.1.5}/webscanner/ui/worldmap.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: web-scanner
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.5
|
|
4
4
|
Summary: An async Textual TUI for website reconnaissance — DNS, WHOIS, TLS, security, tech-stack and SEO, with no paid APIs.
|
|
5
5
|
Project-URL: Homepage, https://github.com/iamramizk/web-scanner
|
|
6
6
|
Project-URL: Repository, https://github.com/iamramizk/web-scanner
|
|
@@ -55,7 +55,7 @@ Description-Content-Type: text/markdown
|
|
|
55
55
|
_An async Textual TUI for website reconnaissance — DNS, WHOIS, TLS, security, tech-stack and SEO, with no paid APIs._
|
|
56
56
|
|
|
57
57
|
[](https://www.python.org/downloads/)
|
|
58
|
-
[](https://pypi.org/project/web-scanner/)
|
|
59
59
|
[](https://github.com/iamramizk/web-scanner/releases/latest)
|
|
60
60
|
|
|
61
61
|
</div>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
_An async Textual TUI for website reconnaissance — DNS, WHOIS, TLS, security, tech-stack and SEO, with no paid APIs._
|
|
6
6
|
|
|
7
7
|
[](https://www.python.org/downloads/)
|
|
8
|
-
[](https://pypi.org/project/web-scanner/)
|
|
9
9
|
[](https://github.com/iamramizk/web-scanner/releases/latest)
|
|
10
10
|
|
|
11
11
|
</div>
|
|
@@ -39,11 +39,38 @@ SOCIAL_DOMAINS = (
|
|
|
39
39
|
)
|
|
40
40
|
|
|
41
41
|
_STOPWORDS = frozenset(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
(
|
|
43
|
+
# core articles / conjunctions / prepositions / pronouns
|
|
44
|
+
"the a an and or but if of to in on for with as by at from is are was were be "
|
|
45
|
+
"been being this that these those it its you your we our us they their he she "
|
|
46
|
+
"his her not no so do does did has have had can will would should could may "
|
|
47
|
+
"might just than then there here what which who when where how all any some "
|
|
48
|
+
"more most other into out up down over under about also new get one two "
|
|
49
|
+
# additional pronouns / possessives
|
|
50
|
+
"him them myself yourself himself herself itself ourselves themselves "
|
|
51
|
+
"whom whose mine yours ours hers theirs "
|
|
52
|
+
# modals / auxiliaries
|
|
53
|
+
"shall must cannot ought need used "
|
|
54
|
+
# conjunctions / subordinators
|
|
55
|
+
"nor yet because while since until unless although though whether whereas "
|
|
56
|
+
"whenever wherever whoever whatever "
|
|
57
|
+
# prepositions
|
|
58
|
+
"off per via upon above below beneath between among amongst throughout during "
|
|
59
|
+
"before after against without within along across behind beyond near toward "
|
|
60
|
+
"towards onto "
|
|
61
|
+
# determiners / quantifiers
|
|
62
|
+
"each every either neither both few many much such own same only very too quite "
|
|
63
|
+
"rather enough none another several "
|
|
64
|
+
# common adverbs / fillers
|
|
65
|
+
"back even still again ever never always often once now thus hence therefore "
|
|
66
|
+
"however moreover otherwise indeed perhaps maybe actually really simply almost "
|
|
67
|
+
"already else yes why well like "
|
|
68
|
+
# contractions (the tokenizer keeps apostrophes, so these survive verbatim)
|
|
69
|
+
"don't doesn't didn't isn't aren't wasn't weren't won't wouldn't can't couldn't "
|
|
70
|
+
"shouldn't hasn't haven't hadn't i'm i've i'll i'd you're you've you'll you'd "
|
|
71
|
+
"we're we've we'll we'd they're they've they'll it's he's she's that's there's "
|
|
72
|
+
"here's what's who's let's"
|
|
73
|
+
).split()
|
|
47
74
|
)
|
|
48
75
|
|
|
49
76
|
|
|
@@ -99,6 +126,18 @@ def _len_line(text: str, lo: int, hi: int) -> str:
|
|
|
99
126
|
return f"[{MUTED}]{escape(text)}[/]\n[{colour}]{n} chars · rec. {lo}-{hi}[/]"
|
|
100
127
|
|
|
101
128
|
|
|
129
|
+
def _text(el) -> str:
|
|
130
|
+
"""Element text as the browser's `textContent` sees it, whitespace collapsed.
|
|
131
|
+
|
|
132
|
+
`get_text(strip=True)` strips each child text node then joins with no
|
|
133
|
+
separator, so words split across spans/newlines fuse ("One <span>Two</span>
|
|
134
|
+
<span>Three</span>" -> "OneTwoThree"). Taking the raw text and re-joining on
|
|
135
|
+
whitespace keeps the gaps that actually exist between nodes without inventing
|
|
136
|
+
any where the DOM has none (e.g. `<br>`).
|
|
137
|
+
"""
|
|
138
|
+
return " ".join(el.get_text().split())
|
|
139
|
+
|
|
140
|
+
|
|
102
141
|
class SeoModule(ScanModule):
|
|
103
142
|
name = "seo"
|
|
104
143
|
label = "SEO"
|
|
@@ -141,7 +180,7 @@ class SeoModule(ScanModule):
|
|
|
141
180
|
|
|
142
181
|
# --- Content ---
|
|
143
182
|
title_el = soup.find("title")
|
|
144
|
-
title = title_el
|
|
183
|
+
title = _text(title_el) if title_el else None
|
|
145
184
|
desc_el = soup.find("meta", attrs={"name": "description"})
|
|
146
185
|
desc = (desc_el.get("content") or "").strip() if desc_el else None
|
|
147
186
|
content: dict[str, object] = {
|
|
@@ -149,7 +188,7 @@ class SeoModule(ScanModule):
|
|
|
149
188
|
"Description": _len_line(desc, *DESC_RANGE) if desc else "-",
|
|
150
189
|
}
|
|
151
190
|
for lvl in range(1, 4):
|
|
152
|
-
content[f"H{lvl}"] = [h
|
|
191
|
+
content[f"H{lvl}"] = [_text(h) for h in soup.find_all(f"h{lvl}")]
|
|
153
192
|
content["Socials"] = sorted({
|
|
154
193
|
tag["href"].rstrip("/")
|
|
155
194
|
for tag in soup.find_all("a", href=True)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|