在Julia循环中处理JSON字段双值或空值的问题
解决Julia网页抓取中JSON字段类型不一致的问题
问题根源
你的代码存在两个核心问题:
- 误用了R的
NA,Julia中处理缺失值的标准是missing; - 当
classeCooperativa为nothing时,直接嵌套调用get会尝试从非字典类型取值,导致报错。
修正方案
以下是修改后的完整代码,关键部分做了注释说明:
using HTTP, JSON, DataFrames # 提前初始化空DataFrame,明确列类型更规范 info_gerais_coop = DataFrame( cnpj_coop = Int[], nome_coop = String[], naturezaJuridica = Union{String, Missing}[], classe = Union{String, Missing}[], situacao = Union{String, Missing}[], regimeEspecial = Union{Any, Missing}[], logradouro = Union{String, Missing}[], complemento = Union{String, Missing}[], bairro = Union{String, Missing}[], municipio = Union{String, Missing}[], uf = Union{String, Missing}[], cep = Union{String, Missing}[], endereco_eletronico = Union{String, Missing}[], email = Union{String, Missing}[], segmento_prudencial = Union{Any, Missing}[] ) cnpj_list = [3795072, 1439107] for cnpj in cnpj_list url = "https://www3.bcb.gov.br/informes/rest/pessoasJuridicas?cnpj=$cnpj" response = HTTP.get(url) dcoop = JSON.parse(String(response.body)) # 先提取地址对象,避免重复调用get endereco = get(dcoop, "endereco", missing) # 安全提取classe字段:先判断classeCooperativa是否有效,再取值 classe = let cc = get(dcoop, "classeCooperativa", missing) ismissing(cc) || cc === nothing ? missing : String(get(cc, "nome", missing)) end # 构建单行数据 row = ( cnpj_coop = cnpj, nome_coop = dcoop["nome"], naturezaJuridica = String(get(dcoop, "naturezaJuridica", missing)), classe = classe, situacao = String(get(dcoop, "situacao", missing)), regimeEspecial = get(dcoop, "regimeEspecial", missing), logradouro = ismissing(endereco) ? missing : String(get(endereco, "logradouro", missing)), complemento = ismissing(endereco) ? missing : String(get(endereco, "complemento", missing)), bairro = ismissing(endereco) ? missing : String(get(endereco, "bairro", missing)), municipio = ismissing(endereco) ? missing : String(get(get(endereco, "municipio", missing), "nome", missing)), uf = ismissing(endereco) ? missing : String(get(get(endereco, "municipio", missing), "siglaEstado", missing)), cep = ismissing(endereco) ? missing : String(get(endereco, "cep", missing)), endereco_eletronico = ismissing(endereco) ? missing : String(get(endereco, "email", missing)), email = ismissing(endereco) ? missing : String(get(endereco, "email", missing)), segmento_prudencial = get(dcoop, "segmentoPrudencial", missing) ) # 将行添加到DataFrame,比循环vcat高效 push!(info_gerais_coop, row) end
额外优化建议
- 推荐替换
JSON包为JSON3:JSON3解析速度更快,返回带类型的结构体,能更安全地访问字段,减少类型不确定的问题; - 提前定义DataFrame列类型:避免自动推断类型带来的错误,处理大量数据时更稳定;
- 直接遍历
cnpj_list而非索引:代码更简洁易读,符合Julia的惯用写法。
内容的提问来源于stack exchange,提问作者RxT
相关产品推荐
相关产品推荐

