如何使用Python BeautifulSoup等待页面完全加载后进行网页爬取
解决动态页面爬取与等待加载的问题
嘿Adriano,咱们来解决你遇到的这个动态页面爬取问题!你目前的核心困扰是:目标网站的内容是通过JavaScript动态渲染出来的,而urlopen只能拿到服务器返回的初始静态HTML,不会执行页面里的JS代码——所以哪怕你在请求后等5秒,静态请求也没法获取到后续加载的内容,单纯加time.sleep()是没用的。
下面给你两种可行的解决方案,按需选择:
方案一:用Selenium模拟浏览器(推荐,适配动态渲染场景)
Selenium能模拟真实浏览器的行为,等待页面完全渲染(包括JS执行后的内容),再获取完整的页面源码,完美解决你要等页面加载的需求。
步骤准备:
- 先安装Selenium:
pip install selenium - 下载对应浏览器的驱动(比如ChromeDriver,要和你的Chrome版本匹配),可以把驱动放在系统PATH目录,或者在代码里指定路径。
示例代码:
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 url = 'https://www.edocente.com.br/pnld/2020/' user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' # 初始化Chrome浏览器配置 options = webdriver.ChromeOptions() options.add_argument(f'user-agent={user_agent}') # 可选:开启无头模式(后台运行,不弹出浏览器窗口) options.add_argument('--headless=new') driver = webdriver.Chrome(options=options) try: driver.get(url) # 显式等待目标元素加载完成,最多等10秒(比sleep精准,元素出现就继续) WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, 'a.btn.bold.mt-4.px-5')) ) # 如果你不确定元素加载时间,也可以用sleep兜底,但显式等待更高效 # import time # time.sleep(5) # 获取渲染后的完整页面源码 html = driver.page_source soup = BeautifulSoup(html, 'html.parser') # 提取目标a标签的href属性并打印 target_links = soup.find_all('a', class_="btn bold mt-4 px-5") for link in target_links: print(link.get('href')) finally: # 不管成功失败,最后都关闭浏览器 driver.quit()
代码说明:
WebDriverWait是显式等待,它会一直等到目标元素出现在页面里再继续执行,比固定时间的time.sleep()更智能,避免浪费时间。- 无头模式可以让浏览器在后台悄悄运行,不会打扰你做别的事。
方案二:直接请求网站的API接口(更高效,适合有抓包基础的情况)
很多动态加载的网站,其实是通过AJAX请求从后端API获取数据,再渲染到页面上的。你可以用浏览器的开发者工具抓包,找到返回目标链接的API接口,直接请求这个接口拿数据,比模拟浏览器快得多。
操作思路:
- 打开目标网站,按F12调出开发者工具,切换到
Network标签页。 - 刷新页面,在
XHR或Fetch分类里找请求,看看哪个接口返回的数据里包含你要的那些href链接。 - 用
requests或urllib直接请求这个接口,解析返回的JSON数据就行。
这种方法效率最高,但需要你懂一点抓包和API分析的基础。
补充:为什么你的原代码拿不到内容?
你的原代码用urlopen获取的是服务器一开始就返回的静态HTML,而那些带btn bold mt-4 px-5类的a标签,是页面加载完成后通过JS动态生成的——静态HTML里根本没有这些内容,所以不管怎么等,静态请求都拿不到。
内容的提问来源于stack exchange,提问作者Adriano
相关产品推荐
相关产品推荐

