WebScraping新手爬取Thingiverse遇问题:无法获取搜索结果列表
嘿,作为WebScraping新手遇到这种情况太正常了,咱们一步步拆解问题:
首先,代码里的语法错误
你写的find_all参数格式不对,BeautifulSoup的find_all方法按class查找时,正确写法是先指定标签名(这里是div),再用class_参数(因为class是Python关键字,加下划线做区分)。你原来的字典写法不符合BeautifulSoup的API规范,这会导致它无法正确匹配元素。
修正后的代码行应该是:
product_list = soup.find_all('div', class_='SearchResult__searchResultItem--c4VZk')
其次,动态内容加载的核心问题
如果修正语法后还是得到空列表,那大概率是Thingiverse的搜索结果是JavaScript动态渲染的。你用urlopen获取的只是页面的初始静态HTML,这时候那些搜索结果的div还没被加载出来——现代网站常用AJAX或前端框架(比如React)在页面加载后再请求数据并渲染内容,初始HTML里只有页面骨架。
针对这种情况,有两种实用解决办法:
方法1:用Selenium模拟浏览器加载
Selenium可以打开真实浏览器,执行JavaScript并等待页面完全渲染,这样就能拿到完整的页面内容。示例代码如下:
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 # 初始化Chrome浏览器(需提前下载对应版本的ChromeDriver) driver = webdriver.Chrome() url = "https://www.thingiverse.com/search?q=vader&type=things&sort=relevant" driver.get(url) # 等待搜索结果元素加载完成(最多等待10秒) try: WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "SearchResult__searchResultItem--c4VZk")) ) finally: # 获取渲染后的页面源代码 page_source = driver.page_source driver.quit() # 解析页面 soup = BeautifulSoup(page_source, "lxml") product_list = soup.find_all('div', class_='SearchResult__searchResultItem--c4VZk') print(len(product_list)) # 现在应该能看到有效结果数量了
方法2:直接调用网站的API接口
打开浏览器开发者工具(F12),切换到「网络」标签,刷新页面后找到搜索相关的AJAX请求(通常是XHR类型),可以直接请求这个API接口获取JSON格式的搜索结果,这种方式比Selenium效率更高。不过要注意,部分网站API可能需要认证或有请求频率限制,务必遵守网站的robots协议。
最后,反爬小提示
不管用哪种方法,都建议在请求时加上浏览器的User-Agent头,模拟真实用户请求,避免被反爬机制拦截。比如用requests的示例:
import requests from bs4 import BeautifulSoup headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, "lxml")
内容的提问来源于stack exchange,提问作者Ander Arbide Nieto

