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

Python爬取HTML的data属性问题:BeautifulSoup.find()用法求助

问题解决与说明

1. BeautifulSoup支持自定义属性(包括data-*)

BeautifulSoup完全支持匹配class、id之外的任何HTML属性,包括data-label这类自定义属性。只是因为Python参数名不允许包含连字符,不能直接写data-label="Precinct"作为关键字参数,有两种正确写法:

  • 方法一:将属性名中的连字符替换为下划线,BeautifulSoup会自动转换匹配,比如data_label="Precinct"
  • 方法二:使用attrs参数传入字典,明确指定属性名和值,比如attrs={"data-label": "Precinct"}

2. 代码错误修正

语法错误原因

你写的data-label_="Precinct"是错误的:一是参数名包含连字符,Python解析时会报错;二是多了一个下划线,正确写法应为data_label="Precinct"(用下划线替换连字符),或者使用attrs参数。

逻辑错误修正

你的代码先获取所有<td>,再在每个<td>里嵌套查找<td>,这不符合目标页面结构(辖区编号和地址是同一行<tr>下的不同<td>)。另外还有变量名笔误:address.append(address)应该改为addresses.append(address)。

修正后的完整代码

import pandas as pd
import requests
from bs4 import BeautifulSoup

url = "http://wgetsnaps.github.io/nyc.gov--nypd-videos/html/nypd/html/home/precincts.shtml.html"
response = requests.get(url)
soup = BeautifulSoup(response.content, "html.parser")

# 获取页面所有行
rows = soup.find_all("tr")
numbers = []
addresses = []

for row in rows:
    # 方法一:用下划线替换连字符匹配data-label
    precinct_td = row.find("td", data_label="Precinct")
    address_td = row.find("td", data_label="Address")
    
    # 方法二:用attrs参数(两种方式选其一即可)
    # precinct_td = row.find("td", attrs={"data-label": "Precinct"})
    # address_td = row.find("td", attrs={"data-label": "Address"})
    
    # 跳过无目标数据的行(比如表头)
    if precinct_td and address_td:
        numbers.append(precinct_td.text.strip())
        addresses.append(address_td.text.strip())

# 整理数据并导出CSV
df = pd.DataFrame({"Precinct": numbers, "Address": addresses})
df.to_csv("nypd_precincts.csv", index=False)

补充说明

  • 遍历<tr>行比遍历所有<td>更高效,能确保辖区编号和地址是同一行的对应数据。
  • 添加if precinct_td and address_td判断是为了跳过表头或无目标数据的行,避免出现None.text的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 09:43:34