# Goofish Scraper — Xianyu C2C Listings, Item Detail & Seller (`khadinakbar/goofish-scraper`) Actor

Scrape Goofish (闲鱼/Xianyu — Alibaba C2C secondhand marketplace) by keyword, item URL/ID, or seller URL/ID. Returns title, price, condition, location, image, seller (Zhima credit, verification). Cookieless via MTOP XHR. Three modes auto-detected. MCP-ready.

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

## Pricing

from $5.00 / 1,000 listing scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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 Scraper — Xianyu C2C Listings, Item Detail & Seller

> Scrape **Goofish** (闲鱼/Xianyu — Alibaba's C2C secondhand marketplace) by **keyword**, **item URL/ID**, or **seller URL/ID**. Cookieless. MCP-ready.

### What it does

Pass a search keyword, item URL/ID, or seller URL/ID — get back structured Goofish listings:

| Field | Type | Description |
|---|---|---|
| `mode` | string | `search`, `detail`, or `seller` |
| `itemId` | string | Goofish numeric item ID |
| `title` | string | Listing title (Chinese / English) |
| `price` | number | Current price in **CNY** (¥) |
| `originalPrice` | number | Strike-through price (when present) |
| `condition` | string | 全新 / 99新 / 9成新 etc. |
| `city`, `province` | string | Seller location |
| `image`, `images[]` | string | Image URLs (full gallery in detail mode) |
| `description` | string | Full listing description (detail mode) |
| `wantCount`, `viewCount` | int | Want / view counters (detail mode) |
| `publishedAt` | ISO 8601 | Publish or last-bump time |
| `seller` | object | `{ nickname, userId, zhimaCredit, verified, totalSold, totalListed }` |
| `itemUrl` | string | `https://www.goofish.com/item?id=...` |
| `searchQuery`, `position` | string, int | Echo + result rank (search mode) |
| `scrapedAt` | ISO 8601 | When this record was captured |

### When to use it

- **Resellers / arbitrage** — China secondhand price intelligence.
- **Market researchers** — track demand & pricing on a category in mainland China's biggest C2C platform.
- **AI monitoring agents** — clean tool call: keyword in, listings out.
- **Product designers / collectors** — niche listings (BJD, retro games, vintage cameras) surfaced fast.

### When NOT to use it

- **Taobao / Tmall (B2C)** — Goofish is C2C only. For Taobao use a Taobao scraper.
- **AliExpress** — see `khadinakbar/aliexpress-product-search-scraper`.
- **Goofish account automation** (publish, message, buy) — out of scope; this is read-only public data.

### Pricing — Pay-Per-Event + Pay-Per-Usage

Both monetization models are enabled. Pick whichever fits your run.

| Event | Price | When |
|---|---|---|
| `apify-actor-start` | $0.00005 | once per run, scaled by RAM |
| `listing-scraped` | **$0.005** / listing | search & seller modes (no detail enrichment) |
| `listing-enriched-with-detail` | **$0.008** / listing | detail mode or `fetchDetails: true` |

Filtered-out listings are **not** charged (`priceMin`, `priceMax`, `condition`, `publishedWithinDays` filter client-side before charge).

Cost-cap visibility: every run logs the upfront max cost before the first charge fires.

### Quick start

#### From Apify Console

Open the actor → click **Run** with the default input (`searchQuery: "iPhone 15 Pro"`). Returns up to 30 listings.

#### From code

```js
// JavaScript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('khadinakbar/goofish-scraper').call({
    searchQuery: 'Sony A7 III',
    maxResults: 50,
    sortBy: 'newest',
    priceMin: 5000,
    priceMax: 12000,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

```python
## Python
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("khadinakbar/goofish-scraper").call(run_input={
    "searchQuery": "手办",
    "maxResults": 30,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["price"], item["itemUrl"])
```

```bash
## CLI
apify call khadinakbar/goofish-scraper --input='{"searchQuery":"iPhone 15 Pro","maxResults":20}'
```

#### Detail mode — specific item

```json
{ "startUrls": ["https://www.goofish.com/item?id=1234567890"] }
```

or

```json
{ "itemIds": ["1234567890", "9876543210"], "fetchDetails": true }
```

#### Seller mode — listings from one seller

```json
{ "sellerIds": ["2200000000000"], "maxResults": 100 }
```

### Modes auto-detected from input

| Input you give | Mode |
|---|---|
| `searchQuery` | search |
| `startUrls` matching `/search?q=` | search |
| `startUrls` matching `/item?id=` | detail |
| `startUrls` matching `/personal?userId=` | seller |
| `itemIds` | detail |
| `sellerIds` | seller |

You can combine all of them in one run.

### Input filters

| Filter | What it does |
|---|---|
| `sortBy` | relevance, newest, priceAsc, priceDesc (search mode) |
| `priceMin` / `priceMax` | CNY range (client-side, filtered before charge) |
| `condition` | all / used / new (matches 全新, 未拆, new for "new"; everything else = used) |
| `publishedWithinDays` | only listings posted within N days |
| `fetchDetails` | enrich every listing with detail page (bills enriched rate) |

### MCP / AI-agent usage

The actor is exposed in Apify MCP as `apify--goofish-scraper`. From Claude, ChatGPT, or any MCP client:

```
search-actors: "goofish"
call-actor name="khadinakbar/goofish-scraper" input={"searchQuery":"...","maxResults":20}
get-actor-output runId=...
```

Tool description is intentionally narrow (read-only public Goofish data); pricing signal is on the listing — so AI agents budget per call before invoking.

### How it works

PlaywrightCrawler navigates Goofish public web URLs; an XHR response interceptor catches Alibaba MTOP responses (`mtop.taobao.idlemtopsearch.pc.search`, `mtop.taobao.idle.pc.detail`) and parses the JSON. No login. No cookies you have to provide. No signature crypto on your side — the browser does it.

Proxy resilience:

1. `DATAIMPULSE_PROXY` env var (residential, primary if set).
2. Apify Residential (`apifyProxyGroups: ["RESIDENTIAL"]`).
3. Apify Datacenter US fallback.

The actor probes candidates in order and picks the first that responds. Resource blocking (images, fonts, media) keeps cost down without losing the MTOP XHRs.

### Limitations

- Goofish ships from mainland China; some IPs may serve degraded content or trigger soft blocks. The actor retries with session rotation; failures terminate honestly (charge $0, status message explains).
- Some private listings, "seller-only" channels, or login-walled content cannot be scraped.
- Pricing on listings is the live ask from the seller; sold prices and bargain history are not surfaced by the public web app.

### Legal & ToS

Goofish is operated by Alibaba Group. Scraping public listings is generally permitted for personal/research use under most jurisdictions, but you are responsible for compliance with Goofish/Alibaba Terms of Service, robots.txt, applicable data-protection law (PIPL, GDPR), and any restrictions of your jurisdiction. **Do not scrape personally identifiable information beyond what Goofish publishes publicly on the listing.** Do not use scraped data to harass, contact, dox, or otherwise harm sellers.

This actor performs read-only HTTP access to Goofish's public web interface — no login, no automated buying, no account operations.

### Related actors in this portfolio

- [`aliexpress-product-search-scraper`](https://apify.com/khadinakbar/aliexpress-product-search-scraper) — AliExpress search.
- [`alibaba-listings-scraper`](https://apify.com/khadinakbar/alibaba-listings-scraper) — Alibaba B2B listings.

### Support

Open an issue in the Apify Console Issues tab. The actor is actively maintained.

# Actor input Schema

## `searchQuery` (type: `string`):

Free-text keyword to search Goofish listings (e.g. 'iPhone 15 Pro', '手办', 'Sony A7 III'). Chinese and English both work. Leave blank if you are using startUrls or itemIds instead.

## `startUrls` (type: `array`):

Goofish/Xianyu URLs — accepted: item pages (https://www.goofish.com/item?id=...), seller pages (https://www.goofish.com/personal?userId=...), and search URLs (https://www.goofish.com/search?q=...). Mode is auto-detected per URL. Each URL counts toward maxResults independently.

## `itemIds` (type: `array`):

Numeric Goofish item IDs (the value after `id=` in the item URL). Each ID is scraped as a detail-mode item. Mutually compatible with startUrls and searchQuery.

## `sellerIds` (type: `array`):

Numeric Goofish seller user IDs (the value after `userId=` in the seller URL). Each seller is scraped for profile + their active listings (capped per seller by maxResults).

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

Hard cap on listings/items returned and charged for. Useful to control PPE spend. The actor stops scraping the moment this is reached. Defaults to 30.

## `sortBy` (type: `string`):

Sort order for SEARCH mode results. 'relevance' is Goofish default; 'newest' shows recent posts first; 'priceAsc'/'priceDesc' sort by current price.

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

Minimum listing price in CNY (¥). Listings below this are filtered out client-side (not charged). Leave empty for no minimum.

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

Maximum listing price in CNY (¥). Listings above this are filtered out client-side (not charged). Leave empty for no maximum.

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

Filter by item condition. 'all' returns everything; 'used' keeps only secondhand items; 'new' keeps only items listed as new/unopened.

## `publishedWithinDays` (type: `integer`):

Keep only listings published within the last N days (client-side filter; not charged for filtered items). Leave empty for no freshness limit.

## `fetchDetails` (type: `boolean`):

When true, every search/seller listing is enriched with a detail-page fetch (full description, all images, view count, want count, full seller card). Bills the higher per-listing rate — see pricing. Defaults to false.

## `proxyConfiguration` (type: `object`):

Goofish (Alibaba) requires anti-bot-capable IPs. The actor auto-resolves: DataImpulse residential (if DATAIMPULSE\_PROXY env is set) → Apify residential → Apify datacenter US fallback. Override here if you have a preferred config.

## Actor input object example

```json
{
  "searchQuery": "iPhone 15 Pro",
  "maxResults": 30,
  "sortBy": "relevance",
  "condition": "all",
  "fetchDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `datasetJson` (type: `string`):

All scraped listings as JSON.

## `datasetCsv` (type: `string`):

All scraped listings as CSV.

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

Counts per mode + total charged events for this run.

# 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 = {
    "searchQuery": "iPhone 15 Pro",
    "maxResults": 30,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/goofish-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 = {
    "searchQuery": "iPhone 15 Pro",
    "maxResults": 30,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

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

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

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

```

## CLI example

```bash
echo '{
  "searchQuery": "iPhone 15 Pro",
  "maxResults": 30,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call khadinakbar/goofish-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=khadinakbar/goofish-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/uceKrxORZYJoIq7Y4/builds/MvoZF1S0oe9FpQFPc/openapi.json
