使用BeautifulSoup爬取时无唯一class/id如何通过兄弟节点定位元素
完全可以基于兄弟元素的文本内容定位目标元素,针对你给出的HTML结构,BeautifulSoup可以通过以下方式实现需求:
核心思路
你提供的页面字段都是固定的成对结构:每一行.row.clearfix里左侧col-md-3存字段名(ISBN、出版社等),右侧col-md-9存对应值。只要先定位到包含指定字段名的元素,再顺着节点关系找到右侧对应值的节点即可。
具体实现代码
首先是基础的页面请求和解析逻辑:
from bs4 import BeautifulSoup import requests # 请求目标页面 url = "https://www.nb.co.za/en/view-book/?id=9780798182539" response = requests.get(url) soup = BeautifulSoup(response.text, "html.parser")
方法1:精准匹配字段名提取单条数据
如果要单独提取ISBN,直接定位包含ISBN:的p标签,再向上找父节点、找相邻的下一个div即可:
# 定位文本为ISBN:的p标签 isbn_label = soup.find("p", string="ISBN:") # 父div的下一个相邻div就是存ISBN值的节点,strip()去除前后空白字符 isbn = isbn_label.find_parent("div").find_next_sibling("div").text.strip() print(isbn) # 输出:9780798182539
这个方法可以直接复用提取其他字段,比如提取出版社:
publisher_label = soup.find("p", string="Publisher:") publisher = publisher_label.find_parent("div").find_next_sibling("div").text.strip() print(publisher) # 输出:Human & Rousseau
方法2:模糊匹配避免匹配失败
如果担心字段文本前后有空格、换行符导致精准匹配失败,可以用lambda做模糊匹配:
# 只要p标签的文本去除空白后包含ISBN:就算匹配成功 isbn_label = soup.find("p", string=lambda s: s and "ISBN:" in s.strip()) isbn = isbn_label.find_parent("div").find_next_sibling("div").text.strip()
方法3:批量提取所有字段
如果需要把页面上所有的书籍信息都提取出来,可以直接遍历所有行节点,存为字典更方便调用:
book_info = {} # 选中所有行容器 for row in soup.select(".author-details .row.clearfix"): # 分别取左右两列的内容 label = row.select_one(".col-md-3 p").text.strip() value = row.select_one(".col-md-9").text.strip() book_info[label] = value # 直接通过字段名取对应值 print(book_info["ISBN:"]) print(book_info["Date Released:"]) print(book_info["Price (incl. VAT):"])
内容的提问来源于stack exchange,提问作者Schalk Joubert
相关产品推荐
相关产品推荐

