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

网页爬取练习:统计指定class的div数量异常,实际更多却仅返回1

解决爬取时可见div数量与统计结果不符的问题

嘿,作为刚入门web scraping时踩过不少坑的人,这种情况我太懂了!浏览器里明明能看到好几个目标div,但用len()统计只返回1个,大概率是下面这几个原因之一,咱们一个个来排查:

1. 页面内容是JavaScript动态加载的

这是最常见的原因!你用urllib.request.urlopen()拿到的是服务器返回的原始HTML代码,但很多现代网站会用JS在页面加载后动态渲染内容——比如滚动加载、AJAX请求获取数据再插入页面。浏览器里看到的那些div,其实是JS运行后才生成的,原始HTML里可能只有一个空的容器div,所以BeautifulSoup自然只能找到1个。

解决方案:用能执行JS的工具爬取

推荐用Selenium(上手简单)或者Playwright,它们能模拟真实浏览器加载页面,等JS执行完成后再获取完整的HTML。举个Selenium的例子:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup as soup

my_url = 'random_url'
# 初始化Chrome浏览器(需提前安装对应版本的chromedriver)
driver = webdriver.Chrome()
driver.get(my_url)

# 等待目标元素加载完成(最多等10秒,直到至少2个目标div出现)
try:
    WebDriverWait(driver, 10).until(
        EC.presence_of_all_elements_located((By.CLASS_NAME, '你的目标class名'))
    )
finally:
    # 获取渲染后的完整HTML
    page_html = driver.page_source
    driver.quit()

page_soup = soup(page_html, "html.parser")
target_divs = page_soup.find_all('div', class_='你的目标class名')
print(len(target_divs))  # 现在应该能得到正确数量了

2. BeautifulSoup的解析器使用错误

看你代码里写的soup(page_html, "html.pa..."),应该是想写"html.parser"吧?如果解析器拼写错误或者选择不合适,可能会导致HTML结构解析混乱,把多个div识别成一个。

解决方案:确认解析器正确

推荐用"html.parser"(Python内置,无需额外安装)或者"lxml"(解析速度更快,需要先pip install lxml)。修正后的初始化代码:

page_soup = soup(page_html, "html.parser")
# 或者用lxml(需先安装)
# page_soup = soup(page_html, "lxml")

3. 目标class名称匹配错误

有时候浏览器里看到的class可能包含多个值(比如class="product-item featured"),如果你只写了其中一个,或者拼写、大小写不对,都会导致匹配不全。另外,BeautifulSoup里用class_参数时,多个class值要写成完整字符串(比如class_="product-item featured"),或者用CSS选择器更精准。

解决方案:用CSS选择器匹配更可靠

用select()方法配合CSS选择器,能准确匹配多class的元素:

# 匹配同时包含product-item和featured类的div
target_divs = page_soup.select('div.product-item.featured')
print(len(target_divs))

4. 目标div嵌套在iframe中

如果你的目标div是在页面的iframe里,urllib只会拿到主页面的HTML,iframe里的内容需要单独请求。

解决方案:单独爬取iframe的内容

先找到iframe的src属性,然后请求这个URL:

from urllib.request import urlopen as uReq
from urllib.parse import urljoin
from bs4 import BeautifulSoup as soup

my_url = 'random_url'
uClient = uReq(my_url)
page_html = uClient.read()
uClient.close()

page_soup = soup(page_html, "html.parser")
iframe = page_soup.find('iframe')
if iframe and 'src' in iframe.attrs:
    # 处理相对路径,拼接成完整URL
    iframe_url = urljoin(my_url, iframe['src'])
    
    uClient_iframe = uReq(iframe_url)
    iframe_html = uClient_iframe.read()
    uClient_iframe.close()
    
    iframe_soup = soup(iframe_html, "html.parser")
    target_divs = iframe_soup.find_all('div', class_='你的目标class名')
    print(len(target_divs))

先从这几个方向排查,应该能解决问题啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:59:32