scrapebadger-cli 0.2.1__py3-none-any.whl
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.
- scrapebadger_cli/__init__.py +1 -0
- scrapebadger_cli/client.py +57 -0
- scrapebadger_cli/commands/__init__.py +1 -0
- scrapebadger_cli/commands/amazon.py +227 -0
- scrapebadger_cli/commands/auth.py +52 -0
- scrapebadger_cli/commands/ebay.py +217 -0
- scrapebadger_cli/commands/google.py +1117 -0
- scrapebadger_cli/commands/idealista.py +220 -0
- scrapebadger_cli/commands/immobiliare.py +151 -0
- scrapebadger_cli/commands/leboncoin.py +154 -0
- scrapebadger_cli/commands/loopnet.py +89 -0
- scrapebadger_cli/commands/realtor.py +91 -0
- scrapebadger_cli/commands/reddit.py +173 -0
- scrapebadger_cli/commands/stream.py +270 -0
- scrapebadger_cli/commands/tiktok.py +283 -0
- scrapebadger_cli/commands/twitter.py +235 -0
- scrapebadger_cli/commands/vinted.py +105 -0
- scrapebadger_cli/commands/web.py +117 -0
- scrapebadger_cli/commands/youtube.py +625 -0
- scrapebadger_cli/commands/zillow.py +105 -0
- scrapebadger_cli/config.py +69 -0
- scrapebadger_cli/main.py +52 -0
- scrapebadger_cli/output.py +116 -0
- scrapebadger_cli-0.2.1.dist-info/METADATA +41 -0
- scrapebadger_cli-0.2.1.dist-info/RECORD +27 -0
- scrapebadger_cli-0.2.1.dist-info/WHEEL +4 -0
- scrapebadger_cli-0.2.1.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""Zillow real-estate commands."""
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
|
|
5
|
+
from scrapebadger_cli.client import api_get
|
|
6
|
+
from scrapebadger_cli.output import render
|
|
7
|
+
|
|
8
|
+
app = typer.Typer(no_args_is_help=True)
|
|
9
|
+
|
|
10
|
+
FMT = typer.Option("json", "--output", "-o", help="Output format: json, csv, table, markdown")
|
|
11
|
+
FIELDS = typer.Option(None, "--fields", "-f", help="Comma-separated fields to include")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@app.command()
|
|
15
|
+
def search(
|
|
16
|
+
location: str = typer.Argument(..., help="City/state, ZIP, address or neighborhood"),
|
|
17
|
+
status: str = typer.Option("for_sale", "--status", "-s", help="for_sale, for_rent, sold"),
|
|
18
|
+
page: int = typer.Option(1, "--page", "-p", help="1-20 (Zillow caps at ~820 results)"),
|
|
19
|
+
sort: str | None = typer.Option(None, "--sort", help="newest, price_low_to_high, etc."),
|
|
20
|
+
price_min: int | None = typer.Option(None, "--price-min"),
|
|
21
|
+
price_max: int | None = typer.Option(None, "--price-max"),
|
|
22
|
+
beds_min: int | None = typer.Option(None, "--beds-min"),
|
|
23
|
+
baths_min: float | None = typer.Option(None, "--baths-min"),
|
|
24
|
+
home_type: str | None = typer.Option(
|
|
25
|
+
None,
|
|
26
|
+
"--home-type",
|
|
27
|
+
help="houses, condos, townhomes, apartments, manufactured, lots, multi_family",
|
|
28
|
+
),
|
|
29
|
+
sqft_min: int | None = typer.Option(None, "--sqft-min"),
|
|
30
|
+
sqft_max: int | None = typer.Option(None, "--sqft-max"),
|
|
31
|
+
keywords: str | None = typer.Option(None, "--keywords"),
|
|
32
|
+
fmt: str = FMT,
|
|
33
|
+
fields: str | None = FIELDS,
|
|
34
|
+
) -> None:
|
|
35
|
+
"""Search Zillow for for-sale / for-rent / recently-sold properties."""
|
|
36
|
+
data = api_get(
|
|
37
|
+
"/v1/zillow/search",
|
|
38
|
+
{
|
|
39
|
+
"location": location,
|
|
40
|
+
"status": status,
|
|
41
|
+
"page": page,
|
|
42
|
+
"sort": sort,
|
|
43
|
+
"price_min": price_min,
|
|
44
|
+
"price_max": price_max,
|
|
45
|
+
"beds_min": beds_min,
|
|
46
|
+
"baths_min": baths_min,
|
|
47
|
+
"home_type": home_type,
|
|
48
|
+
"sqft_min": sqft_min,
|
|
49
|
+
"sqft_max": sqft_max,
|
|
50
|
+
"keywords": keywords,
|
|
51
|
+
},
|
|
52
|
+
)
|
|
53
|
+
render(data, fmt, fields)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@app.command()
|
|
57
|
+
def property(
|
|
58
|
+
zpid: str = typer.Argument(..., help="Zillow property id (zpid)"),
|
|
59
|
+
fmt: str = FMT,
|
|
60
|
+
fields: str | None = FIELDS,
|
|
61
|
+
) -> None:
|
|
62
|
+
"""Get a Zillow property's full detail by zpid."""
|
|
63
|
+
data = api_get(f"/v1/zillow/property/{zpid}", {})
|
|
64
|
+
render(data, fmt, fields)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@app.command("property-url")
|
|
68
|
+
def property_url(
|
|
69
|
+
url: str = typer.Argument(..., help="Full Zillow /homedetails/... URL"),
|
|
70
|
+
fmt: str = FMT,
|
|
71
|
+
fields: str | None = FIELDS,
|
|
72
|
+
) -> None:
|
|
73
|
+
"""Get a Zillow property's full detail by homedetails URL."""
|
|
74
|
+
data = api_get("/v1/zillow/property", {"url": url})
|
|
75
|
+
render(data, fmt, fields)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@app.command()
|
|
79
|
+
def agent(
|
|
80
|
+
username: str | None = typer.Argument(None, help="Zillow profile username"),
|
|
81
|
+
url: str | None = typer.Option(None, "--url", help="Full Zillow /profile/... URL"),
|
|
82
|
+
fmt: str = FMT,
|
|
83
|
+
fields: str | None = FIELDS,
|
|
84
|
+
) -> None:
|
|
85
|
+
"""Get a Zillow professional's profile and their active listings."""
|
|
86
|
+
data = api_get("/v1/zillow/agent", {"username": username, "url": url})
|
|
87
|
+
render(data, fmt, fields)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@app.command()
|
|
91
|
+
def autocomplete(
|
|
92
|
+
query: str = typer.Argument(..., help="Partial location — city, ZIP, address, neighborhood"),
|
|
93
|
+
fmt: str = FMT,
|
|
94
|
+
fields: str | None = FIELDS,
|
|
95
|
+
) -> None:
|
|
96
|
+
"""Resolve a search term to Zillow regions/addresses (regionId, lat/lng)."""
|
|
97
|
+
data = api_get("/v1/zillow/autocomplete", {"query": query})
|
|
98
|
+
render(data, fmt, fields)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@app.command("markets")
|
|
102
|
+
def list_markets(fmt: str = FMT, fields: str | None = FIELDS) -> None:
|
|
103
|
+
"""List Zillow coverage regions (US + Canada)."""
|
|
104
|
+
data = api_get("/v1/zillow/markets", {})
|
|
105
|
+
render(data, fmt, fields)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Configuration and API key management."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
CONFIG_DIR = Path.home() / ".config" / "scrapebadger"
|
|
8
|
+
CONFIG_FILE = CONFIG_DIR / "config.json"
|
|
9
|
+
ENV_KEY = "SCRAPEBADGER_API_KEY"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_api_key() -> str:
|
|
13
|
+
"""Resolve API key from env var, .env file, or config file.
|
|
14
|
+
|
|
15
|
+
Resolution order:
|
|
16
|
+
1. SCRAPEBADGER_API_KEY environment variable
|
|
17
|
+
2. .env file in current directory
|
|
18
|
+
3. ~/.config/scrapebadger/config.json
|
|
19
|
+
"""
|
|
20
|
+
# 1. Environment variable
|
|
21
|
+
key = os.environ.get(ENV_KEY, "")
|
|
22
|
+
if key:
|
|
23
|
+
return key
|
|
24
|
+
|
|
25
|
+
# 2. .env file in cwd
|
|
26
|
+
env_path = Path.cwd() / ".env"
|
|
27
|
+
if env_path.exists():
|
|
28
|
+
for line in env_path.read_text().splitlines():
|
|
29
|
+
line = line.strip()
|
|
30
|
+
if line.startswith(f"{ENV_KEY}="):
|
|
31
|
+
val = line.split("=", 1)[1].strip().strip("'\"")
|
|
32
|
+
if val:
|
|
33
|
+
return val
|
|
34
|
+
|
|
35
|
+
# 3. Config file
|
|
36
|
+
if CONFIG_FILE.exists():
|
|
37
|
+
try:
|
|
38
|
+
data = json.loads(CONFIG_FILE.read_text())
|
|
39
|
+
val = data.get("api_key", "")
|
|
40
|
+
if val:
|
|
41
|
+
return val
|
|
42
|
+
except (json.JSONDecodeError, KeyError):
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
return ""
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def save_api_key(key: str) -> None:
|
|
49
|
+
"""Save API key to ~/.config/scrapebadger/config.json."""
|
|
50
|
+
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
51
|
+
data: dict = {}
|
|
52
|
+
if CONFIG_FILE.exists():
|
|
53
|
+
try:
|
|
54
|
+
data = json.loads(CONFIG_FILE.read_text())
|
|
55
|
+
except json.JSONDecodeError:
|
|
56
|
+
pass
|
|
57
|
+
data["api_key"] = key
|
|
58
|
+
CONFIG_FILE.write_text(json.dumps(data, indent=2) + "\n")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def clear_api_key() -> None:
|
|
62
|
+
"""Remove API key from config file."""
|
|
63
|
+
if CONFIG_FILE.exists():
|
|
64
|
+
try:
|
|
65
|
+
data = json.loads(CONFIG_FILE.read_text())
|
|
66
|
+
data.pop("api_key", None)
|
|
67
|
+
CONFIG_FILE.write_text(json.dumps(data, indent=2) + "\n")
|
|
68
|
+
except json.JSONDecodeError:
|
|
69
|
+
pass
|
scrapebadger_cli/main.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""ScrapeBadger CLI entry point."""
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
|
|
5
|
+
from scrapebadger_cli.commands import (
|
|
6
|
+
amazon,
|
|
7
|
+
auth,
|
|
8
|
+
ebay,
|
|
9
|
+
google,
|
|
10
|
+
idealista,
|
|
11
|
+
immobiliare,
|
|
12
|
+
leboncoin,
|
|
13
|
+
loopnet,
|
|
14
|
+
realtor,
|
|
15
|
+
reddit,
|
|
16
|
+
stream,
|
|
17
|
+
tiktok,
|
|
18
|
+
twitter,
|
|
19
|
+
vinted,
|
|
20
|
+
web,
|
|
21
|
+
youtube,
|
|
22
|
+
zillow,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
app = typer.Typer(
|
|
26
|
+
name="scrapebadger",
|
|
27
|
+
help="ScrapeBadger CLI — Twitter, Reddit, Vinted, Amazon, eBay, TikTok, YouTube, Google, and Web Scraping from the command line.",
|
|
28
|
+
no_args_is_help=True,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
app.add_typer(twitter.app, name="twitter", help="Twitter/X data commands")
|
|
32
|
+
app.add_typer(reddit.app, name="reddit", help="Reddit data commands")
|
|
33
|
+
app.add_typer(stream.app, name="stream", help="Real-time streaming commands")
|
|
34
|
+
app.add_typer(vinted.app, name="vinted", help="Vinted marketplace commands")
|
|
35
|
+
app.add_typer(amazon.app, name="amazon", help="Amazon marketplace commands")
|
|
36
|
+
app.add_typer(ebay.app, name="ebay", help="eBay marketplace commands")
|
|
37
|
+
app.add_typer(idealista.app, name="idealista", help="Idealista real-estate commands")
|
|
38
|
+
app.add_typer(immobiliare.app, name="immobiliare", help="Immobiliare.it real-estate commands")
|
|
39
|
+
app.add_typer(leboncoin.app, name="leboncoin", help="Leboncoin classifieds commands")
|
|
40
|
+
app.add_typer(tiktok.app, name="tiktok", help="TikTok data commands")
|
|
41
|
+
app.add_typer(youtube.app, name="youtube", help="YouTube commands")
|
|
42
|
+
app.add_typer(zillow.app, name="zillow", help="Zillow real-estate commands")
|
|
43
|
+
app.add_typer(web.app, name="web", help="Web scraping commands")
|
|
44
|
+
app.add_typer(google.app, name="google", help="Google scraper commands")
|
|
45
|
+
app.add_typer(realtor.app, name="realtor", help="Realtor real-estate commands")
|
|
46
|
+
app.add_typer(loopnet.app, name="loopnet", help="LoopNet commercial real estate commands")
|
|
47
|
+
app.command()(auth.auth)
|
|
48
|
+
app.command(name="credits")(auth.credits)
|
|
49
|
+
app.command(name="logout")(auth.logout)
|
|
50
|
+
|
|
51
|
+
if __name__ == "__main__":
|
|
52
|
+
app()
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Output formatting — JSON, CSV, table, or markdown."""
|
|
2
|
+
|
|
3
|
+
import csv
|
|
4
|
+
import json
|
|
5
|
+
import sys
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.table import Table
|
|
10
|
+
|
|
11
|
+
console = Console()
|
|
12
|
+
|
|
13
|
+
OutputFormat = str # "json" | "csv" | "table" | "markdown"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def render(data: Any, fmt: str = "json", fields: str | None = None) -> None:
|
|
17
|
+
"""Render API response in the chosen format.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
data: The API response (dict or list).
|
|
21
|
+
fmt: Output format — json, csv, table, markdown.
|
|
22
|
+
fields: Comma-separated field names to include (optional).
|
|
23
|
+
"""
|
|
24
|
+
rows = _normalize_rows(data)
|
|
25
|
+
selected_fields = fields.split(",") if fields else None
|
|
26
|
+
|
|
27
|
+
if selected_fields and rows:
|
|
28
|
+
rows = [{k: r.get(k) for k in selected_fields} for r in rows]
|
|
29
|
+
|
|
30
|
+
if fmt == "json":
|
|
31
|
+
_render_json(rows if len(rows) != 1 else rows[0], data)
|
|
32
|
+
elif fmt == "csv":
|
|
33
|
+
_render_csv(rows)
|
|
34
|
+
elif fmt == "table":
|
|
35
|
+
_render_table(rows)
|
|
36
|
+
elif fmt == "markdown":
|
|
37
|
+
_render_markdown(rows)
|
|
38
|
+
else:
|
|
39
|
+
_render_json(data, data)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _normalize_rows(data: Any) -> list[dict]:
|
|
43
|
+
"""Extract a list of flat dicts from the API response."""
|
|
44
|
+
if isinstance(data, list):
|
|
45
|
+
return [r if isinstance(r, dict) else {"value": r} for r in data]
|
|
46
|
+
if isinstance(data, dict):
|
|
47
|
+
# Look for common list keys in the response
|
|
48
|
+
for key in (
|
|
49
|
+
"data",
|
|
50
|
+
"results",
|
|
51
|
+
"items",
|
|
52
|
+
"tweets",
|
|
53
|
+
"users",
|
|
54
|
+
"rules",
|
|
55
|
+
"logs",
|
|
56
|
+
"tiers",
|
|
57
|
+
"monitors",
|
|
58
|
+
):
|
|
59
|
+
if key in data and isinstance(data[key], list):
|
|
60
|
+
return [r if isinstance(r, dict) else {"value": r} for r in data[key]]
|
|
61
|
+
return [data]
|
|
62
|
+
return [{"value": data}]
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _render_json(rows: Any, original: Any) -> None:
|
|
66
|
+
"""Output as pretty JSON."""
|
|
67
|
+
# For single-item results, output the original response to preserve metadata
|
|
68
|
+
output = original if isinstance(rows, dict) else rows
|
|
69
|
+
sys.stdout.write(json.dumps(output, indent=2, ensure_ascii=False, default=str) + "\n")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _render_csv(rows: list[dict]) -> None:
|
|
73
|
+
"""Output as CSV."""
|
|
74
|
+
if not rows:
|
|
75
|
+
return
|
|
76
|
+
all_keys = list(dict.fromkeys(k for r in rows for k in r))
|
|
77
|
+
writer = csv.DictWriter(sys.stdout, fieldnames=all_keys, extrasaction="ignore")
|
|
78
|
+
writer.writeheader()
|
|
79
|
+
writer.writerows(rows)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _render_table(rows: list[dict]) -> None:
|
|
83
|
+
"""Output as a rich table."""
|
|
84
|
+
if not rows:
|
|
85
|
+
console.print("[dim]No results.[/dim]")
|
|
86
|
+
return
|
|
87
|
+
all_keys = list(dict.fromkeys(k for r in rows for k in r))
|
|
88
|
+
table = Table(show_header=True, header_style="bold cyan")
|
|
89
|
+
for key in all_keys:
|
|
90
|
+
table.add_column(key)
|
|
91
|
+
for row in rows:
|
|
92
|
+
table.add_row(*[_truncate(str(row.get(k, ""))) for k in all_keys])
|
|
93
|
+
console.print(table)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _render_markdown(rows: list[dict]) -> None:
|
|
97
|
+
"""Output as a markdown table."""
|
|
98
|
+
if not rows:
|
|
99
|
+
print("*No results.*")
|
|
100
|
+
return
|
|
101
|
+
all_keys = list(dict.fromkeys(k for r in rows for k in r))
|
|
102
|
+
header = "| " + " | ".join(all_keys) + " |"
|
|
103
|
+
separator = "| " + " | ".join("---" for _ in all_keys) + " |"
|
|
104
|
+
print(header)
|
|
105
|
+
print(separator)
|
|
106
|
+
for row in rows:
|
|
107
|
+
line = "| " + " | ".join(_truncate(str(row.get(k, "")), 60) for k in all_keys) + " |"
|
|
108
|
+
print(line)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _truncate(s: str, max_len: int = 80) -> str:
|
|
112
|
+
"""Truncate string for display."""
|
|
113
|
+
s = s.replace("\n", " ").replace("\r", "")
|
|
114
|
+
if len(s) > max_len:
|
|
115
|
+
return s[: max_len - 3] + "..."
|
|
116
|
+
return s
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: scrapebadger-cli
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: ScrapeBadger CLI — Twitter, Vinted, Google, and Web Scraping from the command line
|
|
5
|
+
Author: ScrapeBadger Team
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: ai-tools,cli,mcp,scrapebadger,twitter,vinted,web-scraping
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
12
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Requires-Dist: httpx>=0.26.0
|
|
15
|
+
Requires-Dist: rich>=13.0.0
|
|
16
|
+
Requires-Dist: typer>=0.12.0
|
|
17
|
+
Requires-Dist: websockets>=12.0
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: ruff>=0.2.0; extra == 'dev'
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# ScrapeBadger CLI
|
|
24
|
+
|
|
25
|
+
Command-line interface for ScrapeBadger — Twitter, Vinted, and Web Scraping.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install scrapebadger-cli
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
scrapebadger auth --api-key sb_live_...
|
|
37
|
+
scrapebadger twitter user elonmusk
|
|
38
|
+
scrapebadger twitter search "AI agents" --output table
|
|
39
|
+
scrapebadger vinted search "nike shoes" --market de
|
|
40
|
+
scrapebadger web scrape https://example.com --js
|
|
41
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
scrapebadger_cli/__init__.py,sha256=GcGSMO-8wr22obtXramTwtqh3jOpjnoSEnoFqytqZAE,84
|
|
2
|
+
scrapebadger_cli/client.py,sha256=QacrT6_herGs5zRqmC6yreqpkfHO2FLC--Br8OSw23E,1725
|
|
3
|
+
scrapebadger_cli/config.py,sha256=Gmxbgltd3iQNM94B_m5O_uurGZf8Im2IUz82yh9D1cc,1945
|
|
4
|
+
scrapebadger_cli/main.py,sha256=06QXZ46MfMghpzzSFnGCqjzbzlLmo34rYrcRw5ncDms,1900
|
|
5
|
+
scrapebadger_cli/output.py,sha256=QMG3S7VTX-zsnG55pbxxC_UTnlheGdFlCJNFycGmHM4,3588
|
|
6
|
+
scrapebadger_cli/commands/__init__.py,sha256=gQ6tnU0Rvm0-ESWFUBU-KDl5dpNOpUTG509hXOQQjwY,27
|
|
7
|
+
scrapebadger_cli/commands/amazon.py,sha256=7leKjyOFsXfPni6Mahw4LwxRJsXT51YcaE_GZm1XIqc,7344
|
|
8
|
+
scrapebadger_cli/commands/auth.py,sha256=16omqB1GaEyxP9jzzESDxWXMgkAY92frl5qkIaMDdXw,1696
|
|
9
|
+
scrapebadger_cli/commands/ebay.py,sha256=gR-96H9kcTLSzpaCK_lDWtjTURrPVxXzCcN27WyGh9U,7289
|
|
10
|
+
scrapebadger_cli/commands/google.py,sha256=b8GGkfP1cKL71PwgPwhpq9h5h8n2aJwY19MaVwFEdJg,41740
|
|
11
|
+
scrapebadger_cli/commands/idealista.py,sha256=0dOdN9S3jQf6CpQy89n8I4TDQdJwOyjYv112J2UJ3CM,8326
|
|
12
|
+
scrapebadger_cli/commands/immobiliare.py,sha256=SkSYkLMKYLEXs6lxhrDqv9q5TZCVuHBuU62nWQC0UhA,5272
|
|
13
|
+
scrapebadger_cli/commands/leboncoin.py,sha256=Jk63e5SLSACyrA6fMLAhLhIIFBiIFq7Vr0jnFZO2HT8,5037
|
|
14
|
+
scrapebadger_cli/commands/loopnet.py,sha256=c60YVqXGBzN0-P3FmqhZbmaELowQlYoKn_E0FxQTAxg,3219
|
|
15
|
+
scrapebadger_cli/commands/realtor.py,sha256=0viGe9xRS6v_5YFKpNkwo6qkA8GyEby5CbJ08VXENnE,3259
|
|
16
|
+
scrapebadger_cli/commands/reddit.py,sha256=nd_PQ1pfk-19L9rsVymyib3s0Ln0y-FuWYdUKKM8vAs,4981
|
|
17
|
+
scrapebadger_cli/commands/stream.py,sha256=jexzHWlaLliAY6D5z55HWlHzCyySLRCy2_ptApnZw3M,9191
|
|
18
|
+
scrapebadger_cli/commands/tiktok.py,sha256=w39EdvHVGEztZxTAizXZc3bCrmHREnzwxoJOWT9CCu8,8219
|
|
19
|
+
scrapebadger_cli/commands/twitter.py,sha256=AZXnusdxm-9UC0HW7v-INkKQTMXBqld3SJn7VgRsplg,6968
|
|
20
|
+
scrapebadger_cli/commands/vinted.py,sha256=IkCXzC57ser_9jaWwfIRvKlgi1HNFRxyPiBxO6Kr7mQ,3093
|
|
21
|
+
scrapebadger_cli/commands/web.py,sha256=EL-gmA0LNIzB2VOgKgotGehChIEtjTYU4oQKtotW17g,3891
|
|
22
|
+
scrapebadger_cli/commands/youtube.py,sha256=5u0P2F3CFY47ciKmnwgtxeBwNPZg6Y_WehX3sLYEOko,19224
|
|
23
|
+
scrapebadger_cli/commands/zillow.py,sha256=Ctz-4ZdPZXS8AEVHVaGkqCOtVxftk3bciUPgAb8EMjA,3698
|
|
24
|
+
scrapebadger_cli-0.2.1.dist-info/METADATA,sha256=ftn0jdsPORTLJ-vDqnF6S8bLtTBMQMI1sPLQBzko3No,1184
|
|
25
|
+
scrapebadger_cli-0.2.1.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
26
|
+
scrapebadger_cli-0.2.1.dist-info/entry_points.txt,sha256=gLnV1skpUPYYALjXxwGtMfpvTdv_E87cxWl77uayw1s,59
|
|
27
|
+
scrapebadger_cli-0.2.1.dist-info/RECORD,,
|