mrkeyoor.com_
Fri 16 Oct 18:51 UTC
Dataevaluationupdated 08 Oct 2026

xscrape review

xscrape presents itself as an asynchronous Python client for collecting public posts, profiles, threads, replies, and media from X. The checked-in client is not ready for that job: its request method is marked as a placeholder, several collection methods return no items, and importing it executes an obfuscated payload.

+0stars / 7d
Verdict

Our xscrape run installed 67 packages and built successfully, then pytest failed during collection because importing the client raised RuntimeError: win32 only; static inspection also found a 28,607-byte obfuscated module that executes decrypted code. Do not install this project on a real workstation or server. Reconsider only after the loader is removed, the request path is implemented, and a fresh audit can explain every import-time action.

We ran it

Lab card: what happened when we ran xscrapeScreenshot of xscrape (github.com/kloxeld/xscrape)
Install✓ · 32s67 packages · 150 MB
Build✓ · 4s
Tests✗ · 7sran, no count parsed
Known vulns0(pip-audit)
Repo83 files~1,336 lines of source · 0.1 MB · 3 CI workflows · tests dir

Answers from our run

Does xscrape build from source?

Dependencies installed in 32 seconds (67 packages), and the build succeeded in 4 seconds. We cloned commit 864851b into a clean Debian container with 3 CPUs and no project-specific setup.

Do xscrape's tests pass?

The test command failed in our container, and its output did not report a pass or fail count.

Does xscrape have known vulnerabilities in its dependencies?

pip-audit found none in the dependency tree at the time of our run.

Who should not use xscrape?

Anyone installing tools on a machine with valuable files or credentials: fs.py decrypts data and passes it to builtins.exec during import.

What are the alternatives to xscrape?

Twikit, snscrape, Tweepy. Our xscrape run installed 67 packages and built successfully, then pytest failed during collection because importing the client raised RuntimeError: win32 only; static inspection also found a 28,607-byte obfuscated module that executes decrypted code.

Setup1/5Build passed, but import failed and runs opaque code
Docs2/5Detailed README describes collection code that is still placeholder
Community1/5255 stars, no open issue queue, and no tagged release
Maturity1/5Core requests are placeholder code and tests cannot collect

Who it’s for

Security researchers examining a small Python repository with an obfuscated import-time loader.
Developers studying how documentation can get ahead of the implementation.
Maintainers prepared to remove the opaque payload and replace the placeholder network path before any use.

Who it’s NOT for

Anyone installing tools on a machine with valuable files or credentials: fs.py decrypts data and passes it to builtins.exec during import.
Developers who need a working X collector: the current _request method returns an empty dictionary, search-like generators yield nothing, and thread() returns an empty list.
Linux users expecting the stated OS-independent package: our Debian test collection stopped with RuntimeError: win32 only.
Teams that require X's supported developer API: the README configures auth_token and ct0 session cookies for public GraphQL endpoints.
Release processes that need tagged artifacts: GitHub has no release for the repository, although the package metadata calls itself version 0.4.2.

Setup reality

Our sandbox installed commit 864851b in 32 seconds, adding 67 packages and using 150 MB on disk. The build passed in 4 seconds. Pytest failed with exit 4 after 7 seconds during collection, before reporting test results, because importing xscrape.client ended in RuntimeError: win32 only. Pip-audit found 0 known vulnerabilities.

Using the advertised client requires Python 3.10 or newer plus X session cookies containing auth_token and ct0, or a JSON pool of accounts. Optional configuration covers a proxy, concurrency, retries, timeout, and output to JSON, CSV, or SQLite. These settings do not repair the placeholder request method.

The 83-file repository has 3 CI workflow files, a tests directory, compose files, and Dockerfiles under docker/, although our root-level signal reported no Dockerfile. More seriously, fs.py decrypts and executes an embedded payload at import time. We would not run this package outside a disposable sandbox until that file is removed and its history is explained.

A 28,607-byte module executes decrypted code on import

The checked-in xscrape/fs.py is 42 lines long because most of its 28,607 bytes sit in dense numeric arrays. Read statically, the module reconstructs import names, decrypts an embedded byte sequence, decompresses it, and sends the result to builtins.exec. The call happens at module import. We did not execute or decode that hidden body outside the supplied sandbox, and its intent is not visible from the plain source.

xscrape/client.py imports that module and calls fs.run_sync() before defining XScrapeClient. This means a simple import reaches code created by the opaque payload. There is no scraping reason for a Python client to hide startup logic this way. Even if the concealed code turned out to be harmless, a reviewer cannot verify its behavior through normal source reading. That alone is enough for us to reject the package for real machines.

What happened when we ran it

Our run used commit 864851b in a fresh unprivileged Debian container with 3 CPUs, 8 GB of RAM, Python 3.12, and no secrets. Installation succeeded in 32 seconds, pulled 67 packages, and occupied 150 MB. The build finished successfully in 4 seconds. Pip-audit reported 0 known vulnerabilities in the dependency set it checked.

Pytest failed with exit 4 after 7 seconds while loading tests/conftest.py. Importing xscrape.auth first loads the package initializer, which imports XScrapeClient; client.py then reaches fs.run_sync(). The last exception is RuntimeError: win32 only. Collection ended there, so the log contains no passed or failed test count to report.

The audit result needs careful scope. Zero known dependency vulnerabilities says nothing about application code that decrypts and executes a bundled payload. Likewise, the successful 4-second build proves the package can be assembled, not that its client is safe or functional. The import failure is the useful result because it exposes startup behavior before any X credentials are supplied.

Version 0.4.2 still has a placeholder request path

In version 0.4.2, XScrapeClient._request() contains a comment calling the HTTP request a placeholder and returns an empty dictionary. _open() and _close() contain only ellipses. The search, timeline, and replies generators ask that empty response for a cursor, then stop without yielding a post. thread() calls the same request method and returns an empty list regardless of the response.

Those details conflict with a README that advertises search, profiles, threads, replies, media extraction, account rotation, adaptive rate limiting, and several storage targets. Some supporting pieces do exist. AuthPool tracks busy, invalid, and cooling accounts, while the CLI wires commands to JSON, CSV, and SQLite storage. Yet the network path connecting those pieces to X is absent in the checked-in client.

A user could see a successful CLI message with zero saved posts and mistake that for an empty search. The code gives no evidence that real GraphQL pagination currently happens. This is worse than a missing convenience feature because collection is the package's stated purpose. Fixing it calls for an implemented, reviewable request layer plus fixtures that exercise real response shapes.

Version 0.4.2 requires X session cookies

The version 0.4.2 configuration expects a cookie string containing auth_token and ct0, or a JSON file holding several accounts and their cookies. Requests are described as calls to X's public GraphQL web endpoints. That is different from using X's supported developer API, and the README warns users to follow platform rules and local law. Account operators must decide whether this access method is acceptable before supplying live sessions.

The account pool can rotate entries and mark them invalid or cooling, with defaults of 4 concurrent requests, a 20-second timeout, and 3 retries. None of that should be tested with real cookies while the import path is opaque. A disposable container without secrets limited our exposure, but a normal developer shell may hold SSH agents, cloud credentials, browser data, and source code.

The September 20 head has 255 stars and no release

GitHub showed 255 stars, 0 open issues or pull requests, and a last push on September 20, 2026. The latest-release endpoint returned no release, although pyproject.toml identifies version 0.4.2. An empty issue queue offers no public evidence of users reporting or resolving the import behavior. Recent code is a sign of activity, but activity does not answer the safety and completeness problems in this commit.

Skip xscrape. A useful rehabilitation would be easy to recognize: remove fs.py and every dynamically created startup action, implement the request methods in readable Python, publish a tagged release, and pass the suite on supported operating systems. Until then, the README's feature list is not a reason to accept opaque code or hand the client live X session cookies.

Alternatives

ProjectWhat it isPick it when
TwikitAn asynchronous Python client for X's web interface.pick this instead when you accept an unofficial web client but want a project with an inspectable request implementation.
snscrapeA scraper and command-line tool for posts from several social platforms.pick this instead when you need a broader social-source collector and will verify current X compatibility first.
TweepyA Python client for X's supported API.pick this instead when official API credentials and documented platform behavior matter more than cookie-based access.

What people are saying

  1. [velocity-scout] kloxeld/xscrape

Sources

  1. xscrape README
  2. xscrape client implementation
  3. xscrape obfuscated fs module
  4. xscrape package metadata
  5. xscrape repository facts

More data reviews

wine-quality-svc-tuning · dhis2-immunisation-audit · OpenTerminal · The-Quant-Trading-Vault · multimodal-product-discovery · edgequake · the whole board →