Selenium优化AWS可转换3年期预留实例定价爬虫速度
优化AWS预留实例定价爬取速度的实用方案
嘿,我来帮你搞定这个爬取速度慢的问题!你现在遍历1925个元素确实太耗时间了,咱们可以从提前过滤元素和优化等待逻辑入手,甚至还有更高效的官方方案可以替代网页爬取:
一、用精准选择器直接过滤目标元素(获取阶段就筛掉无关项)
你之前是先把所有aws-pricing-table-wrapper元素都捞出来再遍历过滤,这完全是做无用功。咱们可以用XPath直接定位符合你要求的元素——也就是名称以c5开头,同时包含"CONVERTIBLE 3-YEAR TERM"文本的实例块:
把原来获取allElements的代码换成这个:
# 直接用XPath筛选符合条件的元素,不用再遍历所有1925个 allElements = browser.find_elements(By.XPATH, "//div[contains(@class, 'aws-pricing-table-wrapper') and .//div[starts-with(text(), 'c5')] and .//*[text()='CONVERTIBLE 3-YEAR TERM']]")
这个XPath的逻辑很直白:
- 找class带
aws-pricing-table-wrapper的div - 这个div下必须有个文本以
c5开头的子元素(对应实例名称) - 同时这个div里得有显示
CONVERTIBLE 3-YEAR TERM的元素
这样拿到的allElements直接就是你要的目标,不需要再做后续过滤,速度会快很多。
二、优化页面等待逻辑,别瞎等时间
你现在用的time.sleep(10)和time.sleep(2)都是固定等待,很浪费时间。换成显式等待吧,只等必要的元素加载完成,页面一就绪就开始处理:
# 替换原来的time.sleep和WebDriverWait部分 # 先等实例列表区域加载出来 WebDriverWait(browser, 15).until( EC.presence_of_element_located((By.CLASS_NAME, 'aws-pricing-table-wrapper')) ) # 再等定价信息里的"CONVERTIBLE 3-YEAR TERM"文本出现,确保数据加载完成 WebDriverWait(browser, 10).until( EC.presence_of_element_located((By.XPATH, "//*[text()='CONVERTIBLE 3-YEAR TERM']")) )
这样就不用傻等固定时间了,页面加载好立刻干活。
三、更靠谱的替代方案:用AWS官方定价API
说实话,爬网页真不是获取AWS定价的最佳方式——网页结构随时可能变,还容易被反爬。AWS有官方的Pricing API,直接请求结构化数据,速度快到飞起,还稳定。
你可以用boto3库调用这个API,直接筛选你要的条件:c5开头的Linux实例、3年期可转换预留实例。示例代码如下(需要先配置好AWS凭证):
import boto3 import json # 初始化Pricing客户端 client = boto3.client('pricing', region_name='us-east-1') # 请求符合条件的定价数据 response = client.get_products( ServiceCode='AmazonEC2', Filters=[ {'Type': 'TERM_MATCH', 'Field': 'productFamily', 'Value': 'Compute Instance'}, {'Type': 'TERM_MATCH', 'Field': 'instanceType', 'Value': 'c5.'}, # 匹配所有c5开头的实例 {'Type': 'TERM_MATCH', 'Field': 'tenancy', 'Value': 'Shared'}, {'Type': 'TERM_MATCH', 'Field': 'operatingSystem', 'Value': 'Linux'}, {'Type': 'TERM_MATCH', 'Field': 'preInstalledSw', 'Value': 'NA'}, {'Type': 'TERM_MATCH', 'Field': 'leaseContractLength', 'Value': '3yr'}, {'Type': 'TERM_MATCH', 'Field': 'offeringClass', 'Value': 'Convertible'}, ] ) # 解析返回的JSON,提取实例名称和价格 for product in response['PriceList']: product_data = json.loads(product) instance_type = product_data['product']['attributes']['instanceType'] # 提取3年期可转换的价格(根据返回结构调整) for term in product_data['terms']['Reserved'].values(): for price_dim in term['priceDimensions'].values(): print(f"实例: {instance_type}, 价格: {price_dim['pricePerUnit']['USD']} USD")
这个方案的好处太多了:
- 不用加载整个网页,数据请求量极小,速度比爬网页快N倍
- 拿到的是结构化JSON,不用费劲解析文本内容
- 官方API稳定,不会因为AWS改网页UI就失效
总结
如果一定要用Selenium爬网页,优先用精准XPath提前过滤元素+优化显式等待;如果可以换方案,强烈推荐用AWS Pricing API,这才是最靠谱高效的方式。
内容的提问来源于stack exchange,提问作者Lukasz
相关产品推荐
相关产品推荐

