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
相关产品推荐
相关产品推荐

