Python调用LDA API时如何匹配候选人姓名的拼写变体与录入错误
LDA API姓名异写/拼写错误匹配方案
问题背景
- 基于senate.gov站点的《游说披露法》(Lobbying Disclosure Act, LDA)API搭建数据库,存储游说者、游说团体向国会公职特定候选人提供的所有捐款记录。
- 官方LDA数据规整度较差,提交表单的游说者常出现政客姓名拼写错误、同一姓名使用不同变体写法的问题。
典型场景:同一位候选人的收款人姓名可能被记录为John Smith、Jonathan Smith、Jon Smith等多种形式。
- 需求:无需手动录入所有姓名变体,通过类似
J.*n Smith的正则规则实现匹配,避免遗漏存在异写、拼写错误的记录。
原有代码参考
可正常运行但未适配异写场景的版本
import requests import json import csv Candidate = John Smith Payee_Parameter = { "contribution_payee": Candidate, "dt_posted": "ascending", "key": "1234" } ContributionsLink = "https://lda.senate.gov/api/v1/contributions/" response = requests.get(ContributionsLink, params=Payee_Parameter) data = json.loads(response.text) lines = json.dumps(response.json(),indent=4) # 后续代码功能为按分类整理结果写入csv文件
失效的正则适配版本
尝试直接将编译后的正则对象传入URL查询参数,方案运行失败,推测原因是无法直接将正则对象传入URL查询参数。
import requests import json import csv import re Candidate = r'J.*n Smith' pattern = re.compile(Candidate) Payee_Parameter = { "contribution_payee": pattern, "dt_posted": "ascending", "key": "1234" } ContributionsLink = "https://lda.senate.gov/api/v1/contributions/" response = requests.get(ContributionsLink, params=Payee_Parameter) data = json.loads(response.text) lines = json.dumps(response.json(),indent=4) # matches = pattern.finditer(data) <-- 猜测这个方法可能有用?我刚接触正则,Python水平尚可
解决方案
核心问题说明
LDA API本身不支持在查询参数中传入正则表达式做服务端匹配,HTTP请求参数仅支持字符串类型值,即便传入正则格式的字符串,服务端也不会解析执行,这是之前方案失效的根本原因。
可行的实现路径为宽范围拉取数据+本地正则过滤,具体实现步骤如下:
- 第一步:请求API时不要传入完整姓名作为查询条件,仅传入姓氏(比如示例中的
Smith)做宽泛查询,把所有同姓氏的捐款记录全部拉取到本地。注意LDA API为分页返回,单次请求最多返回25条结果,需要循环遍历所有分页地址,直到拉完所有符合条件的数据。 - 第二步:在本地用提前编译好的正则规则,遍历所有拉取到的记录,匹配收款人姓名,筛出符合要求的条目即可,完全不需要手动录入所有姓名变体。
核心实现代码参考:
import requests import re # 配置姓名匹配正则,加IGNORECASE flag忽略大小写差异 name_pattern = re.compile(r'J.*n Smith', re.IGNORECASE) matched_records = [] # 初始请求地址 next_page_url = "https://lda.senate.gov/api/v1/contributions/" # 基础请求参数,仅传姓氏做宽匹配 base_params = { "contribution_payee": "Smith", "dt_posted": "ascending", "key": "1234" } # 循环拉取全部分页数据 while next_page_url: # 第一页带基础参数,后续分页直接请求返回的next地址即可 if next_page_url.endswith("contributions/"): resp = requests.get(next_page_url, params=base_params) else: resp = requests.get(next_page_url) resp.raise_for_status() page_data = resp.json() # 遍历当前页所有记录,做正则匹配 for record in page_data.get("results", []): payee_name = record.get("contribution_payee", "").strip() if name_pattern.search(payee_name): matched_records.append(record) # 更新下一页地址,拉到最后一页时next为None,循环终止 next_page_url = page_data.get("next") # 后续将matched_records按原有逻辑写入csv即可
优化建议
- 正则规则不要用过于宽泛的
J.*n Smith,这类规则会误匹配到Justin Smith、Jason Smith等无关人员,建议针对目标姓名的常见变体优化规则,比如针对John的各类变体可以写为r'^(John|Jonathan|Jon|Jonathon|Johnathon)\s+Smith$',匹配准确率会高很多。 - 如果需要覆盖更多随机拼写错误场景,正则维护成本太高,可以在正则初筛后,引入字符串编辑距离(比如Levenshtein距离)做二次筛选,将和目标姓名相似度高于设定阈值的记录保留,容错能力更强。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

