# Goofish Search Scraper — 闲鱼 Keyword Listings (`khadinakbar/goofish-search-scraper`) Actor

Search Goofish (闲鱼/Xianyu) by keyword or search URL. Returns indexed public listings: title, price, item URL, snippet. Cookieless Google discovery, no login. MCP-ready.

- **URL**: https://apify.com/khadinakbar/goofish-search-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** E-commerce, Automation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 goofish listing founds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Goofish Search Scraper

Search **public Goofish (闲鱼 / Xianyu) listings by keyword** and get one dataset row per indexed item page: item ID, title, yuan price when the public snippet shows it, condition cues, canonical item URL, Google snippet, and `scrapedAt`. Each run also writes `OUTPUT` / `RUN_SUMMARY` so agents can tell a complete export from an empty index or a provider that needs a later retry.

This actor is designed as a focused standalone workflow for Goofish **keyword search**. It does not open live 闲鱼 rank, chat, or seller stores.

### Best Fit

Choose this actor when the starting point is a product keyword or a Goofish `/search?q=` URL and the job is a **listing table**, not a known item ID. It works well for electronics sourcing, used-phone price scans, and Chinese-term discovery. Pair it with the [Goofish Scraper](https://apify.com/khadinakbar/goofish-scraper) when you already have an item or seller URL and need that page's public detail. Continue with the [Alibaba Listings Scraper](https://apify.com/khadinakbar/alibaba-listings-scraper) after this export when you want B2B search cards from Alibaba instead of 闲鱼 C2C listings.

### How To Use

Open the Input tab, keep the prefill keyword `iPhone 15` (or paste a Chinese term such as `小米`), leave `maxResults` at 5 for a cheap test, and start the actor. Download JSON, CSV, or Excel from the dataset when it finishes. Confirm `RUN_SUMMARY.outcome` before raising the cap.

### Input

```json
{
  "keywords": ["iPhone 15"],
  "maxResults": 5,
  "maxPagesPerKeyword": 1
}
```

| Input | Default | Notes |
| --- | --- | --- |
| `keywords` | `["iPhone 15"]` | One or more phrases, up to 10. Chinese terms usually match more listings than pinyin. |
| `searchUrls` | none | Optional `https://www.goofish.com/search?q=...` URLs. Item and seller URLs are rejected. |
| `maxResults` | `20` | Unique listings saved and billed this run. Prefill is 5. Maximum 50. |
| `maxPagesPerKeyword` | `2` | Google pages per keyword (about 10 organic hits each). Prefill is 1. Maximum 3. |
| `priceMin` / `priceMax` | none | Keep listings whose parsed yuan price falls in this band. Rows with no visible price are dropped when a bound is set. |
| `condition` | `all` | `all`, `used`, or `new`, inferred from public text, not native 闲鱼 chips. |

### Output

You can download the dataset as JSON, HTML, CSV, or Excel. One row per indexed Goofish item:

| Field | Description |
| --- | --- |
| `itemId` / `itemUrl` | Numeric ID and canonical public item URL |
| `title` | Listing title, or a snippet fallback when Google labels the page Untitled |
| `price` / `currency` | Yuan asking price when the title or snippet shows it (`CNY`) |
| `condition` | `new` or `used` when public text has a cue |
| `snippet` | Google snippet used as listing evidence |
| `searchQuery` / `googleQuery` | Caller keyword and the exact Google query |
| `provider` / `source` | Google provider name and `indexed-google` |
| `scrapedAt` | ISO 8601 collection time |

```json
{
  "itemId": "955486240562",
  "title": "iPhone 15 128G 闲置",
  "price": 3999,
  "currency": "CNY",
  "condition": "used",
  "snippet": "iPhone 15 128G ¥3999 闲置出",
  "itemUrl": "https://www.goofish.com/item?id=955486240562",
  "searchQuery": "iPhone 15",
  "googleQuery": "iPhone 15 site:goofish.com/item",
  "position": 1,
  "provider": "scrapecreators",
  "source": "indexed-google",
  "scrapedAt": "2026-09-10T12:00:00.000Z"
}
```

```json
{
  "outcome": "COMPLETE",
  "message": "Returned 5 indexed Goofish listing(s).",
  "itemsPushed": 5,
  "chargedEventCounts": { "listing-found": 5 },
  "warnings": []
}
```

### Workflow Story

A typical workflow starts with a buyer keyword such as `iPhone 15`. A sourcing analyst runs this actor with `maxResults: 5`, exports titles and item URLs, then compares yuan prices that appeared in the public snippets. Next they schedule the same keyword weekly and diff `RUN_SUMMARY.itemsPushed` to see whether indexed supply moved. When they already have a specific item URL from this table, they pass that URL into the all-in-one Goofish actor for the public detail page instead of repeating search.

### Pricing

This actor uses **Pay per event (PPE)** with **platform usage** passed through.

| Event | Price |
| --- | ---: |
| Actor start | `$0.00005` |
| Listing found | `$0.008` |

Example: 5 listings cost about `$0.04005` in events, plus compute platform usage. See the **Pricing tab** on this actor's page for the live price table.

### API Example

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('khadinakbar/goofish-search-scraper').call({
  keywords: ['iPhone 15'],
  maxResults: 5,
  maxPagesPerKeyword: 1
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

```bash
curl "https://api.apify.com/v2/acts/khadinakbar~goofish-search-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"keywords":["iPhone 15"],"maxResults":5,"maxPagesPerKeyword":1}'
```

### MCP And AI Agents

Exposed through Apify MCP as `khadinakbar/goofish-search-scraper`. Agent prompt card:

> Search public Goofish (闲鱼) listings by keyword. Use this when the user wants indexed item IDs, titles, yuan prices, and item URLs from a search phrase. For a known item or seller URL, route to the sibling Goofish scraper. Returns one dataset row per listing plus a RUN\_SUMMARY with outcome, itemsPushed, provider provenance, source URL fields (`itemUrl`, `googleQuery`), collection time (`scrapedAt`), and cost via listing-found events. Cap spend with maxResults. Google's public index is smaller than live 闲鱼 pagination.

### Best Results Guidance

- Provide specific product keywords. Chinese terms usually return more indexed pages than English or pinyin.
- Start with `maxResults: 5` and `maxPagesPerKeyword: 1` to validate the query, then raise the cap.
- Confirm `RUN_SUMMARY.outcome` before retrying: `VALID_EMPTY` means Google found no public item pages for that keyword.
- Schedule weekly keyword snapshots and validate `itemsPushed` against last week's summary.
- Keep runs focused on a small keyword list so Google-provider spend stays predictable.

### Builder's Note

I built this because native 闲鱼 search is a Baxia / RGV587 wall for cookieless traffic, while buyers still need a keyword-to-listing table. In my testing, Google `site:goofish.com/item` was the covering public path: ScrapeCreators and SociaVault can return a thin first page, and an existing owner Google fallback fills in when those routes yield no parseable item URLs. My goal is an honest indexed-search SKU, not a fake live rank.

### Related Actors

- Use the [Goofish Scraper](https://apify.com/khadinakbar/goofish-scraper) when you already have an item or seller URL and need that page's public detail instead of keyword search.
- Use the [Alibaba Listings Scraper](https://apify.com/khadinakbar/alibaba-listings-scraper) to search Alibaba.com B2B cards after you finish a 闲鱼 C2C keyword pass.

### Legal

Use this actor only for public Goofish pages you are authorized to access and process. You are responsible for complying with Goofish / 闲鱼 site terms, applicable laws, and data-protection rules. This actor does not log in, join chats, or collect private inboxes.

Goofish, 闲鱼, and Xianyu are trademarks of their respective owners. Google is a trademark of Google LLC. This independent Actor is not affiliated with, associated with, or endorsed by Alibaba Group, Goofish, 闲鱼, Xianyu, or Google.

# Actor input Schema

## `keywords` (type: `array`):

Keywords to search on Goofish, such as iPhone 15 or 小米. Chinese terms usually match more listings than pinyin. Accepts one or more phrases, up to 10 unique values. This is not an item URL and not a seller profile.

## `searchUrls` (type: `array`):

Optional Goofish search pages whose q= keyword should be scraped, for example https://www.goofish.com/search?q=iPhone%2015. Keywords are extracted from those URLs and merged with the keywords field. Item or seller URLs are rejected; send those to Goofish Scraper instead.

## `maxResults` (type: `integer`):

Hard cap on unique Goofish item listings saved and billed this run. Default 20. Prefill is 5 so quality tests stay short. Google's public index is much smaller than live 闲鱼 search, so values above 50 are not useful.

## `maxPagesPerKeyword` (type: `integer`):

How many Google result pages to request per keyword after the first page. Each page is about 10 organic results. Default 2. Raise only when a keyword still has unused index coverage under maxResults.

## `priceMin` (type: `integer`):

Keep only listings whose parsed asking price is at least this amount in yuan. Listings with no visible price in the Google title or snippet are dropped when this filter is set. Leave empty for no lower bound.

## `priceMax` (type: `integer`):

Keep only listings whose parsed asking price is at most this amount in yuan. Listings with no visible price in the Google title or snippet are dropped when this filter is set. Leave empty for no upper bound.

## `condition` (type: `string`):

Optional condition filter applied after Google returns a listing. all keeps every indexed item. new keeps titles that mention 全新 or brand new. used keeps 99新, 闲置, and similar used cues. This is inferred from public text, not Goofish's native filter chips.

## Actor input object example

```json
{
  "keywords": [
    "iPhone 15"
  ],
  "maxResults": 5,
  "maxPagesPerKeyword": 1,
  "condition": "all"
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset items containing itemId, title, price when visible, canonical item URL, search query, and provider.

## `summary` (type: `string`):

Run summary including outcome, itemsPushed, chargedEventCounts, and warnings.

## `runSummary` (type: `string`):

Machine-readable RUN\_SUMMARY record mirroring OUTPUT for integrations that read RUN\_SUMMARY directly.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keywords": [
        "iPhone 15"
    ],
    "maxResults": 5,
    "maxPagesPerKeyword": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/goofish-search-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "keywords": ["iPhone 15"],
    "maxResults": 5,
    "maxPagesPerKeyword": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/goofish-search-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keywords": [
    "iPhone 15"
  ],
  "maxResults": 5,
  "maxPagesPerKeyword": 1
}' |
apify call khadinakbar/goofish-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,khadinakbar/goofish-search-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/jGvmuWuuzvEN0cvP6/builds/BCMpl2JPpnkPEqmOE/openapi.json
