如何抓取相同标签类的网页元素?解决BeautifulSoup循环异常
解决BeautifulSoup网页抓取的两个核心问题
问题1:循环仅执行一次,仅输出单条数据
你的代码里info = [...]和print(info)语句不在for循环的缩进块内,导致循环遍历所有容器后,只会创建最后一个容器的信息并输出一次。把这两行缩进,放到循环内部即可解决。
另外导入语句存在语法错误(比如from bs4和import BeautifulSoup分成两行),先修正这些基础语法问题,否则代码无法正常运行。
问题2:相同标签类无法区分不同内容
对于重复使用相同标签和类的元素(如text-nowrap),不要用find()(只会返回第一个匹配元素),改用find_all()获取所有匹配元素的列表,再根据元素在网页中的位置索引提取对应内容。也可以通过元素的父节点、兄弟节点关系精准定位,降低对索引的依赖。
修正后的代码
# 安装依赖建议在终端单独执行,不要写在代码里 # pip install beautifulsoup4 lxml requests from bs4 import BeautifulSoup import requests from csv import writer url = "https://www.boliga.dk/salg/resultater?searchTab=1&sort=date-d&saleType=1&propertyType=1,3&salesDateMin=2015" page = requests.get(url) print(page.status_code) # 打印状态码确认请求成功 soup = BeautifulSoup(page.content, "html.parser") lists = soup.find_all("div", class_="container mb-5") for item in lists: # 避免用list做变量名,覆盖内置类型 # 提取房产类型 resitype_elem = item.find('span', class_="text") resitype = resitype_elem.text.strip() if resitype_elem else "N/A" # 提取地址 address_elem = item.find('a', class_="text-primary font-weight-bolder text-left") address = address_elem.text.strip() if address_elem else "N/A" # 提取所有text-nowrap元素,按位置取对应内容 text_nowrap_elems = item.find_all('span', class_="text-nowrap") price = text_nowrap_elems[0].text.replace('\xa0kr.', "").strip() if len(text_nowrap_elems) > 0 else "N/A" salesdate = text_nowrap_elems[1].text.strip() if len(text_nowrap_elems) > 1 else "N/A" sqm = text_nowrap_elems[2].text.strip() if len(text_nowrap_elems) > 2 else "N/A" # 提取text-nowrap mt-1元素 mt1_elems = item.find_all('span', class_="text-nowrap mt-1") sqmprice = mt1_elems[0].text.strip() if len(mt1_elems) > 0 else "N/A" salestype = mt1_elems[1].text.strip() if len(mt1_elems) > 1 else "N/A" # 提取房间数和建造年份(注意标签是td不是span) table_cells = item.find_all('td', class_="table-col d-print-table-cell text-center") rooms = table_cells[0].text.strip() if len(table_cells) > 0 else "N/A" buildingyear = table_cells[1].text.strip() if len(table_cells) > 1 else "N/A" # 提取降价百分比 procent_elem = item.find('a', class_="price-reduced ng-star-inserted") procent = procent_elem.text.strip() if procent_elem else "N/A" info = [resitype, address, price, salesdate, rooms, sqm, sqmprice, salestype, buildingyear, procent] print(info)
额外说明
- 避免使用
list作为变量名,防止覆盖Python内置的list类型 - 所有元素提取都添加了
if判断,避免找不到元素时抛出AttributeError - 用
strip()去除文本多余的空格和换行符
内容的提问来源于stack exchange,提问作者Laurits
相关产品推荐
相关产品推荐

