Selenium爬取Houzz俄站页面时响应被截断,如何获取完整页面代码及目标JSON数据?
解决Houzz页面爬取时内容截断及获取完整JSON的问题
我来帮你搞定这个Houzz爬取的问题!你遇到的内容截断、JSON数据不完整的情况,主要是因为Houzz的反爬检测机制和滚动加载的逻辑没处理到位。下面是针对性的解决方案:
核心问题分析
- Houzz会检测Selenium的自动化特征,默认配置容易被识别,导致返回不完整内容
- 你之前通过
page_source是否变化判断加载完成的逻辑不可靠,内容加载后源码变化可能极细微,或加载过程中存在短暂重复 - 直接获取整个
innerHTML效率低,还容易引入冗余内容,不如直接定位目标标签精准
可行解决方案
1. 优化Selenium配置,绕过反爬检测
添加参数隐藏自动化特征,让浏览器更接近真实用户环境:
opts = Options() # 设置真实User-Agent opts.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") # 禁用自动化检测特征 opts.add_argument("--disable-blink-features=AutomationControlled") opts.add_experimental_option("excludeSwitches", ["enable-automation"]) opts.add_experimental_option('useAutomationExtension', False) # 设置窗口大小,避免自适应布局导致内容加载异常 opts.add_argument("--window-size=1920,1080") # 无头模式(测试通过后再开启,建议用新版无头模式) # opts.add_argument('-headless=new')
2. 改进滚动加载逻辑,确保内容完全加载
用显式等待代替time.sleep,通过加载元素的状态判断是否停止滚动:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 滚动加载直到没有新内容 last_height = browser.execute_script("return document.body.scrollHeight") while True: # 滚动到底部 browser.execute_script("window.scrollTo(0, document.body.scrollHeight);") # 等待加载动画消失(Houzz滚动后会有hz-loader类的加载元素) try: WebDriverWait(browser, 5).until( EC.invisibility_of_element_located((By.CLASS_NAME, "hz-loader")) ) except: # 超时说明无更多内容 pass # 对比高度判断是否加载完成 new_height = browser.execute_script("return document.body.scrollHeight") if new_height == last_height: break last_height = new_height
3. 直接定位目标script标签,提取完整JSON
无需获取整个HTML,精准定位id="hz-ctx"的script标签提取内容:
# 等待目标标签出现 script_tag = WebDriverWait(browser, 10).until( EC.presence_of_element_located((By.ID, "hz-ctx")) ) # 获取标签内的JSON内容并解析 json_content = script_tag.get_attribute('innerHTML') import json data = json.loads(json_content) print(json.dumps(data, indent=2, ensure_ascii=False))
完整代码示例
from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By import json chromedriver = r'E:/ProgrammFiles/chromdriver/chromedriver.exe' opts = Options() opts.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") opts.add_argument("--disable-blink-features=AutomationControlled") opts.add_experimental_option("excludeSwitches", ["enable-automation"]) opts.add_experimental_option('useAutomationExtension', False) opts.add_argument("--window-size=1920,1080") # opts.add_argument('-headless=new') # 测试通过后可开启 browser = webdriver.Chrome(service=Service(chromedriver), options=opts) browser.get('https://www.houzz.ru/professionals/remont-i-otdelka-kvartir-i-domov') # 滚动加载所有内容 last_height = browser.execute_script("return document.body.scrollHeight") while True: browser.execute_script("window.scrollTo(0, document.body.scrollHeight);") try: WebDriverWait(browser, 5).until( EC.invisibility_of_element_located((By.CLASS_NAME, "hz-loader")) ) except: pass new_height = browser.execute_script("return document.body.scrollHeight") if new_height == last_height: break last_height = new_height # 获取并解析目标JSON script_tag = WebDriverWait(browser, 10).until( EC.presence_of_element_located((By.ID, "hz-ctx")) ) json_content = script_tag.get_attribute('innerHTML') data = json.loads(json_content) print(json.dumps(data, indent=2, ensure_ascii=False)) browser.quit()
注意事项
- 若开启无头模式,建议使用
--headless=new(Chrome 112+版本的新无头模式,更接近真实浏览器) - 等待时间可根据网络情况调整,避免过短导致内容未加载完成
- Houzz页面结构可能更新,若
hz-loader类名变化,需根据实际页面元素调整等待条件
内容的提问来源于stack exchange,提问作者Ivan Nikolaev
相关产品推荐
相关产品推荐

