You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将地址哈希合并到Ruby Nokogiri提取的当事人信息哈希中?

使用Nokogiri从HTML表格关联当事人信息与对应地址

我正在用Ruby的Nokogiri库从HTML表格提取当事人名称和类型,已经能把它们合并成哈希数组,也能获取到地址信息,但因为表格结构特殊,不知道怎么把对应地址合并到对应的当事人哈希中。

现有代码

require 'nokogiri'

html = '    <table class="detailRecordTable"><tbody><tr>
                                                        <td width="3%" class="detailSeperator" style="width:3%;"></td>
                                                        <td width="30%" class="detailSeperator" style="width:30%;text-align:left">
                                                                SMALL   , DANIEL, Appellant&nbsp;&nbsp;&nbsp            </td>       <td width="20%" class="detailSeperator" style="width:20%;font-weight: normal">  represented by&nbsp;&nbsp;&nbsp;
                                                        </td>
                                                        <td width="47%" class="detailSeperator" style="width:47%;text-align:left">
                                                                KELLY   , MARK EDWARD
                                                                , Attorney for Appellant
                                                        </td>
                                                    </tr>
                                                    <tr>
                                                        <td width="3%" class="detailData" style="width:3%;text-align:right">
                                                        </td>
                                                        <td width="30%" class="detailData">

                                                        </td>   <td width="20%" class="detailData">

                                                        </td><td width="47%" class="detailData">
                                                                    134 N WATER STREET<br>
                                                                    LIBERTY,
                                                                    MO
                                                                    64068<br>   <br>
                                                            <p></p>
                                                        </td>
                                                    </tr>
                                                    <tr>
                                                        <td width="3%" class="detailData">&nbsp;</td>
                                                        <td width="30%" class="detailData">&nbsp;</td>
                                                        <td width="20%" class="detailData">&nbsp;</td>
                                                        <td width="47%" class="detailData"></td>
                                                    </tr>

                                                    <tr>
                                                        <td class="detailSeperator" style="width:3%;text-align:right"></td>
                                                        <td class="detailSeperator" style="width:30%;text-align:left"></td>
                                                        <td class="detailSeperator" style="width:20%;font-weight: normal">co-counsel</td>
                                                        <td class="detailSeperator" style="width:47%;text-align:left">
                                                            PITTMAN     , KRISTI LANAE  , Co-Counsel for Appellant</td>
                                                    </tr>
                                                    <tr>
                                                        <td width="3%" class="detailData">&nbsp;</td>
                                                        <td width="30%" class="detailData">&nbsp;</td>
                                                        <td width="20%" class="detailData">&nbsp;</td>
                                                        <td width="47%" class="detailData">
                                                                134 NORTH WATER STREET<br>
                                                                LIBERTY,
                                                                MO
                                                                64068<br>               <br>

                                                        </td>
                                                    </tr>
                                                    <tr>
                                                        <td width="3%" class="detailSeperator" style="width:3%;">&nbsp;
                                                        </td>
                                                        <td width="30%" class="detailSeperator" style="width:30%;text-align:left">
                                                                RED SIMPSON, INC.
                                                                , Respondent&nbsp;&nbsp;&nbsp;
                                                        </td>

                                                        <td width="20%" class="detailSeperator" style="width:20%;font-weight: normal">  represented by&nbsp;&nbsp;&nbsp;
                                                        </td>
        <td width="47%" class="detailSeperator" style="width:47%;text-align:left">
                                                                GREENWALD   , DOUGLAS   MARK
                                                                , Attorney for Respondent
                                                        </td>
                                                    </tr>
                                                    <tr>
                                                        <td width="3%" class="detailData" style="width:3%;text-align:right">
                                                        </td>
                                                        <td width="30%" class="detailData">
                                                        </td>
                                                        <td width="20%" class="detailData">

                                                        </td>

                                                        <td width="47%" class="detailData">

                                                                    10 EAST CAMBRIDGE CIRCLE DRIVE<br>
                                                                    KANSAS CITY,
                                                                    KS
                                                                    66103<br><br>
                                                            <p></p>
                                                        </td>
                                                    </tr>
                                                    <tr>
                                                        <td width="3%" class="detailData">&nbsp;</td>
                                                        <td width="30%" class="detailData">&nbsp;</td>
                                                        <td width="20%" class="detailData">&nbsp;</td>
                                                        <td width="47%" class="detailData"></td>
                                                    </tr>

                                                    <tr>
                                                        <td class="detailSeperator" style="width:3%;text-align:right"></td>
                                                        <td class="detailSeperator" style="width:30%;text-align:left"></td>
                                                        <td class="detailSeperator" style="width:20%;font-weight: normal">co-counsel</td>
                                                        <td class="detailSeperator" style="width:47%;text-align:left">
                                                            BENJAMIN, SAMANTHA  NICOLE
                                                            , Co-Counsel for Respondent</td>
                                                    </tr>
                                                    <tr>
                                                        <td width="3%" class="detailData">&nbsp;</td>
                                                        <td width="30%" class="detailData">&nbsp;</td>
                                                        <td width="20%" class="detailData">&nbsp;</td>
                                                        <td width="47%" class="detailData">

                                                                MCANANY VAN CLEVE AND PHILLIPS<br>

                                                                10 E CAMBRIDGE CIRCLE DR<br>

                                                                STE 300<br>

                                                                KANSAS CITY,
                                                                KS
                                                                66103<br>
                                                            <b>Business: </b>
                                                            (913)
                                                            573-3319 <br>   <br>

                                                        </td>
                                                    </tr>

                                </tbody></table>'

doc = Nokogiri::HTML(html)
rows = doc.xpath("//table[@class='detailRecordTable']//tr")
# address2 = doc.css('td:nth-of-type(4)').text.strip

# puts address2

@party_names = []
@party_types = []
@party_des = []

rows.each do |row|
  nodes = row.css('.detailSeperator:nth-of-type(2), .detailSeperator:nth-of-type(4)')
  nodes.each do |node|
    name = node.text.strip.gsub("\n", '').gsub("\t", '')
    parts = name.split(',')
    name = if parts.length == 3
             "#{parts[0]}, #{parts[1]}"
           else
             parts[0]
           end
    party_type = parts[-1].strip if parts && parts.length >= 2
    addr = ("#{parts[0]}, #{parts[1]}" if parts.length == 2)
    @party_names << name
    @party_types << party_type
    @party_des   <<  addr
  end

  address = row.css('td:nth-of-type(2),td:nth-of-type(4)')
  address.each do |node|
    addr = node.text.strip.gsub("\n", '').gsub("\t", '')
    parts = addr.split(',')
    addr = ("#{parts[0]}, #{parts[1]}" if parts.length == 2)
    @party_des << addr
  end
end
@party_names.compact!
@party_names.reject(&:empty?)
@party_types.compact!
@party_des.compact!        
@party_names_and_types = @party_names.zip(@party_types).map { |name, type| { part_name: name, party_type: type } }

当前输出

{:part_name=>"SMALL,  DANIEL", :party_type=>"Appellant  &nbsp"}
{:part_name=>"KELLY,  MARK EDWARD", :party_type=>"Attorney for Appellant"}
{:part_name=>"PITTMAN,  KRISTI LANAE", :party_type=>"Co-Counsel for Appellant"}
{:part_name=>"RED SIMPSON,  INC.", :party_type=>"Respondent   "}
{:part_name=>"GREENWALD,  DOUGLASMARK", :party_type=>"Attorney for Respondent"}
{:part_name=>"BENJAMIN,  SAMANTHA NICOLE", :party_type=>"Co-Counsel for Respondent"}

期望输出

{:part_name=>"SMALL,  DANIEL", :party_type=>"Appellant  &nbsp"}
{:part_name=>"KELLY,  MARK EDWARD", :party_type=>"Attorney for Appellant", :party_address => "134 N WATER STREETLIBERTY,MO 64068"}
{:part_name=>"PITTMAN,  KRISTI LANAE", :party_type=>"Co-Counsel for Appellant",:party_address => "134 N WATER STREETLIBERTY,MO 64068"}
{:part_name=>"RED SIMPSON,  INC.", :party_type=>"Respondent  "}
{:part_name=>"GREENWALD,  DOUGLASMARK", :party_type=>"Attorney for Respondent", :party_address => " 10 EAST CAMBRIDGE CIRCLE DRIVE KANSAS CITY,KS 66103"}
{:part_name=>"BENJAMIN,  SAMANTHA NICOLE", :party_type=>"Co-Counsel for Respondent", :party_address => "    MCANANY VAN CLEVE AND PHILLIPS  10 E CAMBRIDGE CIRCLE DR STE 300 KANSAS CITY,KS 66103", :party_des => "Business:(913) 573-3319"}

解决方案

根据表格结构规律,律师/联合律师的地址行紧跟在其信息行之后,我们可以通过跟踪最后一个创建的当事人哈希,将后续地址关联到该哈希中:

require 'nokogiri'

html = '...' # 保持原HTML内容不变

doc = Nokogiri::HTML(html)
rows = doc.xpath("//table[@class='detailRecordTable']//tr")

parties = []
last_party = nil

rows.each do |row|
  # 处理包含当事人/律师信息的行(detailSeperator类的单元格)
  info_nodes = row.css('.detailSeperator:nth-of-type(2), .detailSeperator:nth-of-type(4)')
  info_nodes.each do |node|
    text = node.text.strip.gsub(/[\n\t]/, '').gsub(/\s+/, ' ')
    next if text.empty?

    parts = text.split(',').map(&:strip)
    # 提取名称和类型
    name = parts.size >= 2 ? "#{parts[0]}, #{parts[1]}" : parts[0]
    party_type = parts[-1] if parts.size >= 2

    # 创建哈希并加入数组
    party_hash = { part_name: name, party_type: party_type }
    parties << party_hash
    last_party = party_hash
  end

  # 处理包含地址的行(detailData类的第4个单元格)
  addr_node = row.css('.detailData:nth-of-type(4)')
  next if addr_node.empty?

  addr_text = addr_node.text.strip.gsub(/[\n\t]/, '').gsub(/\s+/, ' ')
  next if addr_text.empty?

  # 拆分地址和业务联系信息
  if addr_text.include?('Business:')
    address_part, contact_part = addr_text.split('Business:', 2)
    last_party[:party_address] = address_part.strip
    last_party[:party_des] = "Business:#{contact_part.strip}"
  else
    last_party[:party_address] = addr_text.strip
  end
end

# 输出结果
parties.each { |p| puts p.inspect }

代码说明

  1. 跟踪最后一个当事人:每次创建新的当事人哈希时,用last_party变量记录,后续遇到地址行时直接将地址添加到这个哈希中。
  2. 清理文本:用正则替换多余的换行、制表符和连续空格,让地址和名称格式更整洁。
  3. 拆分联系信息:如果地址文本包含"Business:",将其拆分为地址和业务电话两部分,分别存入对应的键中。
  4. 跳过空行:判断单元格文本是否为空,避免处理无效的空行。

运行上述代码后,输出结果将与期望输出一致。

内容的提问来源于stack exchange,提问作者snoozy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 18:01:24