ferret-crawler 1.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.
- ferret_crawler-1.1.0/PKG-INFO +106 -0
- ferret_crawler-1.1.0/README.md +96 -0
- ferret_crawler-1.1.0/pyproject.toml +24 -0
- ferret_crawler-1.1.0/pyproject.toml.orig +24 -0
- ferret_crawler-1.1.0/src/site2md/__init__.py +68 -0
- ferret_crawler-1.1.0/src/site2md/__main__.py +3 -0
- ferret_crawler-1.1.0/src/site2md/crawl.py +851 -0
- ferret_crawler-1.1.0/src/site2md/html.py +253 -0
- ferret_crawler-1.1.0/src/site2md/static/favicon.svg +10 -0
- ferret_crawler-1.1.0/src/site2md/static/index.html +181 -0
- ferret_crawler-1.1.0/src/site2md/static/ui.css +222 -0
- ferret_crawler-1.1.0/src/site2md/static/ui.js +367 -0
- ferret_crawler-1.1.0/src/site2md/ui.py +760 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: ferret-crawler
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Save a website or intranet as Markdown files, one per page (for search indexes and LLM tools)
|
|
5
|
+
Requires-Dist: playwright>=1.48 ; extra == 'browser'
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Project-URL: Homepage, https://github.com/MayankPunghal/ferret
|
|
8
|
+
Provides-Extra: browser
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
<p align="center"><img src="src/site2md/static/favicon.svg" width="88" alt=""></p>
|
|
12
|
+
|
|
13
|
+
<h1 align="center">Ferret Crawler</h1>
|
|
14
|
+
|
|
15
|
+
<p align="center">Part of <a href="../README.md">Ferret</a>. Command-line name: <code>site2md</code> (or <code>ferret-crawler</code>).</p>
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
Save a website or intranet as Markdown files, one per page, for a search index (such as Ferret),
|
|
19
|
+
an LLM tool or an offline copy. Standard-library Python; a real browser is optional for sites behind a login.
|
|
20
|
+
|
|
21
|
+
## The easy way (no setup)
|
|
22
|
+
|
|
23
|
+
1. Unzip this folder anywhere.
|
|
24
|
+
2. Double-click **`Crawl Website.bat`** (Windows) or **`Crawl Website.command`** (macOS; on Linux run
|
|
25
|
+
`bash "Crawl Website.command"`). A page opens in your browser; keep the small black window open while you
|
|
26
|
+
copy (closing it stops the crawler).
|
|
27
|
+
3. **Copy a website** → paste the address. The page checks it at once ("Found “Engineering Wiki”", or "this
|
|
28
|
+
address asks you to sign in"). Give the copy a name and press **Start copying**. For a site behind a
|
|
29
|
+
sign-in, a browser window opens: sign in there; the page notices and starts copying by itself.
|
|
30
|
+
|
|
31
|
+
While it copies you see each section of the site filling in, with Pause and Stop. When it is done, the page
|
|
32
|
+
lists what was not copied, grouped by reason ("page not found · 12"), with **Try these again**, and can
|
|
33
|
+
**send the copy to Ferret**.
|
|
34
|
+
|
|
35
|
+
The copies are in `output/<name>/`, one Markdown file per page, next to the original PDF, Word and
|
|
36
|
+
PowerPoint files the pages link to or embed. The first run installs what it needs (uv, Python, about 1–2
|
|
37
|
+
minutes; the internet is needed for that). **Your copies** lists them, with **Update** (copy the site again;
|
|
38
|
+
the old copy is kept until the new one is finished), **Continue** for a stopped copy, Open folder and Delete.
|
|
39
|
+
|
|
40
|
+
Sign-ins use Google Chrome or Microsoft Edge already on the computer (or a Chromium downloaded with
|
|
41
|
+
`uv run --extra browser playwright install chromium`). The sign-in is kept on your computer only, in
|
|
42
|
+
`~/.site2md/profile-<browser>`. Delete that folder to sign out. The crawler never sees your password.
|
|
43
|
+
|
|
44
|
+
**Original HTML (optional):** *More options → Also keep each page's original HTML* saves each page's HTML in
|
|
45
|
+
`output/<name>-html/`, next to the copy rather than in it, to check what a page held. It is not sent to
|
|
46
|
+
Ferret: the Markdown already keeps the structure that search uses (headings, lists, tables, code,
|
|
47
|
+
links), and indexing the same page twice would crowd results with duplicates.
|
|
48
|
+
|
|
49
|
+
The page listens on 127.0.0.1 only, at an address with a one-time key, so other computers and other web
|
|
50
|
+
pages cannot use it. `site2md ui --copies <folder>` opens it from a command line; `site2md <url> --out
|
|
51
|
+
<folder>` still copies without the page.
|
|
52
|
+
|
|
53
|
+
## Install as a command (technical users)
|
|
54
|
+
|
|
55
|
+
Needs Python 3.11+ (or [uv](https://docs.astral.sh/uv/), which installs Python for you).
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
uv tool install "site2md[browser] @ ./site2md" # this folder; or: pipx install "./site2md[browser]"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Use
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
site2md https://docs.example.com/ --out example-docs
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Sites behind a company login (Google Sites, SharePoint, Confluence with SSO) — sign in once in a browser
|
|
68
|
+
window, then crawl with that session (kept in `~/.site2md/profile-<channel>`, on your machine only):
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
site2md "https://sites.google.com/acme.com/intranet/home" --out intranet --browser --login --channel chrome
|
|
72
|
+
site2md "https://sites.google.com/acme.com/intranet/home" --out intranet --browser --channel chrome # later runs
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`--channel chrome` or `--channel msedge` uses the browser already installed. `--channel firefox` or
|
|
76
|
+
`--channel chromium` (the default) uses Playwright's own copy: run `playwright install firefox` (or
|
|
77
|
+
`chromium`) once. Other Chromium-based browsers (Brave, Vivaldi): `--browser-path` to the executable.
|
|
78
|
+
|
|
79
|
+
## What it does
|
|
80
|
+
|
|
81
|
+
- Follows **every link on every page** — content, navigation bar, header, footer, sidebars, frames,
|
|
82
|
+
`<link rel=next>` — plus `sitemap.xml`, until no new page is found (`--max-pages`, default 10,000).
|
|
83
|
+
- Stays under the start URL's folder (`https://host/docs/intro.html` → `https://host/docs/`); `--prefix` sets
|
|
84
|
+
other prefixes (repeatable), `--allow-host` adds whole hosts.
|
|
85
|
+
- Never follows logout, delete, edit, print or feed links; respects robots.txt unless `--ignore-robots`.
|
|
86
|
+
- Writes `<page>.md` for every page, with front matter (`title`, `source_url`, `crawled_at`) and the page's
|
|
87
|
+
text (menus and footers dropped; when the page's `<main>` element misses part of its text, as on Google
|
|
88
|
+
Sites, the whole page is used). Scrolls through each page first, so text drawn when it comes into view is
|
|
89
|
+
included.
|
|
90
|
+
- Saves linked PDF, Word and PowerPoint files **as they are**, under their own names ("Leave Policy (1).pdf") — nothing
|
|
91
|
+
is converted, so nothing can be lost; a search index reads them itself (Ferret does, page by page).
|
|
92
|
+
- Downloads the Google Drive files, Docs (as Word) and Slides (as PDF) a page embeds or links to — the PDF
|
|
93
|
+
viewers on Google Sites pages — and the files in embedded Drive folders, with the same sign-in, and links
|
|
94
|
+
them from the page ("Attached documents"). Only PDF, Word and PowerPoint files are kept, up to 500 MB:
|
|
95
|
+
videos and spreadsheets uploaded to Drive are recognised by name before downloading and skipped (listed in
|
|
96
|
+
the manifest). For files over 100 MB it answers Google's "Download anyway" prompt itself.
|
|
97
|
+
- `--save-html` also keeps the HTML each page was converted from (in `<out>-html/`), to check what a page
|
|
98
|
+
held.
|
|
99
|
+
- Saves a page reached under several URLs once; rewrites links between crawled pages to the local files;
|
|
100
|
+
removes a title suffix shared by most pages (" | Company Wiki").
|
|
101
|
+
- `manifest.json`: every URL → file, failures (e.g. "sign-in page"), skips and the remaining queue;
|
|
102
|
+
`--resume` continues an interrupted crawl. Ctrl+C stops a crawl cleanly (links fixed, manifest saved).
|
|
103
|
+
|
|
104
|
+
Pages with no text of their own (only a title or headings) are not written; the manifest lists them under
|
|
105
|
+
`skipped`. Without `--browser`, pages that build their content with JavaScript are among them. `--resume` also retries the URLs that failed. Embedded Google Sheets and Calendars, forms,
|
|
106
|
+
videos and files whose owner disabled downloads are not saved; the manifest lists them. The copy has no access control: keep it where only the intended readers can open it.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<p align="center"><img src="src/site2md/static/favicon.svg" width="88" alt=""></p>
|
|
2
|
+
|
|
3
|
+
<h1 align="center">Ferret Crawler</h1>
|
|
4
|
+
|
|
5
|
+
<p align="center">Part of <a href="../README.md">Ferret</a>. Command-line name: <code>site2md</code> (or <code>ferret-crawler</code>).</p>
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Save a website or intranet as Markdown files, one per page, for a search index (such as Ferret),
|
|
9
|
+
an LLM tool or an offline copy. Standard-library Python; a real browser is optional for sites behind a login.
|
|
10
|
+
|
|
11
|
+
## The easy way (no setup)
|
|
12
|
+
|
|
13
|
+
1. Unzip this folder anywhere.
|
|
14
|
+
2. Double-click **`Crawl Website.bat`** (Windows) or **`Crawl Website.command`** (macOS; on Linux run
|
|
15
|
+
`bash "Crawl Website.command"`). A page opens in your browser; keep the small black window open while you
|
|
16
|
+
copy (closing it stops the crawler).
|
|
17
|
+
3. **Copy a website** → paste the address. The page checks it at once ("Found “Engineering Wiki”", or "this
|
|
18
|
+
address asks you to sign in"). Give the copy a name and press **Start copying**. For a site behind a
|
|
19
|
+
sign-in, a browser window opens: sign in there; the page notices and starts copying by itself.
|
|
20
|
+
|
|
21
|
+
While it copies you see each section of the site filling in, with Pause and Stop. When it is done, the page
|
|
22
|
+
lists what was not copied, grouped by reason ("page not found · 12"), with **Try these again**, and can
|
|
23
|
+
**send the copy to Ferret**.
|
|
24
|
+
|
|
25
|
+
The copies are in `output/<name>/`, one Markdown file per page, next to the original PDF, Word and
|
|
26
|
+
PowerPoint files the pages link to or embed. The first run installs what it needs (uv, Python, about 1–2
|
|
27
|
+
minutes; the internet is needed for that). **Your copies** lists them, with **Update** (copy the site again;
|
|
28
|
+
the old copy is kept until the new one is finished), **Continue** for a stopped copy, Open folder and Delete.
|
|
29
|
+
|
|
30
|
+
Sign-ins use Google Chrome or Microsoft Edge already on the computer (or a Chromium downloaded with
|
|
31
|
+
`uv run --extra browser playwright install chromium`). The sign-in is kept on your computer only, in
|
|
32
|
+
`~/.site2md/profile-<browser>`. Delete that folder to sign out. The crawler never sees your password.
|
|
33
|
+
|
|
34
|
+
**Original HTML (optional):** *More options → Also keep each page's original HTML* saves each page's HTML in
|
|
35
|
+
`output/<name>-html/`, next to the copy rather than in it, to check what a page held. It is not sent to
|
|
36
|
+
Ferret: the Markdown already keeps the structure that search uses (headings, lists, tables, code,
|
|
37
|
+
links), and indexing the same page twice would crowd results with duplicates.
|
|
38
|
+
|
|
39
|
+
The page listens on 127.0.0.1 only, at an address with a one-time key, so other computers and other web
|
|
40
|
+
pages cannot use it. `site2md ui --copies <folder>` opens it from a command line; `site2md <url> --out
|
|
41
|
+
<folder>` still copies without the page.
|
|
42
|
+
|
|
43
|
+
## Install as a command (technical users)
|
|
44
|
+
|
|
45
|
+
Needs Python 3.11+ (or [uv](https://docs.astral.sh/uv/), which installs Python for you).
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
uv tool install "site2md[browser] @ ./site2md" # this folder; or: pipx install "./site2md[browser]"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Use
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
site2md https://docs.example.com/ --out example-docs
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Sites behind a company login (Google Sites, SharePoint, Confluence with SSO) — sign in once in a browser
|
|
58
|
+
window, then crawl with that session (kept in `~/.site2md/profile-<channel>`, on your machine only):
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
site2md "https://sites.google.com/acme.com/intranet/home" --out intranet --browser --login --channel chrome
|
|
62
|
+
site2md "https://sites.google.com/acme.com/intranet/home" --out intranet --browser --channel chrome # later runs
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`--channel chrome` or `--channel msedge` uses the browser already installed. `--channel firefox` or
|
|
66
|
+
`--channel chromium` (the default) uses Playwright's own copy: run `playwright install firefox` (or
|
|
67
|
+
`chromium`) once. Other Chromium-based browsers (Brave, Vivaldi): `--browser-path` to the executable.
|
|
68
|
+
|
|
69
|
+
## What it does
|
|
70
|
+
|
|
71
|
+
- Follows **every link on every page** — content, navigation bar, header, footer, sidebars, frames,
|
|
72
|
+
`<link rel=next>` — plus `sitemap.xml`, until no new page is found (`--max-pages`, default 10,000).
|
|
73
|
+
- Stays under the start URL's folder (`https://host/docs/intro.html` → `https://host/docs/`); `--prefix` sets
|
|
74
|
+
other prefixes (repeatable), `--allow-host` adds whole hosts.
|
|
75
|
+
- Never follows logout, delete, edit, print or feed links; respects robots.txt unless `--ignore-robots`.
|
|
76
|
+
- Writes `<page>.md` for every page, with front matter (`title`, `source_url`, `crawled_at`) and the page's
|
|
77
|
+
text (menus and footers dropped; when the page's `<main>` element misses part of its text, as on Google
|
|
78
|
+
Sites, the whole page is used). Scrolls through each page first, so text drawn when it comes into view is
|
|
79
|
+
included.
|
|
80
|
+
- Saves linked PDF, Word and PowerPoint files **as they are**, under their own names ("Leave Policy (1).pdf") — nothing
|
|
81
|
+
is converted, so nothing can be lost; a search index reads them itself (Ferret does, page by page).
|
|
82
|
+
- Downloads the Google Drive files, Docs (as Word) and Slides (as PDF) a page embeds or links to — the PDF
|
|
83
|
+
viewers on Google Sites pages — and the files in embedded Drive folders, with the same sign-in, and links
|
|
84
|
+
them from the page ("Attached documents"). Only PDF, Word and PowerPoint files are kept, up to 500 MB:
|
|
85
|
+
videos and spreadsheets uploaded to Drive are recognised by name before downloading and skipped (listed in
|
|
86
|
+
the manifest). For files over 100 MB it answers Google's "Download anyway" prompt itself.
|
|
87
|
+
- `--save-html` also keeps the HTML each page was converted from (in `<out>-html/`), to check what a page
|
|
88
|
+
held.
|
|
89
|
+
- Saves a page reached under several URLs once; rewrites links between crawled pages to the local files;
|
|
90
|
+
removes a title suffix shared by most pages (" | Company Wiki").
|
|
91
|
+
- `manifest.json`: every URL → file, failures (e.g. "sign-in page"), skips and the remaining queue;
|
|
92
|
+
`--resume` continues an interrupted crawl. Ctrl+C stops a crawl cleanly (links fixed, manifest saved).
|
|
93
|
+
|
|
94
|
+
Pages with no text of their own (only a title or headings) are not written; the manifest lists them under
|
|
95
|
+
`skipped`. Without `--browser`, pages that build their content with JavaScript are among them. `--resume` also retries the URLs that failed. Embedded Google Sheets and Calendars, forms,
|
|
96
|
+
videos and files whose owner disabled downloads are not saved; the manifest lists them. The copy has no access control: keep it where only the intended readers can open it.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ferret-crawler"
|
|
3
|
+
version = "1.1.0"
|
|
4
|
+
description = "Save a website or intranet as Markdown files, one per page (for search indexes and LLM tools)"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
dependencies = []
|
|
8
|
+
|
|
9
|
+
[project.optional-dependencies]
|
|
10
|
+
browser = ["playwright>=1.48"]
|
|
11
|
+
|
|
12
|
+
[project.scripts]
|
|
13
|
+
ferret-crawler = "site2md:main"
|
|
14
|
+
site2md = "site2md:main"
|
|
15
|
+
|
|
16
|
+
[project.urls]
|
|
17
|
+
Homepage = "https://github.com/MayankPunghal/ferret"
|
|
18
|
+
|
|
19
|
+
[build-system]
|
|
20
|
+
requires = ["uv_build>=0.11.32,<0.12.0"]
|
|
21
|
+
build-backend = "uv_build"
|
|
22
|
+
|
|
23
|
+
[tool.uv.build-backend]
|
|
24
|
+
module-name = "site2md"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ferret-crawler"
|
|
3
|
+
version = "1.1.0"
|
|
4
|
+
description = "Save a website or intranet as Markdown files, one per page (for search indexes and LLM tools)"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
dependencies = []
|
|
8
|
+
|
|
9
|
+
[project.optional-dependencies]
|
|
10
|
+
browser = ["playwright>=1.48"]
|
|
11
|
+
|
|
12
|
+
[project.scripts]
|
|
13
|
+
ferret-crawler = "site2md:main"
|
|
14
|
+
site2md = "site2md:main"
|
|
15
|
+
|
|
16
|
+
[project.urls]
|
|
17
|
+
Homepage = "https://github.com/MayankPunghal/ferret"
|
|
18
|
+
|
|
19
|
+
[build-system]
|
|
20
|
+
requires = ["uv_build>=0.11.32,<0.12.0"]
|
|
21
|
+
build-backend = "uv_build"
|
|
22
|
+
|
|
23
|
+
[tool.uv.build-backend]
|
|
24
|
+
module-name = "site2md"
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""site2md: save a website or intranet as Markdown files, one per page (see crawl.py)."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
__version__ = "1.1.0"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main(argv: list[str] | None = None) -> None:
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
args = sys.argv[1:] if argv is None else argv
|
|
13
|
+
if not args or args[0] == "ui": # the page in the browser (Crawl Website launchers)
|
|
14
|
+
from . import ui
|
|
15
|
+
|
|
16
|
+
p = argparse.ArgumentParser(prog="site2md ui", description="Open Ferret Crawler's page in your browser.")
|
|
17
|
+
p.add_argument("--copies", default="", help="folder for the copies (default ~/site2md)")
|
|
18
|
+
p.add_argument("--no-browser", action="store_true", help="only print the address")
|
|
19
|
+
a = p.parse_args(args[1:])
|
|
20
|
+
ui.main(a.copies, open_browser=not a.no_browser)
|
|
21
|
+
return
|
|
22
|
+
from .crawl import BrowserFetcher, Crawler
|
|
23
|
+
|
|
24
|
+
ap = argparse.ArgumentParser(prog="site2md", description="Save a website as Markdown files, one per page.")
|
|
25
|
+
ap.add_argument("url", help="start page")
|
|
26
|
+
ap.add_argument("--out", required=True, help="output directory")
|
|
27
|
+
ap.add_argument("--max-pages", type=int, default=10_000)
|
|
28
|
+
ap.add_argument("--prefix", action="append", help="only URLs starting with this (repeatable; default: the start URL's folder)")
|
|
29
|
+
ap.add_argument("--allow-host", action="append", help="also follow links anywhere on this host (repeatable)")
|
|
30
|
+
ap.add_argument("--header", action="append", default=[], help="extra request header, e.g. 'Authorization: Bearer ...'")
|
|
31
|
+
ap.add_argument("--workers", type=int, default=4)
|
|
32
|
+
ap.add_argument("--delay", type=float, default=0.2, help="seconds each worker waits between requests")
|
|
33
|
+
ap.add_argument("--ignore-robots", action="store_true", help="ignore robots.txt (only for your own sites)")
|
|
34
|
+
ap.add_argument("--no-files", action="store_true", help="do not save linked PDF/Word/text files")
|
|
35
|
+
ap.add_argument("--resume", action="store_true", help="continue an interrupted crawl in --out")
|
|
36
|
+
ap.add_argument("--follow", choices=("site", "linked", "everything"), default="linked",
|
|
37
|
+
help="links leaving the start folder: site = never; linked (default) = a link in a page's content "
|
|
38
|
+
"brings in the folder it points to; everything = every link anywhere, up to --max-pages")
|
|
39
|
+
b = ap.add_argument_group("browser (sites behind a login or built with JavaScript; needs: pip install playwright)")
|
|
40
|
+
b.add_argument("--browser", action="store_true", help="fetch pages with a real browser")
|
|
41
|
+
b.add_argument("--login", action="store_true", help="open a browser window to sign in first (saved for next time)")
|
|
42
|
+
b.add_argument("--channel", default="chromium", help="chrome or msedge (the installed browser), or firefox / "
|
|
43
|
+
"chromium (Playwright's own, once: playwright install firefox|chromium); default chromium")
|
|
44
|
+
b.add_argument("--profile", default="", help="where the browser keeps the sign-in "
|
|
45
|
+
"(default: ~/.site2md/profile-<channel>, one per browser)")
|
|
46
|
+
b.add_argument("--show-browser", action="store_true", help="show the browser window while crawling")
|
|
47
|
+
b.add_argument("--browser-path", default="", help="path to a Chromium/Chrome executable")
|
|
48
|
+
ap.add_argument("--save-html", action="store_true", help="also keep the HTML each page was converted from, "
|
|
49
|
+
"in <out>-html (to check what a page held)")
|
|
50
|
+
a = ap.parse_args(args)
|
|
51
|
+
fetcher = None
|
|
52
|
+
a.profile = a.profile or str(Path.home() / ".site2md" / f"profile-{a.channel}")
|
|
53
|
+
if a.browser or a.login:
|
|
54
|
+
Path(a.profile).mkdir(parents=True, exist_ok=True)
|
|
55
|
+
if a.login:
|
|
56
|
+
login = BrowserFetcher(Path(a.profile), a.channel, headless=False, executable=a.browser_path)
|
|
57
|
+
login.login(a.url)
|
|
58
|
+
login.close()
|
|
59
|
+
fetcher = BrowserFetcher(Path(a.profile), a.channel, headless=not a.show_browser, executable=a.browser_path)
|
|
60
|
+
headers = dict(h.split(":", 1) for h in a.header)
|
|
61
|
+
try:
|
|
62
|
+
Crawler(a.url, Path(a.out), prefixes=a.prefix, allow_hosts=a.allow_host, max_pages=a.max_pages,
|
|
63
|
+
workers=a.workers, delay=a.delay, headers={k.strip(): v.strip() for k, v in headers.items()},
|
|
64
|
+
robots=not a.ignore_robots, files=not a.no_files, browser=fetcher,
|
|
65
|
+
save_html=Path(str(Path(a.out)) + "-html") if a.save_html else None, follow=a.follow).run(resume=a.resume)
|
|
66
|
+
finally:
|
|
67
|
+
if fetcher:
|
|
68
|
+
fetcher.close()
|