关于 israel-gov-api
israel-gov-api 是用于通过以色列 data.gov.il CKAN API 查找、查询和分析数据集的技能。它涵盖数据集发现、查询限制、分页、数据质量陷阱,以及附带注意事项呈现结果。
主要功能
- 01按关键词或政府部门搜索数据集
- 02获取数据集元数据和表格记录
- 03筛选、排序并分页查询
- 04处理 SQL、WAF 和响应格式问题
- 05检查数据质量与新鲜度
适用场景
- 01为研究主题查找政府数据
- 02从数据集中提取筛选后的记录
- 03合并数据集并核对字段差异
- 04附带数据注意事项呈现统计结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ skills-il/ government-services --skill israel-gov-api安装后在 Claude Code 中输入/israel-gov-api确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CHANGELOG.mdevidence.jsonmetadata.jsonoptimization-log.jsonSKILL_HE.mdreferences/ckan-api-reference.mdscripts/query_datagov.py详细介绍
以色列政府 API
说明
第 1 步:了解数据需求
询问用户:
- 主题是什么?(交通、医疗、教育、经济等)
- 地理范围是什么?(全国、特定城市/地区、特定地址)
- 时间范围是什么?(当前、历史、时间序列)
- 格式是什么?(原始数据、汇总统计、可视化)
第 2 步:搜索数据集
使用 data.gov.il CKAN API 查找相关数据集:
按关键词搜索:
GET https://data.gov.il/api/3/action/package_search?q=KEYWORD&rows=10
按组织(部委)搜索:
GET https://data.gov.il/api/3/action/package_search?fq=organization:MINISTRY_ID
常见组织 ID(这 7 个 ID 均于 2026-08-27 通过 package_search?fq=organization:<id> 重新验证,且每个都返回非零计数):
| 部委 | ID | 希伯来语 |
|---|---|---|
| 中央统计局 | lamas | halishka hamerkazit listatistika |
| 交通部 | ministry_of_transport | misrad hatahaburah |
| 卫生部 | ministry-health | misrad habriut |
| 教育部 | ministry_of_education | misrad hachinuch |
| 以色列税务局 | taxes-authority | rashut hamisim |
| 以色列土地管理局 | the_israel_lands_administration | rashut mekarkei yisrael |
| 内政部 | interior_affairs | misrad hapnim |
步骤 3:检索和查询数据
找到数据集后:
获取数据集详情:
GET https://data.gov.il/api/3/action/package_show?id=DATASET_ID
查询表格数据(数据存储):
GET https://data.gov.il/api/3/action/datastore_search?resource_id=RESOURCE_ID&limit=100
按字段值筛选:
GET https://data.gov.il/api/3/action/datastore_search?resource_id=RESOURCE_ID&filters={"field_name":"value"}&limit=100
选择特定字段并排序:
GET https://data.gov.il/api/3/action/datastore_search?resource_id=RESOURCE_ID&fields=field1,field2&sort=field1 desc&limit=100
在资源中进行全文搜索:
GET https://data.gov.il/api/3/action/datastore_search?resource_id=RESOURCE_ID&q=search+term&limit=100
datastore_search_sql 可以正常使用,但有一个 WAF 形状的漏洞。 于 2026-08-27 在线重新测试:SELECT、WHERE、ORDER BY、GROUP BY、sum() 和 LIMIT 均返回 HTTP 200,且 success:true 并带有真实数据行。WAF 会拦截少数带有注入特征的子字符串,其中包括 count(、1=1 和 UNION;它返回的是 HTML 404 页面,而不是 JSON 错误,也不是 403,因此只检查 success 的客户端会将拦截误判为解析失败。
- 用
sum(1)替代count(*)。SELECT col, sum(1) AS n FROM "<resource_id>" GROUP BY col ORDER BY n DESC LIMIT 10返回的结果与被拦截的count(*)写法完全相同。 - 如需获取普通行数,无需使用 SQL:
datastore_search的total字段已经包含该值。 - SQL 是实现真正键集分页的唯一方式。
filters无法做到这一点,但SELECT ... FROM "<rid>" WHERE _id > <last_id> ORDER BY _id LIMIT <n>可以正常工作,无论翻到多深都能保持快速,不像深度offset。 - 诊断问题前,先查看响应的结构。 data.gov.il 对这两类失败的响应截然不同,混为一谈会让 Agent 朝错误的方向排查:
- HTTP 409 且正文为 JSON,包含
psycopg2消息 = SQL 已到达 Postgres,但被 Postgres 拒绝(列名未知、语法错误、表名未知)。阅读消息并修正查询。 - HTTP 404 且正文为约 1.4 kB 的 HTML 页面 = 请求根本没有到达 SQL 层。这是网站的通用错误页面,至少有三个不同的成因:WAF 匹配到子字符串、操作名称未定义,以及
resource_id不存在。不要假定这一定是 WAF 导致的。对同一资源重新运行一个已知有效的查询(SELECT * FROM "<rid>" LIMIT 1)以区分原因:如果成功,说明资源正常,是你的 SQL 触发了 WAF;如果仍返回 HTML,则说明resource_id无效或操作名称错误。
- HTTP 409 且正文为 JSON,包含
提示:
- 字段名称通常为希伯来语——先使用
datastore_search并设置limit=1,查看字段名称 - 使用带有 JSON 对象的
filters参数精确匹配字段(例如,filters={"city_code":"5000"}) - 使用
q参数跨所有字段进行全文搜索 - 对于大型数据集,使用
limit和offset分页 - 日期字段可能采用多种格式——请查看数据集文档
分页:
- 使用
limit+offset分页:响应会返回_links.next(基于offset的下一页 URL),你可以直接跟进该链接,也可以自行递增offset。深度offset分页仍然可用(较大的偏移量也会返回数据,没有硬性上限),但页数越靠后,每次请求越慢。 - data.gov.il 的
filters仅支持精确匹配,因此无法**通过filters**进行_id键集分页:filters={"_id":">N"}会返回success:false(查询无效)。请使用offset分页,或使用带有WHERE _id > N ORDER BY _id的datastore_search_sql,以实现真正的键集分页(见步骤 3)。 - 对于非常大的数据集或整表提取,请传入
records_format=csv,或从package_show中的resources[].url下载资源文件。请注意,资源文件通常是 XLSX,而不是 CSV(mosdot 资源就是如此),因此records_format=csv是可靠的 CSV 获取方式;请先检查resources[].format,再作假设。 - 响应的
total字段是资源中的所有记录数(而非当前页的记录数),因此可用它来规划所需的页数。 records_format接受objects(默认 JSON)、lists(位置数组)、csv或tsv。对于大型数据提取,lists和csv明显更快、成本更低;流式处理或批量提取时请优先使用它们。
步骤 3b:数据层陷阱(引用任何数据前请阅读)
步骤 3 可以让你获得包含行的 200 响应。以下是这些行仍然可能出错的情况。每一种情况都已于 2026-08-27 在实时 API 上复现。
文本列会填充空格,看起来像数字的代码实际以文本形式存储。 在 CBS 地方资源中,סמל_ישוב 的类型是 text,其值带有尾随空格:filters={"סמל_ישוב":"4000"} 会返回 success:true 且 total:0,而 "4000 " 则会返回 Haifa。零行成功是此 API 最常见的无声错误,因为 Agent 会报告“没有数据”,看起来一切正常。对文本字段进行等值筛选前,务必先用 limit=1 检查原始值,然后通过 filters 匹配带填充空格的精确字符串({"סמל_ישוב":"4000 "} 可行),或者改用 q= 全文搜索。由于下一段所述原因,你无法在 SQL 中通过 TRIM 解决这个问题。
WAF 还会拦截在谓词或函数中引用希伯来语列名的 SQL。 这是此 API 最令人意外的限制,也决定了你该使用哪个工具。已于 2026-08-27 验证:
| SQL | 结果 |
|---|---|
SELECT "שנה" FROM "<rid>" LIMIT 1 | 200,可用 |
... GROUP BY "שנה" | 200,可用 |
... ORDER BY to_date("תאריך רישום עמותה",'DD/MM/YYYY') DESC | 200,可用,且是处理文本日期的正确方法 |
... WHERE "שנה" = 2015 | HTML 404,已拦截 |
... WHERE TRIM("סמל_ישוב") = '4000' | HTML 404,已拦截 |
... WHERE shnat_yitzur = 2016(拉丁字母列) | 200,可用 |
... WHERE _id > 100 | 200,可用 |
因此,职责划分如下:使用 datastore_search 的 filters 筛选希伯来语列(可以正确处理希伯来语值,但要遵守上述尾随空格规则),并使用 SQL 进行 _id 键集分页、拉丁字母列谓词、GROUP BY、sum(1) 和 to_date 排序。不要尝试在 SQL 中对希伯来语列执行 TRIM:应改用 filters 匹配带填充空格的精确字符串。
不做规范化时,按地方名称联接无法正常工作。 本技能指导你联接的两个资源中,同一座城市有三种拼写:地方资源中是 'תל אביב - יפו '(尾随空格),mosdot 的 שם ישוב 中是 'תל אביב - יפו',而 שם רשות 中是 'תל אביב-יפו'。直接进行等值联接会丢弃所有行。请提取两边的数据并在自己的代码中规范化(去除空格,然后统一连字符周围的空格);由于对希伯来语列使用函数会被拦截,因此无法在 SQL 中执行规范化。
有些资源是多年面板数据,其标题所示的行数并不代表事物的数量。 mosdot 资源仅包含 2011 至 2015 年每家机构每年的一行,因此其 119,761 行是同一批机构的五年数据,且不含 2015 年之后的数据。统计任何内容前,先按 שנה 筛选,绝不要把资源总行数说成“学校数量”。
资源元数据的新旧程度不代表数据的新旧程度。 mosdot 的 resource_show 显示 last_modified 为 2026 年,指的是文件重新发布的时间,而文件内的数据截至 2015 年。向用户引用数据前,应根据数据自身的日期列确定其时间范围。
日期列是文本,因此对其使用 sort 会按字典序排序,结果不正确。 在 amutot 资源中,תאריך רישום עמותה 和 תאריך עדכון סטטוס 的类型都是 text,格式为 DD/MM/YYYY,因此 sort=תאריך רישום עמותה desc 会把 31/12/2025 排在任何 2026 年 1 月的记录之前:它优先按日排序。即使在同一资源中,不同列的日期格式也可能不同。要按真正的时间顺序排序,请使用 SQL:ORDER BY to_date("תאריך רישום עמותה",'DD/MM/YYYY') DESC 会将 26/08/2026 排在最前面,此结果已于 2026-08-27 验证。即使希伯来语列也可以在 ORDER BY 中使用 to_date;只有谓词和 TRIM 会被拦截。
records_format=csv 返回的是没有标题行的 CSV 字符串。 列名只存在于 result.fields 中,且顺序与列相同。请自行将其添加为标题行,否则希伯来语列会悄无声息地错位。
查询前请检查 datastore_active。 package_show / resource_show 会为每个资源提供该字段,且它与 format 无关:mosdot 资源的格式是 XLSX,但仍然 datastore_active:true。对于 datastore_active:false 的资源,必须从 resources[].url 下载并在本地解析。
第 4 步:分析并呈现
对于检索到的数据:
- 用通俗易懂的语言概述关键发现
- 按需计算基本统计数据(平均值、中位数、趋势)
- 根据数据建议合适的可视化方式(条形图、折线图、地图)
- 说明数据的时效性(最后更新日期)及任何注意事项
- 提供 data.gov.il 上数据集的直接链接,以供参考
第 5 步:交叉引用(高级)
组合多个数据集时:
- 找出共同键(城市代码、日期、类别代码)
- 使用以色列行政区划代码(CBS 城市代码)进行地理关联
- 请注意,不同数据集中的字段名称可能不同——应按内容而不是名称匹配
- 记录数据沿袭:分析中使用了哪些数据集
常用数据集
以下资源 ID 已于 2026-08-27 通过 datastore_search?resource_id=<id>&limit=1 在线验证,检查的是响应 BODY(即使状态显示成功,若 records 数组为空,也表示该资源已失效)。data.gov.il 上的 ID 可能会在未通知的情况下变更。向用户引用前务必重新验证。
| 数据集 | 资源 ID | 描述 |
|---|---|---|
| 私人和商用车辆(车辆注册) | 053cea08-09bc-40ec-8f7a-156f0677aff3 | 私人和商用车辆车牌的完整登记册,包含品牌、型号和年份。417 万行。 |
| 公共交通车辆 | cf29862d-ca25-4691-84f6-1be60dcb4a1e | 公共交通车辆(公交车、出租车)的有效车牌。65,953 行。 |
教育机构(mosdot) | 5548fd63-5868-4053-ad81-98caddc5e232 | 由教育部监管的教育机构的特征数据。119,761 行。资源格式为 XLSX。 |
| 注册的非营利组织(amutot) | be5b7935-3922-45d4-9638-08871b17ec95 | 司法部的社团/非营利组织登记册。75,680 行。 |
对于其他领域,请使用 package_search 查找当前数据集,然后使用 package_show 获取有效的 resources[].id——数据集每年重新发布时,这些 ID 都会轮换。
data.gov.il 上没有的内容(已于 2026-08-27 验证;在 CKAN 中搜索这些内容会浪费用户的请求,还容易诱使 Agent 虚构数据集):
| 数据 | 实际所在位置 | CKAN 证据 |
|---|---|---|
| 房地产交易 | nadlan.gov.il(其自有 API,不属于 CKAN) | q=nadlan 返回数量为 0;fq=organization:taxes-authority 返回 4 个数据集,全部与海关有关 |
| 公共交通 GTFS | gtfs.mot.gov.il(静态 zip 文件) | q=gtfs 返回 2 个不相关的数据集 |
| 大多数 CBS 统计序列,包括按地方统计的人口数据 | cbs.gov.il | fq=organization:lamas 返回 14 个数据集,主要是道路事故 PUF,以及地方代码列表;没有一个包含人口数据 |
| 货币和金融序列 | boi.org.il | 未通过 CKAN 发布 |
CKAN 上的 lamas 组织仅包含 CBS 输出的一小部分。未确认特定 CBS 序列已发布在该门户上之前,不要向用户承诺可以提供。
示例
示例 1:查找学校数据(完整链式工作流)
用户说:“我需要特拉维夫的学校数据。”
操作(不要跳过查找步骤——资源 ID 会轮换):
- 查找候选数据集:
curl -s "https://data.gov.il/api/3/action/package_search?q=mosdot&rows=5" - 检查选定的数据集,并获取当前有效的
resources[].id:curl -s "https://data.gov.il/api/3/action/package_show?id=mosdot" \ | python3 -c "import sys,json; r=json.load(sys.stdin)['result']['resources']; [print(x['id'], x['format'], x.get('name','')) for x in r]" - 使用
limit=1查看字段名称:curl -s "https://data.gov.il/api/3/action/datastore_search?resource_id=5548fd63-5868-4053-ad81-98caddc5e232&limit=1" - mosdot 资源将地区公开为名为
שם ישוב的 NAME 字段(城市名称文本,例如תל אביב - יפו),而不是数字城市代码。按城市名称筛选(或使用q=进行全文搜索);希伯来语必须进行百分号编码:
CBS 地区数字代码(特拉维夫-雅法为 5000,海法为 4000,耶路撒冷为 3000)对应字段# full-text search for Tel Aviv schools (q = "תל אביב", percent-encoded) curl -s "https://data.gov.il/api/3/action/datastore_search?resource_id=5548fd63-5868-4053-ad81-98caddc5e232&q=%D7%AA%D7%9C%20%D7%90%D7%91%D7%99%D7%91&limit=100"סמל_ישוב,但它位于 CBS 地区数据集中(资源5c78e9fa-c2e2-4771-93ff-7f400a12f7ba),不在 mosdot 资源中。字段值是前后带空格的文本,因此要使用TRIM(...)进行匹配,并在联接前规范化城市名称(见步骤 3b)。 - 选择一个年份,否则结果会包含重复的五年数据。 mosdot 资源是一个年度面板,仅涵盖 2011 至 2015 年,因此未筛选的
q=תל אביב返回的 18,574 条结果并不代表学校数量。שנה是希伯来语列名,因此要通过datastore_search筛选,不能使用 SQL(对希伯来语列使用 WHERE 会被 WAF 拦截,见步骤 3b):
从该响应中读取# schools in the 2015 slice, filtered by year through `filters` curl -s 'https://data.gov.il/api/3/action/datastore_search?resource_id=5548fd63-5868-4053-ad81-98caddc5e232&filters=%7B%22%D7%A9%D7%A0%D7%94%22%3A%222015%22%7D&limit=1'total作为数量。年度明细本身可以通过合法的 SQL 查询获取,因为允许对希伯来语列使用GROUP BY,但不允许使用WHERE:SELECT "שנה", sum(1) AS n FROM "5548fd63-5868-4053-ad81-98caddc5e232" GROUP BY "שנה"
结果:提供特拉维夫某个指定年份的学校列表,并注明其数据为 2015 年版本,而不是当前数据。
示例 2:目录无法满足的请求
用户说:“请展示海法的房价趋势。”
这里正确的做法是停止,而不是继续搜索。房地产交易数据不在 data.gov.il 上:q=nadlan 返回的数量为 0,且经核实,税务局的四个 CKAN 数据集全是海关数据(已于 2026-08-27 核实)。
操作:
- 运行一次搜索,以便答案基于证据,而不是主观臆测。
- 如果数量为 0 或结果无关,请明确说明,并引导用户前往
nadlan.gov.il,该网站通过自己的非 CKAN API 发布交易数据。 - 不要使用其他组织中看似合理的数据集来代替,也不要编造数据。
结果:用户一步即可前往真正拥有相关数据的来源,而不是经过三步搜索。这一示例旨在避免一种后果最严重的失误:搜索无果后编造数据集。这是 Agent 使用此技能时最不应该做的事。
示例 3:市政数据对比
用户说:“比较以色列各城市的教育支出。”
操作:
package_search?q=%D7%AA%D7%A7%D7%A6%D7%99%D7%91%20%D7%97%D7%99%D7%A0%D7%95%D7%9A(希伯来语“预算 + 教育”,已进行百分号编码)。- 选择一个市政预算数据集,并使用
package_show获取当前有效的资源 ID。 - 使用
datastore_search筛选教育类别的行;对于大型资源,使用offset翻页(或下载资源 CSV)。 - 要按人均标准化,需要人口数据,但 CKAN 上没有人口数据(
fq=organization:lamas不包含人口表)。请从cbs.gov.il获取,并注明数据来源;或者提供绝对数值,并说明未进行人均标准化。
结果:按主要以色列市政机构的学生人均教育支出进行排名,并注明数据来源和年份。
捆绑资源
脚本
scripts/query_datagov.py-- 从命令行搜索数据集、检查资源,并查询 data.gov.il CKAN API。子命令:search、dataset、query、sql、orgs。query支持--filters/--fields/--sort/-q/--offset/--records-format;sql调用datastore_search_sql以进行键集分页和聚合;两者都支持--json,可输出适合机器读取并可用于链式调用的结果。运行:python scripts/query_datagov.py --help
参考资料
references/ckan-api-reference.md——data.gov.il CKAN API 的完整端点目录,包含搜索参数、数据存储查询语法和常见组织 ID。构造 API 调用或排查查询语法问题时请查阅。
推荐的 MCP 服务
将此技能与 MCP 服务配合使用,让 Agent 能够直接将 data.gov.il(或衍生数据集)作为工具调用,而无需编写 HTTP 调用脚本。
| MCP | URL | 提供的功能 |
|---|---|---|
datagov-israel | https://agentskills.co.il/he/mcp/datagov-israel | 直接通过 MCP 工具访问 data.gov.il CKAN API(search、package_show、datastore_search)。 |
data-gov-il | https://agentskills.co.il/he/mcp/data-gov-il | 另一个封装相同 data.gov.il CKAN API 的 MCP。 |
israel-vehicles | https://agentskills.co.il/he/mcp/israel-vehicles | 专用于车辆注册数据集的 MCP(车牌查询、品牌/型号/年份)。 |
israel-amutot | https://agentskills.co.il/he/mcp/israel-amutot | 专用于司法部 amutot(非政府组织)注册信息的 MCP。 |
israel-elections | https://agentskills.co.il/he/mcp/israel-elections | 专用于以色列选举结果数据的 MCP。 |
此技能引导用户进行查询时,如果已安装专用 MCP,请优先使用;否则使用原始 CKAN API。
注意事项
- 以色列政府数据 API(data.gov.il)经常在不通知的情况下更改 URL 和端点结构。Agent 可能会硬编码上个月还能用、现在却返回 404 的端点。引用资源 ID 前,请通过
package_show重新核实。 - data.gov.il API 默认返回带有希伯来语列标题的数据。Agent 可能无法解析 JSON 或 CSV 输出中包含非 ASCII 标题名称的响应。
- 希伯来语筛选值和
q参数必须进行 UTF-8 百分号编码。URL 中的原始希伯来语会导致多个 HTTP 客户端出错(某些curl构建版本、较旧的requests版本、某些代理)。示例:将“רכב”作为q=%D7%A8%D7%9B%D7%91搜索;将“חיפה”作为filters=%7B%22city%22%3A%22%D7%97%D7%99%D7%A4%D7%94%22%7D筛选。 - 速率限制没有文档说明,而且很容易夸大其严重程度。已于 2026-08-27 验证:6.5 秒内连续快速调用 25 次
datastore_search均返回 200;一次会话中约 60 次调用也完全没有触发限流。 将适当延迟视为礼貌之举,而非有文档说明的要求;没有证据时,不要告诉用户问题是速率限制导致的;人们实际遇到的拦截来自下文的 SQL 模式 WAF。 - data.gov.il 的 WAF 会拦截与注入特征相符的 SQL(已于 2026-08-27 确认:
count(、1=1、UNION),并返回约 1.4 kB 的 HTML 404 页面,而非 JSON 或 403。改写查询即可立即解决;等待无济于事,因为这不是限流。2026 年 6 月曾观察到正文为Security Violation的 403,但在 2026-08-27 无法复现;如果遇到此类响应,请将其视为会话级拦截(清除 Cookie、使用新的User-Agent、指数退避),而非查询问题。 - 许多政府数据集的日期字段采用 DD/MM/YYYY 格式(以色列惯例),而非 ISO 8601。Agent 可能会把“01/02/2026”解析为 2 月 1 日,而非 1 月 2 日。
- 在大型数据集中,使用较大的 offset 翻页会越来越慢(已于 2026-08-27 验证:
offset=500000仍返回 200,因此没有硬性上限,但较大的 offset 开销很高)。filters不支持键集分页({"_id":">N"}会失败并返回success:false),但datastore_search_sql可以通过WHERE _id > N ORDER BY _id实现,这是完整提取数据的正确工具。
参考链接
| 来源 | URL | 检查内容 |
|---|---|---|
| data.gov.il 门户网站 | https://data.gov.il | 浏览以色列开放数据目录、组织和数据集 |
| CKAN API 参考 | https://docs.ckan.org/en/latest/api/ | package_search、package_show、datastore_search 的签名 |
| data.gov.il 数据集列表 | https://data.gov.il/datasets | 按组织和标签查找可用数据集。注意这里使用复数:/dataset 会显示客户端 404 页面 |
| 中央统计局 | https://www.cbs.gov.il | data.gov.il 上许多统计数据的上游来源 |
| 以色列银行数据 | https://www.boi.org.il | data.gov.il 上没有的金融和货币数据集 |
故障排查
package_search 返回 count: 0
原因:搜索词过于具体、语言不正确,或者该数据确实不在此门户上。
解决方案:先尝试更宽泛的希伯来语关键词(目录内容主要为希伯来语),然后使用 fq=organization:<id>。如果仍然为零,在得出任何结论之前,先检查第 2 步中的“data.gov.il 上没有的内容”表格:对于房地产、GTFS 或大多数 CBS 系列,计数为零就是正确且最终的答案;正确做法是引导用户前往其他来源,而不是替换成不同的数据集。
JSON 返回 HTTP 409 和希伯来语 Validation Error
原因:请求已到达 CKAN,但 CKAN 拒绝了这些参数。例如,缺少 resource_id 会返回 {"error":{"resource_id":["ערך חסר"],"__type":"Validation Error"},"success":false},HTTP 状态码为 409。错误消息为希伯来语。
解决方案:读取 error,而不是状态码。这是调用方的错误,不是服务中断。
资源没有可查询的 datastore
原因:该资源的 datastore_active 为 false。这与 format 无关:XLSX 资源可以启用 datastore(mosdot 就是如此),而 CSV 资源也可能未启用。
解决方案:调用 datastore_search 之前,先从 package_show 或 resource_show 读取 resources[].datastore_active。如果为 false,则下载 resources[].url 并在本地解析。
错误:datastore_search_sql 返回 HTML 页面而不是 JSON
原因(已于 2026-08-27 验证):请求根本没有到达 SQL 层。这个 1,376 字节的 HTML 404 是网站的通用错误页面,可能由三种情况触发:WAF 匹配到 SQL 中注入特征的子字符串(count(、1=1 和 UNION 都会触发),或者操作名称不存在,或者 resource_id 不存在。只检查 success 的客户端在这三种情况下都会遇到解析失败。
解决方案:先区分具体原因。重新运行 SELECT * FROM "<resource_id>" LIMIT 1。如果成功,说明 SQL 触发了 WAF:将 count(*) 替换为 sum(1),从 datastore_search 的 total 获取普通行数,并避免使用 UNION 和恒真条件。如果仍然返回 HTML,则 resource_id 已失效(使用 package_show 重新解析),或者操作名称有误。SQL 端点本身并未禁用:普通的 SELECT、WHERE、ORDER BY、GROUP BY 和 sum() 均会返回包含数据的 200 响应。
已确认并非原因:速率限制(6.5 秒内快速调用 25 次,均返回 200),以及真正的 SQL 错误;这类错误会返回 JSON 和 HTTP 409,并包含 psycopg2 消息,而不是 HTML。
错误:捆绑脚本出现 Connection error: [SSL: CERTIFICATE_VERIFY_FAILED]
原因:macOS 上的 python.org 构建版本未附带已填充的 CA 存储,因此 urllib 无法验证 data.gov.il 的证书。这是本地信任存储问题,不是 data.gov.il 故障;同一台机器上的 curl 可以成功。
解决方案:如果已安装 certifi(pip install certifi),脚本现在会优先使用它的证书包。否则运行一次 /Applications/Python\ 3.x/Install\ Certificates.command,或者设置 SSL_CERT_FILE=$(python3 -c 'import certifi; print(certifi.where())')。
success:true 且 total: 0,但数据显然存在
原因(已于 2026-08-27 验证):几乎总是文本列中的值带有空格。在 CBS 地区资源上使用 filters={"סמל_ישוב":"4000"} 会返回零行,因为存储的值是 "4000 "。看起来像数字的代码以 text 类型存储,因此 "4000" 和 4000 也不相同。
解决方法:先使用 limit=1 检查原始值,然后匹配带有空格的准确字符串,或使用 datastore_search_sql 和 WHERE TRIM("col") = 'value'。请参阅步骤 3b。
希伯来语字段名
这不是错误。大多数数据集的列名都是希伯来语,不同资源中的列名有时带空格(שם ישוב),有时带下划线(שם_ישוב)。先使用 limit=1 查询以读取准确的字段名,并在 URL 中对其进行百分号编码。