使用requests与bs4爬取网页时目标div无法获取的问题
问题原因
- 页面菜单是JavaScript动态渲染的:浏览器打开页面时会执行JS代码,动态加载渲染出菜单内容;但
requests只能拿到服务器返回的静态HTML源码,这部分源码里并没有menu-area标签,所以soup.find返回None,调用.text就会触发属性错误。 - 本地保存的页面是浏览器渲染完成后的完整DOM结构,已经包含了动态加载的菜单,所以脚本能正常解析。
解决方案
方案1:用Selenium模拟浏览器渲染
Selenium可以模拟真实浏览器行为,等JS加载完成后再获取页面源码,就能拿到包含菜单的完整DOM。
示例代码:
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 venue_url = 'https://untappd.com/v/glory-days-grill-of-ellicott-city/3329822' # 初始化Chrome浏览器驱动(需提前下载和浏览器版本匹配的chromedriver) driver = webdriver.Chrome() driver.get(venue_url) # 等待菜单区域加载完成,最多等10秒 try: WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, 'menu-area')) ) # 获取渲染后的页面源码 page_source = driver.page_source soup = BeautifulSoup(page_source, 'html.parser') menu = soup.find('div', {'class': 'menu-area'}) print(menu.text.strip()) finally: driver.quit()
注意:需要先执行pip install selenium安装库,并把浏览器驱动放到系统PATH中。
方案2:抓包获取菜单API接口
打开浏览器开发者工具的「Network」标签,刷新页面,查找加载菜单数据的AJAX请求。找到对应接口后,直接用requests请求接口拿数据,比模拟浏览器更高效。
示例代码(需替换为实际抓到的API地址):
import requests api_url = '替换为实际抓到的菜单API接口地址' headers = { 'User-agent': 'Mozilla/5.0', 'X-Requested-With': 'XMLHttpRequest' } response = requests.get(api_url, headers=headers) menu_data = response.json() # 按需解析JSON数据提取菜单内容 print(menu_data)
内容的提问来源于stack exchange,提问作者Tendekai Muchenje
相关产品推荐
相关产品推荐

