# How to Perform Prior Art Search Using cnipa_epub_search.py: A Complete Guide

> Learn to perform prior art search with cnipa_epub_search.py, an automated tool for CNIPA portal searches. Extract structured JSON data easily.

- Repository: [handsomestWei/patent-disclosure-skill](https://github.com/handsomestWei/patent-disclosure-skill)
- Tags: how-to-guide
- Published: 2026-09-01

---

**[`cnipa_epub_search.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/cnipa_epub_search.py) is a command-line tool that automates prior art searches on the CNIPA "公布公告" portal by driving a headless Chromium browser via Playwright, extracting patent records, and outputting structured JSON data on stdout.**

The `handsomestWei/patent-disclosure-skill` repository provides a specialized toolkit for automating patent disclosure workflows, with [`cnipa_epub_search.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/cnipa_epub_search.py) serving as the primary interface for conducting prior art searches against the China National Intellectual Property Administration's public database at `epub.cnipa.gov.cn`. This script eliminates manual browsing by programmatically navigating the portal, executing queries, and returning standardized JSON results suitable for downstream analysis.

## Prerequisites and Environment Setup

Before executing a prior art search, you must configure the **Playwright** browser automation environment. The tool relies on a headless Chromium instance managed through the shared browser utilities in [`tools/shared/browser.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/shared/browser.py).

Install Playwright and verify browser binaries:

```bash
pip install playwright
python tools/shared/browser.py --probe

```

The script recognizes two optional environment variables for debugging and timing control. Set `EPUB_WAF_MAX_WAIT_SEC` to adjust the maximum wait time for the search box to appear, or enable `PLAYWRIGHT_HEADED=1` to visualize the browser UI during execution for troubleshooting.

## Command-Line Syntax and Patent Types

The script accepts search terms as positional arguments, where each whitespace-separated token represents an independent query merged into a single result set. You must specify the patent type using the `--type` flag, which internally maps to checkbox states defined in [`tools/shared/patent_type.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/shared/patent_type.py) via the `EPUB_TYPE_CHECKBOXES` configuration.

Available patent types include:

- `invention` – Invention patents
- `utility_model` – Utility models  
- `design` – Design patents
- `all` – Search across all categories (default)

Basic invocation structure:

```bash
python tools/crawl/cnipa_epub_search.py --type <type> <search_term>

```

### Advanced Classification Code Filtering

For precision searching, use the `--class` parameter to filter by **International Patent Classification (IPC)** or **Locarno Classification (LOC)** codes. This triggers an advanced search workflow within the crawler.

- Use IPC codes (e.g., `B01J20`) for invention and utility model patents
- Use LOC codes (e.g., `26-05`) for design patents

## Implementation Architecture

Understanding the source code structure helps debug issues and extend functionality. The search workflow spans four primary modules:

**[`tools/crawl/cnipa_epub_search.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/crawl/cnipa_epub_search.py)** – The CLI entry point that parses arguments via `_parse_argv`, orchestrates the search, merges results, and prints the final JSON output prefixed with `EPUB_HITS_JSON:`.

**[`tools/crawl/cnipa_epub_crawler.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/crawl/cnipa_epub_crawler.py)** – Contains the `search_epub_keywords` function that manages the Playwright browser session, handles the CNIPA home page readiness check, applies type filters, submits queries, and detects result page completion.

**[`tools/crawl/cnipa_epub_parse.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/crawl/cnipa_epub_parse.py)** – Implements `parse_search_result_html` to extract patent data from both table-based and card-based HTML layouts, returning structured `EpubSearchHit` objects containing title, publication number, direct links, abstracts, and classification codes.

**[`tools/shared/patent_type.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/tools/shared/patent_type.py)** – Defines the patent type mappings and validation logic used to translate CLI arguments into the correct checkbox selections on the CNIPA portal.

## Practical Usage Examples

Execute targeted searches using these common patterns:

Search for "玻璃" across all patent types:

```bash
python tools/crawl/cnipa_epub_search.py 玻璃

```

Restrict to utility models only:

```bash
python tools/crawl/cnipa_epub_search.py --type utility_model 卡扣

```

Design patent search with LOC classification:

```bash
python tools/crawl/cnipa_epub_search.py --type design --class 26-05 台灯

```

Invention search with IPC classification:

```bash
python tools/crawl/cnipa_epub_search.py --type invention --class B01J20 胺功能化

```

## Output Format and Data Structure

The script streams diagnostic messages to **stderr** (prefixed with `EPUB_MERGE` and `EPUB_NOTE`) while printing the final results to **stdout** as a single JSON line. Successful executions output:

```

EPUB_HITS_JSON: [{"title": "...", "pub_number": "CN209861402A", "link": "http://epub.cnipa.gov.cn/patent/CN209861402A", "abstract": "...", "ipc_codes": ["B01J20/12"], "loc_codes": []}, …]

```

Each object represents an `EpubSearchHit` with the following fields:

- `title` – Patent title
- `pub_number` – Publication number (e.g., `CN209861402A`)
- `link` – Direct URL to the detailed record
- `abstract` – Optional abstract text
- `ipc_codes` – Array of IPC classifications
- `loc_codes` – Array of LOC classifications

## Summary

- **[`cnipa_epub_search.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/cnipa_epub_search.py)** automates CNIPA prior art searches using Playwright to control a headless Chromium browser
- The tool supports **invention**, **utility_model**, **design**, and **all** patent types, configurable via the `--type` argument
- Advanced searches use `--class` to filter by IPC or LOC classification codes
- Results are output as JSON prefixed with `EPUB_HITS_JSON:` for easy parsing by downstream tools
- Key modules include [`cnipa_epub_crawler.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/cnipa_epub_crawler.py) for browser automation and [`cnipa_epub_parse.py`](https://github.com/handsomestWei/patent-disclosure-skill/blob/main/cnipa_epub_parse.py) for HTML extraction

## Frequently Asked Questions

### What dependency is required to run cnipa_epub_search.py?

You must install **Playwright** (`pip install playwright`) and ensure browser binaries are available by running `python tools/shared/browser.py --probe`. This provides the Chromium instance needed to render the CNIPA website's JavaScript-heavy interface.

### Can I search for multiple terms in a single execution?

Yes. Pass multiple whitespace-separated terms as positional arguments; the script treats each as an independent query and merges the results into a single JSON array. For example: `python tools/crawl/cnipa_epub_search.py term1 term2 term3`.

### How do I debug the browser automation if the search fails?

Set the environment variable `PLAYWRIGHT_HEADED=1` to run the browser in visible mode, allowing you to observe the page interaction. Additionally, adjust `EPUB_WAF_MAX_WAIT_SEC` to increase timeout limits if the CNIPA portal responds slowly.

### What is the difference between IPC and LOC classification codes in the --class parameter?

**IPC** (International Patent Classification) codes apply to invention and utility model patents (e.g., `B01J20`), while **LOC** (Locarno Classification) codes apply specifically to design patents (e.g., `26-05`). The script passes these codes directly to the CNIPA advanced search form without validation, so ensure the format matches the target patent type.