网页邮寄地址中城市、州、邮编提取异常问题求助
邮寄地址中城市、州、邮编提取问题
我在提取网页邮寄地址<br>标签后的城市、州和邮编时遇到问题,其他信息都能正常提取。
初始代码
element = soup.find(lambda tag: tag.name=='th' and 'Mailing Address:' in tag.text) if not element: print(f"Mailing Address not found for {parcel_number}.") return None mailing_address = element.find_next_sibling().decode_contents() address_lines = mailing_address.split('<br>') address = address_lines[0].strip() # first line is the address city_state_zip_br = element.find_next_sibling('br') # find the br tag containing the city, state, and zip if city_state_zip_br: city_state_zip = city_state_zip_br.next_sibling.strip() parts = city_state_zip.split(', ') if len(parts) < 3: city = "" state = "" zip_code = "" else: city = parts[0].strip() state, zip_code = parts[1].strip().split(' ') zip_code = zip_code.strip() else: city = "" state = "" zip_code = ""
目标HTML结构
<tr><th>Parcel Number:</th><td>1207250000015003</td></tr> <tr><th>Type:</th><td>Real</td></tr> <tr><th>Property Class:</th><td>2 </td></tr> <tr class="active form-table-title"><th colspan="2">Location</th></tr> <tr><th>Address:</th><td>11875 HIGHWAY 43 N AXIS, AL 36505 </td></tr> <tr class="active form-table-title"> <th colspan="2"> Owner </th> </tr> <tr><th>Name:</th><td>TOWER LOT 1 LLC </td></tr> <tr><th>Mailing Address:</th><td>P O BOX 336 <br> <br>BIRMINGHAM , AL 35201-0336
当前问题
目前能正确提取州和邮编,但城市字段会混入地址内容,输出示例:
city: 10163 KALI OKA RD EIGHT MILE state: AL zip_code: 36613-8790
修改后的代码(仍未解决)
mailing_address_lines = [line.strip() for line in mailing_address.split('\n') if line.strip()] address = mailing_address_lines[0] # first line is the address print(f"address: {address}") city_state_zip_pattern = r'^(.+?),\s+([A-Z]{2})\s+(\d{5}(?:-\d{4})?)$' city_state_zip_match = re.match(city_state_zip_pattern, mailing_address_lines[-1]) if city_state_zip_match: city = city_state_zip_match.group(1) state = city_state_zip_match.group(2) zip_code = city_state_zip_match.group(3) else: city_state_zip = mailing_address_lines[-1] address_parts = address.split(city_state_zip) if len(address_parts) > 1: city = address_parts[1].strip() else: city = "" city_state_zip_parts = city_state_zip.split() state = city_state_zip_parts[-2] zip_code = city_state_zip_parts[-1] address = address_parts[0].strip() print(f"address: {address}") print(f"city: {city}") print(f"state: {state}") print(f"zip_code: {zip_code}")
解决方案建议
问题核心是手动处理HTML字符串容易出错,直接用BeautifulSoup解析<td>下的文本节点更可靠:
element = soup.find(lambda tag: tag.name == 'th' and 'Mailing Address:' in tag.text) if not element: print(f"Mailing Address not found for {parcel_number}.") return None # 获取邮寄地址对应的td元素 td_element = element.find_next_sibling() # 提取td下所有非空的文本节点,自动处理br分隔 text_nodes = [node.strip() for node in td_element.stripped_strings] address = text_nodes[0] if len(text_nodes) > 0 else "" city_state_zip = text_nodes[-1] if len(text_nodes) > 1 else "" city = "" state = "" zip_code = "" if city_state_zip: # 按逗号分割一次,提取城市部分 city_part, rest = city_state_zip.split(',', 1) city = city_part.strip() # 分割州和邮编,过滤空内容后取最后两个有效项 rest_parts = [part.strip() for part in rest.split() if part.strip()] if len(rest_parts) >= 2: state = rest_parts[-2] zip_code = rest_parts[-1] print(f"address: {address}") print(f"city: {city}") print(f"state: {state}") print(f"zip_code: {zip_code}")
方案说明
td_element.stripped_strings会自动处理<br>标签,将分隔的内容拆分为独立文本节点,无需手动拆分HTML字符串。- 文本节点列表中,第一个元素是邮寄地址首行,最后一个元素是城市、州、邮编所在行。
- 按逗号单次分割避免城市名称含逗号的异常情况,州和邮编取分割后的最后两个非空项,兼容HTML中多余空格的问题。
内容的提问来源于stack exchange,提问作者Mason
相关产品推荐
相关产品推荐

