1. 2scraper
  2. Finance & markets
  3. Binance
Open source · MITRuns with no key, proxy or account

Binance Scraper

P2P adverts, copy-trading portfolios and announcements from Binance — no key, proxy or account needed.

  • Playwright
  • Selenium
  • Puppeteer
  • Plain HTTP
  • Scraping Browser API
  • JSON
  • CSV
binance-scraper
# P2P adverts
$ ./venv/bin/python playwright_scraper.py --asset USDT --fiat EUR --side buy --pages 50
✓ 5 sample rows · 29 columns in sample_output.json
3modes: P2P, copy-trading, announcements
4engines, including plain HTTP with no browser
0keys, proxies or accounts needed
196 / 196adverts in a 10-page USDT/EUR run, Sep 2026
Available Binance scrapers

What the Binance scraper collects

Reads the public lists Binance's own pages are built from: the P2P order book for any asset/fiat pair, the Futures copy-trading leaderboard and the announcement catalogues. Rows go to JSON and CSV, with a sidecar that records the site's own total, so a file says "90 of 8,920" rather than only "90".

P2P adverts

Input: An asset, a fiat currency and a side, or a p2p.binance.com URL

One row per advert: price, available amount, order limits, payment methods, and the advertiser's 30-day orders, completion rate and feedback. 20 adverts per page.

Copy-trading lead portfolios

Input: A time range and a sort key

One row per Futures lead portfolio: ROI, PnL, max drawdown, win rate, AUM, copier PnL, copiers and seats, badge. 30 portfolios per page.

Announcements

Input: An announcement category

One row per article from a catalogue: new listings, delistings, news, maintenance, API updates, airdrops. 50 announcements per page.

Quick start

From zero to Binance data in 3 steps

  1. Install

    Clone the repository and install one browser engine. Python 3.9+.

    $ git clone https://github.com/2scraper/binance-scraper.git && cd binance-scraper
    $ python3 -m venv venv
    $ ./venv/bin/pip install -r requirements.txt -r requirements-playwright.txt
    $ ./venv/bin/playwright install chromium
  2. Run a scraper

    Pick what you need and run it. Every flag is documented in the README.

    $ ./venv/bin/python playwright_scraper.py --asset USDT --fiat EUR --side buy --pages 50
  3. Get structured data

    Rows land in JSON or CSV (--format), with a .meta.json sidecar recording status, pages fetched and why the run stopped.

Output

Binance data fields

29 columns per row in a predictable schema. The most useful ones:

FieldWhat it holds
skuThe advert's own id, used to dedupe and to diff two runs
titleThe advertiser's display name
sideThe side you asked for (buy or sell)
advertiser_sideThe side the advert itself states — the maker's, so the opposite of yours
assetCrypto asset, e.g. USDT
fiatFiat currency, e.g. EUR
priceAdvert price in the fiat currency, as a number
availableAmount of the asset on offer
min_order_fiatSmallest order the advert accepts, in fiat
max_order_fiatLargest order the advert accepts, in fiat
pay_methodsPayment-method identifiers as the site writes them (e.g. SEPAinstant)
pay_time_limit_minMinutes allowed to pay
advertiser_idThe advertiser's public id
month_ordersAdvertiser's orders in the last 30 days
month_finish_rateAdvertiser's 30-day completion rate (0-1)
positive_rateShare of positive feedback (0-1)
[
  {
    "source": "binance.com",
    "scraped_at": "2026-09-24T08:20:08.069219+00:00",
    "url": "https://p2p.binance.com/en/advertiserDetail?advertiserNo=s2f329f93c84e301ea188eb127c7ca1c3",
    "sku": "12912883391234060288",
    "title": "24-Wise-To-Wise-7",
    "side": "buy",
    "advertiser_side": "sell",
    "asset": "USDT",
    "fiat": "EUR",
    "fiat_symbol": "€",
    "price": 0.872,
    "available": 4526.6,
    "min_order_fiat": 500.0,
    "max_order_fiat": 3000.0,
    "pay_methods": [
      "Wise"
    ],
    "pay_method_names": [
      "Wise"
    ],
    "pay_time_limit_min": 15,
    "ad_class": "mass",
    "extra_kyc_required": false,
    "privilege_type": 1,
    "advertiser_id": "s2f329f93c84e301ea188eb127c7ca1c3",
    "advertiser_type": "user",
    "month_orders": 229,
    "month_finish_rate": 0.996,
    "positive_rate": 1.0,
    "page": 1,
    "position": 1,
    "mode": "p2p",
    "data_source": "bapi"
  },
  {
    "source": "binance.com",
    "scraped_at": "2026-09-24T08:20:08.069251+00:00",
    "url": "https://p2p.binance.com/en/advertiserDetail?advertiserNo=s74759087fd0736f68ccf983949908366",
    "sku": "13933898091027263488",
    "title": "SUPER N0VA",
    "side": "buy",
    "advertiser_side": "sell",
    "asset": "USDT",
    "fiat": "EUR",
    "fiat_symbol": "€",
    "price": 0.874,
    "available": 14453.78,
    "min_order_fiat": 200.0,
    "max_order_fiat": 8000.0,
    "pay_methods": [
      "SkrillMoneybookers"
    ],
    "pay_method_names": [
      "Skrill"
    ],
    "pay_time_limit_min": 15,
    "ad_class": "profession",
    "extra_kyc_required": false,
    "privilege_type": null,
    "advertiser_id": "s74759087fd0736f68ccf983949908366",
    "advertiser_type": "merchant",
    "month_orders": 191,
    "month_finish_rate": 0.995,
    "positive_rate": 1.0,
    "page": 1,
    "position": 2,
    "mode": "p2p",
    "data_source": "bapi"
  }
]

First 2 of 5 rows from a real run — sample_output.json. Long values shortened here.

Built for Binance

Handles what breaks naive Binance scrapers

Gated pages, open data

Every HTML page on binance.com sits behind AWS WAF, but the JSON lists the front end calls do not. The engines land once and fetch every page same-origin, so no page is ever rendered — and http_scraper.py needs no browser at all.

Buy and sell sides kept straight

A buy query returns adverts marked SELL, because an advert carries the maker's side. Every row keeps both: side is what you asked for, advertiser_side is what the advert says.

Typos refused before they are sent

The API answers wrong values with plausible data — a misspelt payment method returns zero adverts on a full market. Every parameter is allowlisted, and --pay-type is checked against the site's own list with "did you mean SEPAinstant?".

A moved shape is never an empty market

A served page inside the site's own total that parses to no rows is reported as a parser failure (exit 5 or 6), and a renamed column is named in the sidecar — not passed off as a healthy run.

Everything built in

Scraping infrastructure included

The same tested core runs every 2scraper repository, so the hard parts work the same way on every site.

CAPTCHA handling

Detects the challenge a page really serves and, with a 2Captcha key, solves it only when it blocks the data — a capped number of solves per page.

Proxy rotation

Single proxy or a pool from a file, rotated on blocks with a fresh browser per exit. Credentials stay out of argv and logs.

Fingerprints

Optional complete device identity from the 2Captcha Fingerprint API — user agent, client hints, locale and timezone that agree with each other.

Scraping Browser API

Point --cdp-endpoint at a managed Chromium with its own exit country — no browser infrastructure to run yourself.

Honest run metadata

Every run writes a .meta.json sidecar and distinct exit codes: complete, blocked, empty and partial are never confused, and a failed run never overwrites good data.

Diff two runs

diff_runs.py compares two complete Binance snapshots by id — new, removed and changed rows for monitoring.

Use cases

What teams do with Binance data

P2P spread monitoring

Track buy and sell prices for an asset/fiat pair over time, filtered by payment method, with order limits and advertiser reliability alongside.

Copy-trader research

Rank lead portfolios by ROI, PnL, drawdown or AUM over 7, 30 or 90 days, and diff runs to see who entered or left the top.

Listing and delisting alerts

Pull the new-listing or delisting catalogue on a schedule and diff it against the last run to catch new articles.

Merchant due diligence

Compare P2P advertisers by 30-day order count, completion rate and positive feedback before trading with one.

Access & pricing

Free to run. Pay only for what the site requires.

Runs with no key, proxy or account

All three modes run with no key, no proxy and no account — measured from a datacentre VPS, and checked daily by a canary on a GitHub runner with no secrets. Captcha solving (AWS WAF, AmazonTask) is there for the day the WAF moves in front of the data endpoints; residential proxies add volume and an exit in a country Binance serves; the Scraping Browser API gives you a remote browser with a chosen exit country; fingerprints give a local browser a consistent identity.

Optional 2Captcha services — captcha solving, the Scraping Browser API, residential proxies and fingerprints — work behind one key.

Good to know

  • These are the front end's endpoints, not a published API, so fields can be renamed; the run reports that rather than looking healthy.
  • Win rate is not offered as a --sort-by, because the endpoint gave no evidence it sorts by it.
  • The Scraper API path reads announcements only; this repo does not implement a POST through the Scraper API.

2scraper vs. hosted scraper APIs

2scraperTypical hosted API
CodeOpen source, MIT — read and patch itClosed
CostFree; optional services billed only when usedSubscription or per request / per result
Runs onYour machine, server or CIThe vendor's infrastructure
OutputJSON/CSV files + run metadataAPI responses
When the site changesFix it yourself or open an issue / PRWait for the vendor
FAQ

Binance scraper FAQ

Do I need a Binance account or API key?

No. It reads the public P2P advert list, copy-trading leaderboard and announcement catalogues that the site fetches for an anonymous visitor. It places no order and reads nothing behind a login.

Do I need a browser?

No. http_scraper.py sends the same requests with plain requests and writes the same rows. The browser engines matter only if AWS WAF ever moves in front of the endpoints, when only a browser can run its challenge or have its CAPTCHA solved.

Why does a buy query return adverts marked sell?

An advert carries the maker's side. The side column holds what you asked for and advertiser_side holds what the advert says.

How many pages can I ask for?

--pages is planned against the total the site states on page 1, so asking for more pages than exist fetches all of them and stops.

What output formats are there?

JSON and CSV, plus a <out>.meta.json sidecar with run status and the site's own total. A run that finds nothing writes nothing, so last night's good output is never replaced with an empty file.

Is scraping Binance legal?

This reads public data only. Rate limits, terms of service and the law in your jurisdiction are your responsibility; --delay defaults to 1 second between pages.