使用Python+Selenium爬取网页时,正则提取美元金额失败求助
问题分析与解决方案
问题1:正则匹配结果处理错误
原代码中re.findall(r'\$([\d,.]+)', item_text)返回的是捕获组内容的列表(每个元素是匹配到的金额字符串),但后续用match[0]去取每个元素,这会导致TypeError——因为每个match本身就是字符串,不是元组。
问题2:可能存在的美元符号不匹配
网页中的美元符号可能不是半角的$,而是全角的$,或者符号前带有空格,导致原正则无法匹配到目标内容。
问题3:重复爬取元素
每次滚动后,driver.find_elements会重新获取所有元素,包括之前已经处理过的,最终导致CSV中出现大量重复数据。
问题4:频繁打开CSV文件效率低下
原代码在处理每个元素时都打开一次CSV文件追加写入,频繁IO操作会严重影响程序性能。
修改后的完整代码
from selenium import webdriver from selenium.webdriver.common.by import By import time import csv import re url = 'https://skinsmonkey.com/trade' driver = webdriver.Firefox() driver.get(url) driver.maximize_window() scroll_script = """ var element = arguments[0]; element.scrollTop += 681; """ time.sleep(1) scrollable_box = driver.find_element(By.CSS_SELECTOR, 'div.trade-inventory:nth-child(3) > div:nth-child(3) > div:nth-child(1) > div:nth-child(1)') csv_file_path = 'output.csv' # 记录已处理元素的唯一标识,避免重复爬取 processed_elements = set() # 只打开一次CSV文件,复用writer对象 with open(csv_file_path, mode='w', newline='', encoding='utf-8') as file: writer = csv.writer(file) writer.writerow(['Item Text', 'Alt Text', 'Price']) while True: elements = driver.find_elements(By.CLASS_NAME, 'item-card__body') for element in elements: # 用元素的唯一属性作为标识,避免重复处理 element_id = element.get_attribute('data-id') or element.get_attribute('id') or str(element.location) if element_id in processed_elements: continue processed_elements.add(element_id) if element.text.strip() != "Quick View": item_text = element.text.replace('\n', '') # 匹配半角$和全角$,同时允许符号前有空格 price_matches = re.findall(r'\s*[\$$]([\d,.]+)', item_text) price = "Price not found" if price_matches: # 直接join列表元素,因为findall返回的是捕获组的字符串列表 price = ', '.join(price_matches) img_elements = element.find_elements(By.TAG_NAME, 'img') alt_text = "" for img_element in img_elements: alt_text = img_element.get_attribute('alt') if alt_text: break writer.writerow([item_text, alt_text, price]) for _ in range(2): driver.execute_script(scroll_script, scrollable_box) time.sleep(1) time.sleep(1)
关键修改说明
- 修复正则结果处理:将
price = ', '.join(match[0] for match in price_matches)改为price = ', '.join(price_matches),适配re.findall返回的捕获组字符串列表格式。 - 增强正则匹配能力:修改正则为
r'\s*[\$$]([\d,.]+)',可同时匹配半角/全角美元符号,且允许符号前存在空格。 - 避免重复爬取:新增
processed_elements集合,用元素的唯一标识(data-id、id或位置信息)记录已处理元素,防止重复写入CSV。 - 优化CSV写入:将CSV文件的打开和writer对象的创建移到循环外,避免频繁IO操作,提升程序运行效率。
内容的提问来源于stack exchange,提问作者Canced
相关产品推荐
相关产品推荐

