scrapebadger 0.24.2 → 0.26.0
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.
- package/README.md +1 -0
- package/dist/{index-jp8WyFsJ.d.cts → index-ZD3sVCjc.d.cts} +16 -0
- package/dist/{index-jp8WyFsJ.d.ts → index-ZD3sVCjc.d.ts} +16 -0
- package/dist/index.d.cts +465 -23
- package/dist/index.d.ts +465 -23
- package/dist/index.js +227 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +224 -1
- package/dist/index.mjs.map +1 -1
- package/dist/twitter/index.d.cts +1 -1
- package/dist/twitter/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -131,6 +131,39 @@ var BaseClient = class _BaseClient {
|
|
|
131
131
|
const { data } = await this.requestRaw(path, options);
|
|
132
132
|
return data;
|
|
133
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* POST and return the undecoded response body.
|
|
136
|
+
*
|
|
137
|
+
* For endpoints that answer with something other than JSON — currently
|
|
138
|
+
* `/v1/web/scrape` with `raw_content: true`, which returns the scraped body
|
|
139
|
+
* itself. The normal path funnels a non-JSON response into
|
|
140
|
+
* `{ detail: await response.text() }`, which both loses the result and, for
|
|
141
|
+
* a binary payload, corrupts it: `text()` decodes bytes as UTF-8.
|
|
142
|
+
*
|
|
143
|
+
* Returns the raw bytes plus the response headers.
|
|
144
|
+
*/
|
|
145
|
+
async postBinary(path, options = {}) {
|
|
146
|
+
const url = new URL(path, this.config.baseUrl);
|
|
147
|
+
const { body, headers = {} } = options;
|
|
148
|
+
const response = await this.fetchWithTimeout(url.toString(), {
|
|
149
|
+
method: "POST",
|
|
150
|
+
headers: {
|
|
151
|
+
"Content-Type": "application/json",
|
|
152
|
+
"X-API-Key": this.config.apiKey,
|
|
153
|
+
"User-Agent": `scrapebadger-node/${SDK_VERSION}`,
|
|
154
|
+
...headers
|
|
155
|
+
},
|
|
156
|
+
body: body ? JSON.stringify(body) : void 0
|
|
157
|
+
});
|
|
158
|
+
if (!response.ok) {
|
|
159
|
+
await this.handleResponse(response);
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
bytes: new Uint8Array(await response.arrayBuffer()),
|
|
163
|
+
headers: response.headers,
|
|
164
|
+
status: response.status
|
|
165
|
+
};
|
|
166
|
+
}
|
|
134
167
|
/**
|
|
135
168
|
* Make an HTTP request and return both data and rate limit headers.
|
|
136
169
|
*/
|
|
@@ -2475,11 +2508,54 @@ var WebClient = class {
|
|
|
2475
2508
|
if (options.aiPrompt !== void 0) body.ai_prompt = options.aiPrompt;
|
|
2476
2509
|
if (options.rawContent !== void 0) body.raw_content = options.rawContent;
|
|
2477
2510
|
if (options.skipBotDetection !== void 0) body.skip_bot_detection = options.skipBotDetection;
|
|
2511
|
+
if (options.rawContent) {
|
|
2512
|
+
return this.scrapeRaw(body);
|
|
2513
|
+
}
|
|
2478
2514
|
return this.client.request("/v1/web/scrape", {
|
|
2479
2515
|
method: "POST",
|
|
2480
2516
|
body
|
|
2481
2517
|
});
|
|
2482
2518
|
}
|
|
2519
|
+
/**
|
|
2520
|
+
* Run a `rawContent` scrape, whose response is not JSON.
|
|
2521
|
+
*
|
|
2522
|
+
* The normal path funnels a non-JSON response into `{ detail: text }`, so a
|
|
2523
|
+
* raw scrape returned a result with no content — and for a binary target,
|
|
2524
|
+
* `response.text()` decoded the bytes as UTF-8 and destroyed them. Read the
|
|
2525
|
+
* body as bytes and rebuild the metadata from the `X-Scrape-*` headers the
|
|
2526
|
+
* server sends in this mode.
|
|
2527
|
+
*/
|
|
2528
|
+
async scrapeRaw(body) {
|
|
2529
|
+
const { bytes, headers, status } = await this.client.postBinary("/v1/web/scrape", {
|
|
2530
|
+
body
|
|
2531
|
+
});
|
|
2532
|
+
const int = (name) => {
|
|
2533
|
+
const parsed = Number.parseInt(headers.get(name) ?? "", 10);
|
|
2534
|
+
return Number.isNaN(parsed) ? 0 : parsed;
|
|
2535
|
+
};
|
|
2536
|
+
const mediaType = ((headers.get("content-type") ?? "").split(";")[0] ?? "").trim().toLowerCase();
|
|
2537
|
+
const isText = mediaType.startsWith("text/") || ["application/json", "application/xml", "image/svg+xml"].includes(mediaType);
|
|
2538
|
+
return {
|
|
2539
|
+
success: headers.get("x-scrape-success") !== "0",
|
|
2540
|
+
url: headers.get("x-scrape-url") ?? (typeof body.url === "string" ? body.url : ""),
|
|
2541
|
+
status_code: int("x-scrape-status-code") || status,
|
|
2542
|
+
content: isText ? new TextDecoder().decode(bytes) : null,
|
|
2543
|
+
content_bytes: bytes,
|
|
2544
|
+
content_base64: null,
|
|
2545
|
+
is_binary: !isText,
|
|
2546
|
+
content_type: mediaType || null,
|
|
2547
|
+
format: headers.get("x-scrape-format") ?? "html",
|
|
2548
|
+
engine_used: headers.get("x-scrape-engine") ?? "",
|
|
2549
|
+
credits_used: int("x-credits-used"),
|
|
2550
|
+
duration_ms: int("x-scrape-duration-ms"),
|
|
2551
|
+
retries_used: int("x-scrape-retries"),
|
|
2552
|
+
content_length: int("x-scrape-content-length") || bytes.length,
|
|
2553
|
+
screenshot_url: null,
|
|
2554
|
+
video_url: null,
|
|
2555
|
+
headers: {},
|
|
2556
|
+
blocking_detected: false
|
|
2557
|
+
};
|
|
2558
|
+
}
|
|
2483
2559
|
/**
|
|
2484
2560
|
* Extract structured data from a web page using AI.
|
|
2485
2561
|
*
|
|
@@ -6744,6 +6820,150 @@ var LinkedInClient = class {
|
|
|
6744
6820
|
}
|
|
6745
6821
|
};
|
|
6746
6822
|
|
|
6823
|
+
// src/chatgpt/ask.ts
|
|
6824
|
+
var AskClient = class {
|
|
6825
|
+
client;
|
|
6826
|
+
constructor(client) {
|
|
6827
|
+
this.client = client;
|
|
6828
|
+
}
|
|
6829
|
+
/**
|
|
6830
|
+
* Ask ChatGPT a question and get the answer with its sources.
|
|
6831
|
+
*
|
|
6832
|
+
* Costs 20 credits. Typical latency is 20-25s ungrounded, 30-70s with web search.
|
|
6833
|
+
*
|
|
6834
|
+
* @param params - Ask parameters.
|
|
6835
|
+
* @param params.prompt - The prompt to send (max 4096 characters).
|
|
6836
|
+
* @param params.country - ISO-3166 alpha-2 egress country (default: "US").
|
|
6837
|
+
* @param params.web_search - "auto", "force", or "off" (default: "auto").
|
|
6838
|
+
* @returns The answer, its citations, and the full retrieved search set.
|
|
6839
|
+
*
|
|
6840
|
+
* @example
|
|
6841
|
+
* ```typescript
|
|
6842
|
+
* const result = await client.chatgpt.ask.ask({
|
|
6843
|
+
* prompt: "what is the best CRM for a 10-person startup?",
|
|
6844
|
+
* country: "GB",
|
|
6845
|
+
* web_search: "force",
|
|
6846
|
+
* });
|
|
6847
|
+
* console.log(result.web_search_triggered, result.model);
|
|
6848
|
+
* for (const source of result.search_results) {
|
|
6849
|
+
* console.log(`${source.cited ? "*" : " "} ${source.url}`);
|
|
6850
|
+
* }
|
|
6851
|
+
* ```
|
|
6852
|
+
*/
|
|
6853
|
+
async ask(params) {
|
|
6854
|
+
return this.client.request("/v1/chatgpt/ask", {
|
|
6855
|
+
params: {
|
|
6856
|
+
prompt: params.prompt,
|
|
6857
|
+
country: params.country,
|
|
6858
|
+
web_search: params.web_search
|
|
6859
|
+
}
|
|
6860
|
+
});
|
|
6861
|
+
}
|
|
6862
|
+
};
|
|
6863
|
+
|
|
6864
|
+
// src/chatgpt/brand.ts
|
|
6865
|
+
var BrandClient = class {
|
|
6866
|
+
client;
|
|
6867
|
+
constructor(client) {
|
|
6868
|
+
this.client = client;
|
|
6869
|
+
}
|
|
6870
|
+
/**
|
|
6871
|
+
* Analyse how a brand shows up in ChatGPT's answer to a prompt.
|
|
6872
|
+
*
|
|
6873
|
+
* Costs 25 credits.
|
|
6874
|
+
*
|
|
6875
|
+
* @param params - Brand-visibility parameters.
|
|
6876
|
+
* @param params.prompt - The prompt to send (max 4096 characters).
|
|
6877
|
+
* @param params.brand - The brand name to look for in the answer.
|
|
6878
|
+
* @param params.domain - The brand's domain, used to detect brand citations.
|
|
6879
|
+
* @param params.aliases - Other spellings that should count as mentions.
|
|
6880
|
+
* @param params.competitors - Competitors to measure share of voice against.
|
|
6881
|
+
* @param params.country - ISO-3166 alpha-2 egress country (default: "US").
|
|
6882
|
+
* @param params.web_search - "auto", "force", or "off" (default: "force").
|
|
6883
|
+
* @returns The brand analysis plus the answer and its citations.
|
|
6884
|
+
*
|
|
6885
|
+
* @example
|
|
6886
|
+
* ```typescript
|
|
6887
|
+
* const result = await client.chatgpt.brand.visibility({
|
|
6888
|
+
* prompt: "which proxy provider should I use?",
|
|
6889
|
+
* brand: "ScrapeBadger",
|
|
6890
|
+
* domain: "scrapebadger.com",
|
|
6891
|
+
* aliases: ["Scrape Badger"],
|
|
6892
|
+
* competitors: ["Bright Data", "Oxylabs"],
|
|
6893
|
+
* country: "DE",
|
|
6894
|
+
* });
|
|
6895
|
+
* console.log(`position score: ${result.position_score}`);
|
|
6896
|
+
* for (const competitor of result.competitors) {
|
|
6897
|
+
* console.log(`${competitor.name}: ${competitor.mention_count}`);
|
|
6898
|
+
* }
|
|
6899
|
+
* ```
|
|
6900
|
+
*/
|
|
6901
|
+
async visibility(params) {
|
|
6902
|
+
return this.client.request("/v1/chatgpt/brand-visibility", {
|
|
6903
|
+
params: {
|
|
6904
|
+
prompt: params.prompt,
|
|
6905
|
+
brand: params.brand,
|
|
6906
|
+
domain: params.domain,
|
|
6907
|
+
aliases: params.aliases?.length ? params.aliases.join(",") : void 0,
|
|
6908
|
+
competitors: params.competitors?.length ? params.competitors.join(",") : void 0,
|
|
6909
|
+
country: params.country,
|
|
6910
|
+
web_search: params.web_search
|
|
6911
|
+
}
|
|
6912
|
+
});
|
|
6913
|
+
}
|
|
6914
|
+
};
|
|
6915
|
+
|
|
6916
|
+
// src/chatgpt/reference.ts
|
|
6917
|
+
var ReferenceClient11 = class {
|
|
6918
|
+
client;
|
|
6919
|
+
constructor(client) {
|
|
6920
|
+
this.client = client;
|
|
6921
|
+
}
|
|
6922
|
+
/**
|
|
6923
|
+
* Get the models chatgpt.com currently offers.
|
|
6924
|
+
*
|
|
6925
|
+
* Costs 1 credit.
|
|
6926
|
+
*
|
|
6927
|
+
* @param params - Optional parameters.
|
|
6928
|
+
* @param params.country - ISO-3166 alpha-2 egress country (default: "US").
|
|
6929
|
+
* @returns The available models.
|
|
6930
|
+
*
|
|
6931
|
+
* @example
|
|
6932
|
+
* ```typescript
|
|
6933
|
+
* const result = await client.chatgpt.reference.models({ country: "GB" });
|
|
6934
|
+
* console.log(`${result.count} models`);
|
|
6935
|
+
* for (const model of result.models) {
|
|
6936
|
+
* console.log(`${model.slug}: ${model.max_tokens} tokens`);
|
|
6937
|
+
* }
|
|
6938
|
+
* ```
|
|
6939
|
+
*/
|
|
6940
|
+
async models(params = {}) {
|
|
6941
|
+
return this.client.request("/v1/chatgpt/models", {
|
|
6942
|
+
params: { country: params.country }
|
|
6943
|
+
});
|
|
6944
|
+
}
|
|
6945
|
+
};
|
|
6946
|
+
|
|
6947
|
+
// src/chatgpt/client.ts
|
|
6948
|
+
var ChatGPTClient = class {
|
|
6949
|
+
/** Client for asking ChatGPT a question */
|
|
6950
|
+
ask;
|
|
6951
|
+
/** Client for AEO/GEO brand-visibility analysis */
|
|
6952
|
+
brand;
|
|
6953
|
+
/** Client for reference data (available models) */
|
|
6954
|
+
reference;
|
|
6955
|
+
/**
|
|
6956
|
+
* Create a new ChatGPT client.
|
|
6957
|
+
*
|
|
6958
|
+
* @param client - The base HTTP client for making requests.
|
|
6959
|
+
*/
|
|
6960
|
+
constructor(client) {
|
|
6961
|
+
this.ask = new AskClient(client);
|
|
6962
|
+
this.brand = new BrandClient(client);
|
|
6963
|
+
this.reference = new ReferenceClient11(client);
|
|
6964
|
+
}
|
|
6965
|
+
};
|
|
6966
|
+
|
|
6747
6967
|
// src/client.ts
|
|
6748
6968
|
var ScrapeBadger = class {
|
|
6749
6969
|
baseClient;
|
|
@@ -6783,6 +7003,8 @@ var ScrapeBadger = class {
|
|
|
6783
7003
|
depop;
|
|
6784
7004
|
/** LinkedIn scraper API client — 11 no-auth endpoints (jobs, company, school, profile, post, article, learning, geo) */
|
|
6785
7005
|
linkedin;
|
|
7006
|
+
/** ChatGPT scraper API client — ask, brand visibility, models (the real chatgpt.com, anonymous) */
|
|
7007
|
+
chatgpt;
|
|
6786
7008
|
/**
|
|
6787
7009
|
* Create a new ScrapeBadger client.
|
|
6788
7010
|
*
|
|
@@ -6835,9 +7057,10 @@ var ScrapeBadger = class {
|
|
|
6835
7057
|
this.loopnet = new LoopNetClient(this.baseClient);
|
|
6836
7058
|
this.depop = new DepopClient(this.baseClient);
|
|
6837
7059
|
this.linkedin = new LinkedInClient(this.baseClient);
|
|
7060
|
+
this.chatgpt = new ChatGPTClient(this.baseClient);
|
|
6838
7061
|
}
|
|
6839
7062
|
};
|
|
6840
7063
|
|
|
6841
|
-
export { AccountRestrictedError, AmazonClient, ListingsClient as AmazonListingsClient, ProductsClient2 as AmazonProductsClient, ReferenceClient2 as AmazonReferenceClient, SearchClient4 as AmazonSearchClient, SellersClient as AmazonSellersClient, AuthenticationError, CommunitiesClient, ConflictError, DepopClient, CategoriesClient as EbayCategoriesClient, EbayClient, ItemsClient2 as EbayItemsClient, ReferenceClient5 as EbayReferenceClient, SearchClient7 as EbaySearchClient, SellersClient2 as EbaySellersClient, GeoClient, AiModeClient as GoogleAiModeClient, AutocompleteClient as GoogleAutocompleteClient, GoogleClient, FinanceClient as GoogleFinanceClient, FlightsClient as GoogleFlightsClient, HotelsClient as GoogleHotelsClient, ImagesClient as GoogleImagesClient, JobsClient as GoogleJobsClient, LensClient as GoogleLensClient, MapsClient as GoogleMapsClient, NewsClient as GoogleNewsClient, PatentsClient as GooglePatentsClient, ProductsClient as GoogleProductsClient, ScholarClient as GoogleScholarClient, SearchClient2 as GoogleSearchClient, ShoppingClient as GoogleShoppingClient, ShortsClient as GoogleShortsClient, TrendsClient2 as GoogleTrendsClient, VideosClient as GoogleVideosClient, ImmobiliareClient, InsufficientCreditsError, AdsClient2 as LeboncoinAdsClient, LeboncoinClient, ReferenceClient8 as LeboncoinReferenceClient, SearchClient10 as LeboncoinSearchClient, SellersClient3 as LeboncoinSellersClient, LinkedInClient, ListsClient, BrokersClient as LoopNetBrokersClient, LoopNetClient, ListingsClient2 as LoopNetListingsClient, ReferenceClient10 as LoopNetReferenceClient, SearchClient12 as LoopNetSearchClient, NotFoundError, RateLimitError, RealtorClient, PropertiesClient as RealtorPropertiesClient, ReferenceClient7 as RealtorReferenceClient, SearchClient9 as RealtorSearchClient, RedditClient, PostsClient as RedditPostsClient, SearchClient3 as RedditSearchClient, SubredditsClient as RedditSubredditsClient, UsersClient3 as RedditUsersClient, RedfinClient, ScrapeBadger, ScrapeBadgerError, ServerError, ShopeeClient, ProductsClient3 as ShopeeProductsClient, ReferenceClient3 as ShopeeReferenceClient, ReviewsClient as ShopeeReviewsClient, SearchClient5 as ShopeeSearchClient, SpacesClient, StreamClient, AdsClient as TikTokAdsClient, TikTokClient, HashtagsClient as TikTokHashtagsClient, MusicClient as TikTokMusicClient, ReferenceClient4 as TikTokReferenceClient, SearchClient6 as TikTokSearchClient, TrendingClient as TikTokTrendingClient, UsersClient4 as TikTokUsersClient, VideosClient2 as TikTokVideosClient, TimeoutError, TrendsClient, TweetsClient, TwitterClient, UsersClient, ValidationError, VintedClient, ItemsClient as VintedItemsClient, ReferenceClient as VintedReferenceClient, SearchClient as VintedSearchClient, UsersClient2 as VintedUsersClient, WebClient, WebSocketStreamError, ChannelsClient as YoutubeChannelsClient, YoutubeClient, CommunityClient as YoutubeCommunityClient, MusicClient2 as YoutubeMusicClient, PlaylistsClient as YoutubePlaylistsClient, ReferenceClient6 as YoutubeReferenceClient, SearchClient8 as YoutubeSearchClient, ShortsClient2 as YoutubeShortsClient, TrendingClient2 as YoutubeTrendingClient, VideosClient3 as YoutubeVideosClient, AgentClient as ZillowAgentClient, ZillowClient, PropertiesClient2 as ZillowPropertiesClient, ReferenceClient9 as ZillowReferenceClient, SearchClient11 as ZillowSearchClient, collectAll, verifyWebhookSignature };
|
|
7064
|
+
export { AccountRestrictedError, AmazonClient, ListingsClient as AmazonListingsClient, ProductsClient2 as AmazonProductsClient, ReferenceClient2 as AmazonReferenceClient, SearchClient4 as AmazonSearchClient, SellersClient as AmazonSellersClient, AuthenticationError, AskClient as ChatGPTAskClient, BrandClient as ChatGPTBrandClient, ChatGPTClient, ReferenceClient11 as ChatGPTReferenceClient, CommunitiesClient, ConflictError, DepopClient, CategoriesClient as EbayCategoriesClient, EbayClient, ItemsClient2 as EbayItemsClient, ReferenceClient5 as EbayReferenceClient, SearchClient7 as EbaySearchClient, SellersClient2 as EbaySellersClient, GeoClient, AiModeClient as GoogleAiModeClient, AutocompleteClient as GoogleAutocompleteClient, GoogleClient, FinanceClient as GoogleFinanceClient, FlightsClient as GoogleFlightsClient, HotelsClient as GoogleHotelsClient, ImagesClient as GoogleImagesClient, JobsClient as GoogleJobsClient, LensClient as GoogleLensClient, MapsClient as GoogleMapsClient, NewsClient as GoogleNewsClient, PatentsClient as GooglePatentsClient, ProductsClient as GoogleProductsClient, ScholarClient as GoogleScholarClient, SearchClient2 as GoogleSearchClient, ShoppingClient as GoogleShoppingClient, ShortsClient as GoogleShortsClient, TrendsClient2 as GoogleTrendsClient, VideosClient as GoogleVideosClient, ImmobiliareClient, InsufficientCreditsError, AdsClient2 as LeboncoinAdsClient, LeboncoinClient, ReferenceClient8 as LeboncoinReferenceClient, SearchClient10 as LeboncoinSearchClient, SellersClient3 as LeboncoinSellersClient, LinkedInClient, ListsClient, BrokersClient as LoopNetBrokersClient, LoopNetClient, ListingsClient2 as LoopNetListingsClient, ReferenceClient10 as LoopNetReferenceClient, SearchClient12 as LoopNetSearchClient, NotFoundError, RateLimitError, RealtorClient, PropertiesClient as RealtorPropertiesClient, ReferenceClient7 as RealtorReferenceClient, SearchClient9 as RealtorSearchClient, RedditClient, PostsClient as RedditPostsClient, SearchClient3 as RedditSearchClient, SubredditsClient as RedditSubredditsClient, UsersClient3 as RedditUsersClient, RedfinClient, ScrapeBadger, ScrapeBadgerError, ServerError, ShopeeClient, ProductsClient3 as ShopeeProductsClient, ReferenceClient3 as ShopeeReferenceClient, ReviewsClient as ShopeeReviewsClient, SearchClient5 as ShopeeSearchClient, SpacesClient, StreamClient, AdsClient as TikTokAdsClient, TikTokClient, HashtagsClient as TikTokHashtagsClient, MusicClient as TikTokMusicClient, ReferenceClient4 as TikTokReferenceClient, SearchClient6 as TikTokSearchClient, TrendingClient as TikTokTrendingClient, UsersClient4 as TikTokUsersClient, VideosClient2 as TikTokVideosClient, TimeoutError, TrendsClient, TweetsClient, TwitterClient, UsersClient, ValidationError, VintedClient, ItemsClient as VintedItemsClient, ReferenceClient as VintedReferenceClient, SearchClient as VintedSearchClient, UsersClient2 as VintedUsersClient, WebClient, WebSocketStreamError, ChannelsClient as YoutubeChannelsClient, YoutubeClient, CommunityClient as YoutubeCommunityClient, MusicClient2 as YoutubeMusicClient, PlaylistsClient as YoutubePlaylistsClient, ReferenceClient6 as YoutubeReferenceClient, SearchClient8 as YoutubeSearchClient, ShortsClient2 as YoutubeShortsClient, TrendingClient2 as YoutubeTrendingClient, VideosClient3 as YoutubeVideosClient, AgentClient as ZillowAgentClient, ZillowClient, PropertiesClient2 as ZillowPropertiesClient, ReferenceClient9 as ZillowReferenceClient, SearchClient11 as ZillowSearchClient, collectAll, verifyWebhookSignature };
|
|
6842
7065
|
//# sourceMappingURL=index.mjs.map
|
|
6843
7066
|
//# sourceMappingURL=index.mjs.map
|