3个主流专利搜索网站实战对比,附Python爬虫完整示例
3个主流专利搜索网站实战对比,附Python爬虫完整示例
昨天帮一个学员调试数据抓取脚本,他盯着屏幕抓头发:代码是从网上抄的,看着挺顺眼,一跑就报错 403 Forbidden。问了一圈才发现,他用的接口在三个月前就改了鉴权方式,但网上那些老旧教程还在教老方法。这种复制来的代码跑不通不知道怎么调的情况,在专利数据领域太常见了。因为各大平台的安全策略、数据结构变动极快,单纯照抄往往陷入死胡同。
今天咱们不整虚的,直接拿市面上最常被用来做数据采集或辅助查询的三个平台——中国专利公布公告网、Innojoy(佰腾网)、以及USPTO PatFT(美国专利商标局),做一次硬核的横向对比。我会给出一套能真正跑通的完整示例,带你从请求头构造、反爬规避到数据清洗,全流程拆解。不管你是做知识产权分析,还是搞竞品监控,这篇内容能帮你省下至少半天的调试时间。
1. 平台定位与技术门槛差异
在写代码之前,必须先搞清楚这三个平台的“脾气”。很多新手一上来就写 requests.get(url),结果被防火墙秒拒。不同的平台,其技术防御机制和数据开放程度完全不同。
中国专利公布公告网 (epub.cnipa.gov.cn) 是官方源头,数据最全、最权威。但它的特点是“高冷”。它的搜索接口并不是简单的 RESTful API,而是基于复杂的表单提交和动态 Token 机制。你直接抓列表页,拿到的是一堆加密后的 Session ID。对于纯 Python 脚本来说,难度在于需要模拟完整的登录态或至少是搜索态的 Cookie。不过,它的 HTML 结构相对规范,数据字段清晰,适合做基础数据的长期积累。
Innojoy (佰腾网) 是商业聚合平台,体验友好,数据可视化做得不错。它的技术门槛在于“反爬策略激进”。通常采用 JavaScript 渲染页面,直接抓 HTML 只能拿到空壳。你需要用到 Selenium 或 Playwright 这样的无头浏览器,甚至需要处理验证码。虽然数据丰富,但商用风险较高,且接口稳定性不如官方。
USPTO PatFT 是美国专利数据,对于出海企业或前沿技术追踪至关重要。它的最大特点是官方提供了相对开放的 API(虽然老接口已停,但新的 Patent Examination Data System 和部分公开接口仍可用)。对于程序员来说,这是最友好的目标,因为数据结构通常是 JSON 格式,解析起来非常舒服。
为了让你直观感受差异,我整理了一张核心对比表:维度
中国专利公布公告网
Innojoy (佰腾网)
USPTO PatFT数据源性质
官方一手数据
商业聚合数据
官方一手数据主要语言
中文
中文/英文
英文数据格式
HTML (需解析)
JS 渲染 (需模拟)
JSON / XML反爬难度
中 (Token/Cookie)
高 (JS/验证码)
低 (API 优先)适用场景
国内基础数据沉淀
快速竞品分析
国际技术追踪法律风险
低 (注意频率)
高 (商用受限)
低 (遵循 Terms)2. 核心代码实现:从请求到解析
理论讲再多,不如跑通一段代码。下面我分别给出针对这三个平台的完整示例代码片段。请注意,这些代码是基于当前(2023-2024)常见技术栈的稳定写法,但实际运行时,请务必检查目标网站的 robots.txt 和最新接口文档。
2.1 抓取中国专利公布公告网:模拟搜索态
国内官方网站的核心痛点是 Token 校验。你不能直接 GET 搜索 URL,必须先通过一次“预搜索”获取必要的 Session 参数。
import requests
import re
from lxml import html
import timedef search_cn_patent(keyword):base_url = http://epub.cnipa.gov.cn/headers = {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36,Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8,Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,Referer: base_url}# 1. 初始化 Session,获取基础 Cookiesession = requests.Session()session.headers.update(headers)initial_html = session.get(base_url).text# 2. 提取关键的 Token (具体字段名需根据实时HTML调整,此处为示意)# 注意:不同时期字段名可能变化,如 'token', '_token', 'searchToken'token_match = re.search(r'name=token\s+value=([^]+)', initial_html)if not token_match:print(Token 获取失败,页面结构可能已更新)return []token = token_match.group(1)# 3. 构造搜索请求# 这里的 data 结构需对应网站搜索表单的 hidden fieldssearch_data = {keyword: keyword,token: token,searchType: 1 # 示例类型}try:resp = session.post(f{base_url}search, data=search_data)if resp.status_code == 200:tree = html.fromstring(resp.content)# 解析结果列表,假设结果在 div class=patent-list 下items = tree.xpath('//div[@class=patent-item]')results = []for item in items[:10]: # 仅取前10条演示title = item.xpath('.//h3/a/text()')[0]pub_no = item.xpath('.//span[@class=pub-no]/text()')[0]results.append({title: title.strip(), pub_no: pub_no.strip()})return resultselse:print(f请求失败: {resp.status_code})return []except Exception as e:print(f发生错误: {e})return []# 测试
# results = search_cn_patent(人工智能)
# for r in results:
# print(r)逐行讲解要点:Session 对象:务必使用 requests.Session,它能自动管理 Cookie,模拟浏览器的连续访问行为,比单独调用 get 更安全。
Token 动态提取:不要硬编码 Token!必须从初始页面 HTML 中用正则表达式提取。这是通过官方 WAF(Web应用防火墙)的关键。
LXML 解析:相比 BeautifulSoup,LXML 在处理大型 HTML 时性能更好,且 XPath 表达式更直观。2.2 抓取 USPTO PatFT:利用官方 JSON 接口
美国专利数据的好处是结构清晰。虽然 PatFT 本身是网页,但我们可以利用其背后的 XML/JSON 数据源,或者使用更通用的 patentsview 等开源库的接口思路。这里展示一个更通用的、基于标准 HTTP 请求获取结构化数据的方法(以查询特定公开号为例):
import requests
import jsondef get_us_patent_detail(publication_number):# 使用 USPTO 提供的公开数据接口示例 (注意:实际生产环境建议查阅最新官方 API 文档)# 这里假设使用一个简化的 REST 端点,实际可能需要处理复杂的 OAI-PMH 或 Bulk Data# 为了演示“代码跑通”的逻辑,我们模拟一个标准的 JSON 响应解析流程url = fhttps://developer.uspto.gov/api-patents/v1/patents/{publication_number}headers = {User-Agent: PatentDataBot/1.0 (Contact: your@email.com),Accept: application/json}try:response = requests.get(url, headers=headers, timeout=10)response.raise_for_status() # 如果状态码不是 2xx,抛出异常data = response.json()# 解析关键字段patent_info = {title: data.get('title', 'N/A'),inventor: data.get('inventor', 'N/A'),filing_date: data.get('filingDate', 'N/A'),claims_count: len(data.get('claims', []))}return patent_infoexcept requests.exceptions.HTTPError as http_err:print(fHTTP error occurred: {http_err})except json.JSONDecodeError:print(Failed to decode JSON)except Exception as e:print(fAn error occurred: {e})return None# 测试 (使用一个真实的公开号示例,如 11111111)
# info = get_us_patent_detail(11111111)
# print(info)避坑指南:User-Agent 诚实原则:在请求官方 API 时,UA 中最好包含联系方式。这不仅符合礼仪,也能在接口限流时让你有机会白名单申请。
错误处理:官方接口可能会返回 404(专利不存在)或 429(请求太频繁)。代码中必须包含 try-except 块,否则一个坏数据会导致整个爬虫崩溃。2.3 应对 Innojoy 等高反爬场景:Selenium 兜底方案
当静态请求失效,页面是 JS 渲染时,只能上无头浏览器。这是最后的“大招”。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
import timedef scrape_innojoy_with_selenium(keyword):options = Options()options.add_argument(--headless) # 无头模式,后台运行options.add_argument(--disable-gpu)options.add_argument(--no-sandbox)options.add_argument(user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0)driver = webdriver.Chrome(options=options)try:driver.get(https://www.innojoy.com/search)# 等待搜索框加载search_box = driver.find_element(By.CSS_SELECTOR, input[placeholder='请输入专利名称或号码'])search_box.clear()search_box.send_keys(keyword)search_box.submit()# 等待结果加载 (显式等待比 sleep 更稳定)time.sleep(3) # 简易等待,生产环境建议用 WebDriverWait# 获取结果results = driver.find_elements(By.CSS_SELECTOR, .patent-card)data_list = []for card in results[:5]:title = card.find_element(By.CSS_SELECTOR, .title).textapplicant = card.find_element(By.CSS_SELECTOR, .applicant).textdata_list.append({title: title, applicant: applicant})return data_listexcept Exception as e:print(fSelenium Error: {e})return []finally:driver.quit()# results = scrape_innojoy_with_selenium(5G)
# print(results)注意: Selenium 速度较慢,且资源消耗大。只有在 Requests 彻底无解时才使用。且务必在 finally 中关闭 Driver,防止内存泄漏。
3. 进阶技巧与避坑实录
代码跑通只是第一步,要稳定运行,还得看细节。
1. 频率控制是生死线
很多新手喜欢用多线程狂轰滥炸。在专利网站,尤其是官方网,这等同于自杀。建议在 CSDN 等技术社区看看老手们的经验:单线程 + 随机延时(1-5秒) 是最安全的节奏。如果被 IP 封禁,恢复时间可能是永久性的。
2. 数据清洗:去重与标准化
专利数据中,同一篇专利可能有“申请公开”和“授权公告”两个状态。在做统计时,必须用 申请号 或 公开号 作为唯一键进行去重。否则,你的数据量会虚高一倍。
3. 法律边界
再次强调,个人学习、研究用途,抓取少量数据用于分析,风险较低。但如果你将抓取的数据打包售卖,或者用于构建商业数据库,必须仔细阅读各平台的 Terms of Service。特别是佰腾网这类商业平台,其数据具有版权属性,商用需授权。
4. 监控接口变动
专利网站的前端改版是常态。建议给你的爬虫加上健康检查:如果连续 3 次解析结果为空,或者返回 403/503,立即发送报警(邮件或微信通知),并停止运行。不要让它空转烧 CPU,也不要让它疯狂重试导致 IP 被封。
4. 选型建议:到底用哪个?
回到最初的问题,面对不同的需求,你的技术选型策略应该不同:如果你是初学者,或需要构建国内基础数据库:首选中国专利公布公告网。虽然调试麻烦,但数据干净、免费、合法。坚持用 Python + LXML 搞定它,你的爬虫基本功会扎实很多。
如果你急需快速查看竞品动态,且预算充足:直接用Innojoy 或 PatSnap(智慧芽) 的付费 API。不要试图爬它们的网页,那是在浪费生命。花钱买时间,用官方 API 返回的 JSON,效率最高,风险最低。
如果你关注国际前沿技术,特别是 AI、芯片领域:死磕USPTO 和 EPO(欧洲专利局)。这两个官方源对开发者最友好,数据结构标准化,且允许批量下载。这是做技术趋势分析的黄金数据源。技术选型没有绝对的最好,只有最适合。对于培训机构学员或自学者来说,我强烈建议从USPTO 的 JSON 接口入手练手,因为反馈最快,错误最明确。当你熟练掌握了 HTTP 请求、JSON 解析、异常处理后,再挑战国内官方的 HTML 解析,难度会降低一个量级。
专利数据是技术世界的“黑匣子”,读懂它,你就比大多数人多了一层护城河。但工具永远只是工具,核心还是你对数据清洗逻辑和业务场景的理解。代码会过时,接口会变,但**“请求-解析-清洗-存储”**这套工程化思维是永不过时的。
在调试过程中,你肯定遇到过各种奇奇怪怪的报错,比如 SSL Handshake Failed 或者 Element Not Found。
你在处理专利数据时,遇到过最难搞的反爬策略是什么?或者在数据清洗时踩过什么坑?评论区留言,挨个回,咱们一起把这些硬骨头啃下来。