scrapedesk 1.0.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.
- scrapedesk-1.0.0/LICENSE +21 -0
- scrapedesk-1.0.0/PKG-INFO +163 -0
- scrapedesk-1.0.0/README.md +115 -0
- scrapedesk-1.0.0/pyproject.toml +74 -0
- scrapedesk-1.0.0/setup.cfg +4 -0
- scrapedesk-1.0.0/src/scrapedesk/__init__.py +7 -0
- scrapedesk-1.0.0/src/scrapedesk/__main__.py +15 -0
- scrapedesk-1.0.0/src/scrapedesk/assets/icon.ico +0 -0
- scrapedesk-1.0.0/src/scrapedesk/assets/icon.png +0 -0
- scrapedesk-1.0.0/src/scrapedesk/assets/icon64.png +0 -0
- scrapedesk-1.0.0/src/scrapedesk/cli.py +100 -0
- scrapedesk-1.0.0/src/scrapedesk/core.py +1073 -0
- scrapedesk-1.0.0/src/scrapedesk/exporters.py +171 -0
- scrapedesk-1.0.0/src/scrapedesk/gui/__init__.py +1 -0
- scrapedesk-1.0.0/src/scrapedesk/gui/app.py +1849 -0
- scrapedesk-1.0.0/src/scrapedesk/gui/theme.py +239 -0
- scrapedesk-1.0.0/src/scrapedesk/gui/widgets.py +604 -0
- scrapedesk-1.0.0/src/scrapedesk.egg-info/PKG-INFO +163 -0
- scrapedesk-1.0.0/src/scrapedesk.egg-info/SOURCES.txt +22 -0
- scrapedesk-1.0.0/src/scrapedesk.egg-info/dependency_links.txt +1 -0
- scrapedesk-1.0.0/src/scrapedesk.egg-info/entry_points.txt +5 -0
- scrapedesk-1.0.0/src/scrapedesk.egg-info/requires.txt +21 -0
- scrapedesk-1.0.0/src/scrapedesk.egg-info/top_level.txt +1 -0
- scrapedesk-1.0.0/tests/test_core.py +131 -0
scrapedesk-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Engr. Mubashir Hussain
|
|
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.
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: scrapedesk
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A friendly desktop web scraper: grab images, tables, links and text from any website and export to Excel, CSV, JSON or SQLite.
|
|
5
|
+
Author-email: "Engr. Mubashir Hussain" <mubashir6u@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Keywords: web scraping,scraper,gui,tkinter,images,tables,excel,csv,crawler,beautifulsoup,data extraction,desktop
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Environment :: MacOS X
|
|
10
|
+
Classifier: Environment :: Win32 (MS Windows)
|
|
11
|
+
Classifier: Environment :: X11 Applications
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
24
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
|
|
25
|
+
Classifier: Topic :: Office/Business
|
|
26
|
+
Classifier: Topic :: Utilities
|
|
27
|
+
Requires-Python: >=3.9
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: requests>=2.31
|
|
31
|
+
Requires-Dist: beautifulsoup4>=4.12
|
|
32
|
+
Requires-Dist: lxml>=5.0
|
|
33
|
+
Requires-Dist: pandas>=2.0
|
|
34
|
+
Requires-Dist: openpyxl>=3.1
|
|
35
|
+
Requires-Dist: pillow>=10.0
|
|
36
|
+
Provides-Extra: js
|
|
37
|
+
Requires-Dist: playwright>=1.40; extra == "js"
|
|
38
|
+
Provides-Extra: selenium
|
|
39
|
+
Requires-Dist: selenium>=4.15; extra == "selenium"
|
|
40
|
+
Provides-Extra: all
|
|
41
|
+
Requires-Dist: playwright>=1.40; extra == "all"
|
|
42
|
+
Requires-Dist: selenium>=4.15; extra == "all"
|
|
43
|
+
Provides-Extra: dev
|
|
44
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
45
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
46
|
+
Requires-Dist: twine>=5; extra == "dev"
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
|
|
49
|
+
# ScrapeDesk
|
|
50
|
+
|
|
51
|
+
**A friendly desktop web scraper.** Paste a link, choose what you want (images, tables, links, text, emails or custom fields) and export it to Excel, CSV, JSON, SQLite and more. You don't need to write any code.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install scrapedesk
|
|
55
|
+
scrapedesk
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Works on Windows, macOS and Linux with Python 3.9+.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Highlights
|
|
63
|
+
|
|
64
|
+
| | |
|
|
65
|
+
|---|---|
|
|
66
|
+
| **Easy to use** | Sidebar navigation, big toggle cards, live result counters, tooltips, notifications, light and dark mode, and keyboard shortcuts |
|
|
67
|
+
| **Images** | Thumbnail gallery with click-to-select and a full-size viewer. Finds `img`, `srcset`, lazy-loaded (`data-src` and more), `<picture>`, CSS backgrounds, `og:image`, icons and linked image files |
|
|
68
|
+
| **Smart downloads** | Filter by type, width/height and file size. Removes duplicates, downloads in parallel, renames, and converts to PNG/JPG/WEBP |
|
|
69
|
+
| **Tables** | Every `<table>`, including merged cells (`colspan`/`rowspan`) and multi-row headers. Can also turn product grids and lists into tables. Sort, filter, merge, and copy to Excel |
|
|
70
|
+
| **Exports** | Excel (one sheet per table), CSV, TSV, JSON, HTML, SQLite and Markdown, or *everything* in one workbook |
|
|
71
|
+
| **Custom fields** | Pick exact values (title, price, rating, link…) with CSS or XPath and get one row per item |
|
|
72
|
+
| **More pages** | Follows "Next page" pagination and crawls links with depth, page limits and include/exclude rules |
|
|
73
|
+
| **Tough sites** | Browser identities, headers, cookies, proxy, retries, request delay, robots.txt, and optional JavaScript rendering |
|
|
74
|
+
|
|
75
|
+
## Install
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install scrapedesk
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Start the app:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
scrapedesk # or: python -m scrapedesk
|
|
85
|
+
scrapedesk https://example.com # open with a URL already filled in
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
> **Linux:** tkinter is sometimes packaged separately: `sudo apt install python3-tk`.
|
|
89
|
+
|
|
90
|
+
### JavaScript-heavy websites (optional)
|
|
91
|
+
|
|
92
|
+
If a site builds its content with JavaScript (React or Vue apps, infinite scroll), install the browser extra and turn on **Settings → JavaScript websites → Playwright**:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pip install "scrapedesk[js]"
|
|
96
|
+
python -m playwright install chromium
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
If you skip the last step, ScrapeDesk falls back to an installed Google Chrome or Microsoft Edge.
|
|
100
|
+
|
|
101
|
+
## How to use
|
|
102
|
+
|
|
103
|
+
1. **Home:** paste a URL (or several), then click the cards for what you want to collect and press **Start**.
|
|
104
|
+
2. Watch the counters update. When the job finishes, a notification takes you to the results.
|
|
105
|
+
3. **Images:** click thumbnails to select them, double-click to see full size, then **Download selected**.
|
|
106
|
+
4. **Tables:** pick a table, then **Export** it (Excel, CSV…) or **Copy** it straight into Excel.
|
|
107
|
+
5. **Custom Fields:** press **Load example** to see how product names and prices are extracted.
|
|
108
|
+
6. Press **Ctrl+E** to export everything in one Excel workbook.
|
|
109
|
+
|
|
110
|
+
Keyboard shortcuts:
|
|
111
|
+
|
|
112
|
+
| Keys | Action |
|
|
113
|
+
|---|---|
|
|
114
|
+
| Enter / Ctrl+Enter | Start |
|
|
115
|
+
| Esc | Stop |
|
|
116
|
+
| Ctrl+1…9 | Switch section |
|
|
117
|
+
| Ctrl+E | Export all |
|
|
118
|
+
| Ctrl+D | Dark mode |
|
|
119
|
+
| F1 | Help |
|
|
120
|
+
|
|
121
|
+
## Command line
|
|
122
|
+
|
|
123
|
+
Everything also works without the window:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# all images wider than 300 px
|
|
127
|
+
scrapedesk-cli https://example.com --images --download --min-width 300 --types jpg,png
|
|
128
|
+
|
|
129
|
+
# every table to Excel
|
|
130
|
+
scrapedesk-cli https://example.com/stats --tables -o stats.xlsx
|
|
131
|
+
|
|
132
|
+
# one row per product across 50 pages
|
|
133
|
+
scrapedesk-cli https://books.toscrape.com --paginate --max-pages 50 \
|
|
134
|
+
--row article.product_pod --css "title=h3 a@title" --css "price=.price_color" -o books.csv
|
|
135
|
+
|
|
136
|
+
# crawl a site and export everything
|
|
137
|
+
scrapedesk-cli https://example.com --crawl --depth 2 --max-pages 100 --report everything.xlsx
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Run `scrapedesk-cli --help` for all options.
|
|
141
|
+
|
|
142
|
+
## Use it from Python
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from scrapedesk import ScrapeSettings, WebScraper
|
|
146
|
+
from scrapedesk.exporters import export_dataframes, tables_to_frames
|
|
147
|
+
|
|
148
|
+
settings = ScrapeSettings(extract_images=True, extract_tables=True, min_width=200)
|
|
149
|
+
scraper = WebScraper(settings)
|
|
150
|
+
pages = scraper.run(["https://example.com"])
|
|
151
|
+
|
|
152
|
+
tables = [t for p in pages for t in p.tables]
|
|
153
|
+
export_dataframes(tables_to_frames(tables), "tables.xlsx")
|
|
154
|
+
scraper.download_images([img for p in pages for img in p.images])
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Responsible use
|
|
158
|
+
|
|
159
|
+
Only scrape content you are allowed to access. Respect each website's terms of service, robots.txt (there is a setting for it) and rate limits (use the delay setting), and follow privacy laws such as GDPR when you collect personal data. ScrapeDesk does not bypass logins, CAPTCHAs or anti-bot protection.
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
MIT
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# ScrapeDesk
|
|
2
|
+
|
|
3
|
+
**A friendly desktop web scraper.** Paste a link, choose what you want (images, tables, links, text, emails or custom fields) and export it to Excel, CSV, JSON, SQLite and more. You don't need to write any code.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install scrapedesk
|
|
7
|
+
scrapedesk
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Works on Windows, macOS and Linux with Python 3.9+.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Highlights
|
|
15
|
+
|
|
16
|
+
| | |
|
|
17
|
+
|---|---|
|
|
18
|
+
| **Easy to use** | Sidebar navigation, big toggle cards, live result counters, tooltips, notifications, light and dark mode, and keyboard shortcuts |
|
|
19
|
+
| **Images** | Thumbnail gallery with click-to-select and a full-size viewer. Finds `img`, `srcset`, lazy-loaded (`data-src` and more), `<picture>`, CSS backgrounds, `og:image`, icons and linked image files |
|
|
20
|
+
| **Smart downloads** | Filter by type, width/height and file size. Removes duplicates, downloads in parallel, renames, and converts to PNG/JPG/WEBP |
|
|
21
|
+
| **Tables** | Every `<table>`, including merged cells (`colspan`/`rowspan`) and multi-row headers. Can also turn product grids and lists into tables. Sort, filter, merge, and copy to Excel |
|
|
22
|
+
| **Exports** | Excel (one sheet per table), CSV, TSV, JSON, HTML, SQLite and Markdown, or *everything* in one workbook |
|
|
23
|
+
| **Custom fields** | Pick exact values (title, price, rating, link…) with CSS or XPath and get one row per item |
|
|
24
|
+
| **More pages** | Follows "Next page" pagination and crawls links with depth, page limits and include/exclude rules |
|
|
25
|
+
| **Tough sites** | Browser identities, headers, cookies, proxy, retries, request delay, robots.txt, and optional JavaScript rendering |
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install scrapedesk
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Start the app:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
scrapedesk # or: python -m scrapedesk
|
|
37
|
+
scrapedesk https://example.com # open with a URL already filled in
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
> **Linux:** tkinter is sometimes packaged separately: `sudo apt install python3-tk`.
|
|
41
|
+
|
|
42
|
+
### JavaScript-heavy websites (optional)
|
|
43
|
+
|
|
44
|
+
If a site builds its content with JavaScript (React or Vue apps, infinite scroll), install the browser extra and turn on **Settings → JavaScript websites → Playwright**:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install "scrapedesk[js]"
|
|
48
|
+
python -m playwright install chromium
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
If you skip the last step, ScrapeDesk falls back to an installed Google Chrome or Microsoft Edge.
|
|
52
|
+
|
|
53
|
+
## How to use
|
|
54
|
+
|
|
55
|
+
1. **Home:** paste a URL (or several), then click the cards for what you want to collect and press **Start**.
|
|
56
|
+
2. Watch the counters update. When the job finishes, a notification takes you to the results.
|
|
57
|
+
3. **Images:** click thumbnails to select them, double-click to see full size, then **Download selected**.
|
|
58
|
+
4. **Tables:** pick a table, then **Export** it (Excel, CSV…) or **Copy** it straight into Excel.
|
|
59
|
+
5. **Custom Fields:** press **Load example** to see how product names and prices are extracted.
|
|
60
|
+
6. Press **Ctrl+E** to export everything in one Excel workbook.
|
|
61
|
+
|
|
62
|
+
Keyboard shortcuts:
|
|
63
|
+
|
|
64
|
+
| Keys | Action |
|
|
65
|
+
|---|---|
|
|
66
|
+
| Enter / Ctrl+Enter | Start |
|
|
67
|
+
| Esc | Stop |
|
|
68
|
+
| Ctrl+1…9 | Switch section |
|
|
69
|
+
| Ctrl+E | Export all |
|
|
70
|
+
| Ctrl+D | Dark mode |
|
|
71
|
+
| F1 | Help |
|
|
72
|
+
|
|
73
|
+
## Command line
|
|
74
|
+
|
|
75
|
+
Everything also works without the window:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# all images wider than 300 px
|
|
79
|
+
scrapedesk-cli https://example.com --images --download --min-width 300 --types jpg,png
|
|
80
|
+
|
|
81
|
+
# every table to Excel
|
|
82
|
+
scrapedesk-cli https://example.com/stats --tables -o stats.xlsx
|
|
83
|
+
|
|
84
|
+
# one row per product across 50 pages
|
|
85
|
+
scrapedesk-cli https://books.toscrape.com --paginate --max-pages 50 \
|
|
86
|
+
--row article.product_pod --css "title=h3 a@title" --css "price=.price_color" -o books.csv
|
|
87
|
+
|
|
88
|
+
# crawl a site and export everything
|
|
89
|
+
scrapedesk-cli https://example.com --crawl --depth 2 --max-pages 100 --report everything.xlsx
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Run `scrapedesk-cli --help` for all options.
|
|
93
|
+
|
|
94
|
+
## Use it from Python
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from scrapedesk import ScrapeSettings, WebScraper
|
|
98
|
+
from scrapedesk.exporters import export_dataframes, tables_to_frames
|
|
99
|
+
|
|
100
|
+
settings = ScrapeSettings(extract_images=True, extract_tables=True, min_width=200)
|
|
101
|
+
scraper = WebScraper(settings)
|
|
102
|
+
pages = scraper.run(["https://example.com"])
|
|
103
|
+
|
|
104
|
+
tables = [t for p in pages for t in p.tables]
|
|
105
|
+
export_dataframes(tables_to_frames(tables), "tables.xlsx")
|
|
106
|
+
scraper.download_images([img for p in pages for img in p.images])
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Responsible use
|
|
110
|
+
|
|
111
|
+
Only scrape content you are allowed to access. Respect each website's terms of service, robots.txt (there is a setting for it) and rate limits (use the delay setting), and follow privacy laws such as GDPR when you collect personal data. ScrapeDesk does not bypass logins, CAPTCHAs or anti-bot protection.
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
MIT
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "scrapedesk"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "A friendly desktop web scraper: grab images, tables, links and text from any website and export to Excel, CSV, JSON or SQLite."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Engr. Mubashir Hussain", email = "mubashir6u@gmail.com" }]
|
|
14
|
+
keywords = ["web scraping", "scraper", "gui", "tkinter", "images", "tables", "excel", "csv", "crawler",
|
|
15
|
+
"beautifulsoup", "data extraction", "desktop"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Environment :: MacOS X",
|
|
19
|
+
"Environment :: Win32 (MS Windows)",
|
|
20
|
+
"Environment :: X11 Applications",
|
|
21
|
+
"Intended Audience :: End Users/Desktop",
|
|
22
|
+
"Intended Audience :: Developers",
|
|
23
|
+
"Intended Audience :: Science/Research",
|
|
24
|
+
"Operating System :: OS Independent",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
27
|
+
"Programming Language :: Python :: 3.9",
|
|
28
|
+
"Programming Language :: Python :: 3.10",
|
|
29
|
+
"Programming Language :: Python :: 3.11",
|
|
30
|
+
"Programming Language :: Python :: 3.12",
|
|
31
|
+
"Programming Language :: Python :: 3.13",
|
|
32
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
33
|
+
"Topic :: Internet :: WWW/HTTP :: Indexing/Search",
|
|
34
|
+
"Topic :: Office/Business",
|
|
35
|
+
"Topic :: Utilities",
|
|
36
|
+
]
|
|
37
|
+
dependencies = [
|
|
38
|
+
"requests>=2.31",
|
|
39
|
+
"beautifulsoup4>=4.12",
|
|
40
|
+
"lxml>=5.0",
|
|
41
|
+
"pandas>=2.0",
|
|
42
|
+
"openpyxl>=3.1",
|
|
43
|
+
"pillow>=10.0",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[project.optional-dependencies]
|
|
47
|
+
js = ["playwright>=1.40"]
|
|
48
|
+
selenium = ["selenium>=4.15"]
|
|
49
|
+
all = ["playwright>=1.40", "selenium>=4.15"]
|
|
50
|
+
dev = ["pytest>=7", "build>=1.0", "twine>=5"]
|
|
51
|
+
|
|
52
|
+
[project.scripts]
|
|
53
|
+
scrapedesk-cli = "scrapedesk.cli:main"
|
|
54
|
+
|
|
55
|
+
[project.gui-scripts]
|
|
56
|
+
scrapedesk = "scrapedesk.gui.app:main"
|
|
57
|
+
|
|
58
|
+
# Fill these in once the code is on GitHub - they appear as links on the PyPI page.
|
|
59
|
+
# [project.urls]
|
|
60
|
+
# Homepage = "https://github.com/<your-user>/scrapedesk"
|
|
61
|
+
# Issues = "https://github.com/<your-user>/scrapedesk/issues"
|
|
62
|
+
# Changelog = "https://github.com/<your-user>/scrapedesk/blob/main/CHANGELOG.md"
|
|
63
|
+
|
|
64
|
+
[tool.setuptools.dynamic]
|
|
65
|
+
version = { attr = "scrapedesk.__version__" }
|
|
66
|
+
|
|
67
|
+
[tool.setuptools.packages.find]
|
|
68
|
+
where = ["src"]
|
|
69
|
+
|
|
70
|
+
[tool.setuptools.package-data]
|
|
71
|
+
scrapedesk = ["assets/*.png", "assets/*.ico"]
|
|
72
|
+
|
|
73
|
+
[tool.pytest.ini_options]
|
|
74
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"""ScrapeDesk - a friendly desktop web scraper for images, tables, links and text."""
|
|
2
|
+
|
|
3
|
+
__version__ = "1.0.0"
|
|
4
|
+
|
|
5
|
+
from .core import ImageItem, PageResult, ScrapeSettings, TableItem, WebScraper # noqa: E402
|
|
6
|
+
|
|
7
|
+
__all__ = ["ScrapeSettings", "WebScraper", "PageResult", "ImageItem", "TableItem", "__version__"]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""`python -m scrapedesk` opens the GUI; `python -m scrapedesk --cli ...` runs the command line."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
if len(sys.argv) > 1 and sys.argv[1] == "--cli":
|
|
8
|
+
from .cli import main as cli_main
|
|
9
|
+
return cli_main(sys.argv[2:])
|
|
10
|
+
from .gui.app import main as gui_main
|
|
11
|
+
return gui_main()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
sys.exit(main())
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Command-line interface for ScrapeDesk (no GUI needed).
|
|
3
|
+
|
|
4
|
+
Examples
|
|
5
|
+
scrapedesk-cli https://example.com --images --download
|
|
6
|
+
scrapedesk-cli https://en.wikipedia.org/wiki/List_of_largest_cities --tables -o cities.xlsx
|
|
7
|
+
scrapedesk-cli https://books.toscrape.com --crawl --max-pages 20 --report report.xlsx
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import sys
|
|
12
|
+
|
|
13
|
+
from .core import ScrapeSettings, WebScraper, USER_AGENTS
|
|
14
|
+
from . import exporters, __version__
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def main(argv=None):
|
|
18
|
+
ap = argparse.ArgumentParser(prog="scrapedesk-cli", description="ScrapeDesk - scrape images, tables, "
|
|
19
|
+
"links and text from websites (command line)")
|
|
20
|
+
ap.add_argument("-V", "--version", action="version", version=f"%(prog)s {__version__}")
|
|
21
|
+
ap.add_argument("urls", nargs="+", help="URL(s) or local .html file(s)")
|
|
22
|
+
ap.add_argument("--images", action="store_true", help="extract images")
|
|
23
|
+
ap.add_argument("--tables", action="store_true", help="extract tables")
|
|
24
|
+
ap.add_argument("--links", action="store_true", help="extract links")
|
|
25
|
+
ap.add_argument("--text", action="store_true", help="extract text/meta/contacts")
|
|
26
|
+
ap.add_argument("--download", action="store_true", help="download the images found")
|
|
27
|
+
ap.add_argument("--dir", help="image download folder")
|
|
28
|
+
ap.add_argument("--min-width", type=int, default=0)
|
|
29
|
+
ap.add_argument("--min-height", type=int, default=0)
|
|
30
|
+
ap.add_argument("--types", help="comma separated image types, e.g. jpg,png,webp")
|
|
31
|
+
ap.add_argument("-o", "--output", help="export tables to this file (.xlsx .csv .json .html .db .md)")
|
|
32
|
+
ap.add_argument("--report", help="export EVERYTHING to .xlsx / .json / .db")
|
|
33
|
+
ap.add_argument("--crawl", action="store_true")
|
|
34
|
+
ap.add_argument("--depth", type=int, default=1)
|
|
35
|
+
ap.add_argument("--max-pages", type=int, default=20)
|
|
36
|
+
ap.add_argument("--paginate", action="store_true", help="follow 'next page' links")
|
|
37
|
+
ap.add_argument("--js", choices=["none", "playwright", "selenium"], default="none")
|
|
38
|
+
ap.add_argument("--delay", type=float, default=0.5)
|
|
39
|
+
ap.add_argument("--proxy", default="")
|
|
40
|
+
ap.add_argument("--ua", choices=list(USER_AGENTS), default="Chrome (Windows)")
|
|
41
|
+
ap.add_argument("--css", action="append", default=[], metavar="NAME=SELECTOR[@attr]",
|
|
42
|
+
help="custom CSS field, e.g. price=.price_color or link='h3 a@href'")
|
|
43
|
+
ap.add_argument("--row", default="", help="record container CSS selector for --css fields")
|
|
44
|
+
ap.add_argument("--profile", help="load settings from a profile .json saved by the GUI")
|
|
45
|
+
a = ap.parse_args(argv)
|
|
46
|
+
|
|
47
|
+
if a.profile:
|
|
48
|
+
with open(a.profile, encoding="utf-8") as fh:
|
|
49
|
+
s = ScrapeSettings.from_json(fh.read())
|
|
50
|
+
else:
|
|
51
|
+
s = ScrapeSettings()
|
|
52
|
+
any_flag = a.images or a.tables or a.links or a.text
|
|
53
|
+
if any_flag or not a.profile:
|
|
54
|
+
everything = not any_flag
|
|
55
|
+
s.extract_images = a.images or everything
|
|
56
|
+
s.extract_tables = a.tables or everything
|
|
57
|
+
s.extract_links = a.links or everything
|
|
58
|
+
s.extract_text = s.extract_meta = s.extract_contacts = a.text or everything
|
|
59
|
+
s.crawl, s.max_depth, s.max_pages, s.follow_pagination = a.crawl, a.depth, a.max_pages, a.paginate
|
|
60
|
+
s.render_js, s.delay, s.proxy, s.user_agent = a.js, a.delay, a.proxy, USER_AGENTS[a.ua]
|
|
61
|
+
s.min_width, s.min_height = a.min_width, a.min_height
|
|
62
|
+
if a.dir:
|
|
63
|
+
s.download_dir = a.dir
|
|
64
|
+
if a.types:
|
|
65
|
+
s.image_types = [t.strip().lower() for t in a.types.split(",")]
|
|
66
|
+
for spec in a.css:
|
|
67
|
+
name, _, q = spec.partition("=")
|
|
68
|
+
q, _, attr = q.partition("@")
|
|
69
|
+
s.custom_selectors.append({"name": name, "type": "css", "query": q, "attr": attr or "text"})
|
|
70
|
+
s.custom_row_selector = a.row
|
|
71
|
+
|
|
72
|
+
sc = WebScraper(s, log=print)
|
|
73
|
+
results = sc.run(a.urls)
|
|
74
|
+
images = [i for r in results for i in r.images]
|
|
75
|
+
tables = [t for r in results for t in r.tables]
|
|
76
|
+
print(f"\nPages: {len(results)} Images: {len(images)} Tables: {len(tables)} "
|
|
77
|
+
f"Links: {sum(len(r.links) for r in results)} Custom rows: {sum(len(r.custom) for r in results)}")
|
|
78
|
+
for t in tables[:20]:
|
|
79
|
+
print(f" - {t.name}: {len(t.rows)} rows x {max(len(x) for x in t.rows)} cols")
|
|
80
|
+
if a.download and images:
|
|
81
|
+
sc.download_images(images)
|
|
82
|
+
if a.output:
|
|
83
|
+
custom = [row for r in results for row in r.custom]
|
|
84
|
+
frames = exporters.tables_to_frames(tables)
|
|
85
|
+
if custom:
|
|
86
|
+
frames = {"Custom": exporters.records_to_df(custom), **frames}
|
|
87
|
+
if frames:
|
|
88
|
+
for f in exporters.export_dataframes(frames, a.output):
|
|
89
|
+
print("saved", f)
|
|
90
|
+
else:
|
|
91
|
+
print("No tables / custom data to export.")
|
|
92
|
+
if a.report:
|
|
93
|
+
for f in exporters.export_full_report(results, a.report):
|
|
94
|
+
print("saved", f)
|
|
95
|
+
sc.close()
|
|
96
|
+
return 0
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
if __name__ == "__main__":
|
|
100
|
+
sys.exit(main())
|