如何无需手动计算实现产品列表的列对齐打印?
我正在编写一段Selenium代码,用来访问网站、搜索产品并将结果格式化输出。目前功能正常,但输出格式有问题——我希望按以下格式打印:
1. <name> <price> 2. <name> <price> ...
但部分产品名称较长时,仅靠添加1-2个\t会导致格式混乱,比如:
1. Nóż Benchmade 62 Balisong 1 275,00 zł 2. Nóż Benchmade 63 Balisong Bowie 1 290,00 zł 3. Nóż Benchmade 67 Balisong 1 295,00 zł 4. Nóż Benchmade 87 Ti Balisong 2 235,00 zł
我不想手动计算最长名称的长度,有没有标准库或第三方库的方法能自动实现列对齐?
附上我的代码:
from selenium import webdriver class Product: def __init__(self, name, price): self.name = name self.price = price def __str__(self): return f'{self.name}\t{self.price}' def __repr__(self): return f'Product({self.name})' def search_for(driver, input_name, query): search_field = driver.find_element_by_name(input_name) search_field.clear() search_field.send_keys(query) search_field.submit() def create_products(driver): found_elements = driver.find_elements_by_xpath("//div[@class='wrapper']") names = [ fe.find_element_by_xpath(".//img[@alt]").get_attribute("alt") for fe in found_elements ] products = [] int_parts = driver.find_elements_by_xpath( "//span[@class='price']/span[@class='price-integer-part']") decimal_parts = driver.find_elements_by_xpath( "//span[@class='price']/span[@class='price-decimal-part']") currencies = driver.find_elements_by_xpath( "//span[@class='price']/span[@class='price-currency']") for info in zip(names, int_parts, decimal_parts, currencies): name, int_part, decimal_part, currency = info price = f'{int_part.text},{decimal_part.text} {currency.text}' products.append(Product(name, price)) return products def main(): driver = webdriver.Chrome() driver.implicitly_wait(30) driver.maximize_window() driver.get('https://kolba.pl') search_for(driver, 'query', 'benchmade balisong') products = create_products(driver) print(f'Found {len(products)} products:\n') for i, product in enumerate(products): print(f'{i+1}. {product}') if __name__ == '__main__': main()
好问题!这种动态列对齐的需求在文本输出场景里特别常见,我给你几个实用的解决方案,从纯标准库到第三方工具都有:
方案1:纯标准库实现(动态计算宽度)
这是最轻量化的方法,不需要额外安装任何库,核心思路是先算出所有产品名称里最长的那个的长度,然后统一用这个长度来对齐所有名称。
你只需要修改main函数里的打印逻辑就行:
def main(): driver = webdriver.Chrome() driver.implicitly_wait(30) driver.maximize_window() driver.get('https://kolba.pl') search_for(driver, 'query', 'benchmade balisong') products = create_products(driver) print(f'Found {len(products)} products:\n') # 先计算最长名称的长度 if products: max_name_len = max(len(p.name) for p in products) else: max_name_len = 0 # 格式化打印,用<左对齐,动态指定宽度 for i, product in enumerate(products): print(f'{i+1}. {product.name:<{max_name_len}} {product.price}')
这里的{product.name:<{max_name_len}}是Python格式化字符串的语法:<表示左对齐,{max_name_len}是动态传入的宽度值,这样所有名称都会被填充到最长的长度,价格自然就整齐地排在同一列了。
如果你想让名称和价格之间的间隔更可控,还可以在宽度基础上加几个空格,比如{product.name:<{max_name_len + 2}},这样会多留两个空格的间隔。
方案2:用第三方库tabulate生成专业表格
如果想让输出更美观,比如带表头、边框的表格,tabulate库是个非常好的选择,它会自动帮你计算每列的最优宽度,实现完美对齐。
首先安装库:
pip install tabulate
然后修改main函数的打印部分:
from tabulate import tabulate def main(): driver = webdriver.Chrome() driver.implicitly_wait(30) driver.maximize_window() driver.get('https://kolba.pl') search_for(driver, 'query', 'benchmade balisong') products = create_products(driver) print(f'Found {len(products)} products:\n') # 准备表格数据:序号、名称、价格 table_data = [[i+1, product.name, product.price] for i, product in enumerate(products)] # 打印表格,指定表头、格式和对齐方式 print(tabulate(table_data, headers=["序号", "产品名称", "价格"], tablefmt="simple", colalign=("left", "left", "right")))
tabulate支持多种表格格式,比如grid(带边框)、fancy_grid(更美观的边框)、markdown(Markdown格式表格)等,你可以根据需求替换tablefmt参数的值。
方案3:进阶用法——string.Formatter
Python内置的string.Formatter类提供了更底层的格式化控制,适合处理更复杂的场景,不过对于你的需求来说,前两种方法已经足够好用了,这里给你做个参考:
from string import Formatter def main(): driver = webdriver.Chrome() driver.implicitly_wait(30) driver.maximize_window() driver.get('https://kolba.pl') search_for(driver, 'query', 'benchmade balisong') products = create_products(driver) print(f'Found {len(products)} products:\n') formatter = Formatter() if products: max_name_len = max(len(p.name) for p in products) # 动态生成格式化字符串 format_str = "{}. {:<%d} {}" % max_name_len for i, product in enumerate(products): print(formatter.format(format_str, i+1, product.name, product.price))
总结
- 如果你不想引入第三方依赖,方案1是最佳选择,简单高效,完全用Python标准库就能实现;
- 如果你需要更专业、美观的表格输出,方案2的
tabulate库能帮你快速搞定。
内容的提问来源于stack exchange,提问作者minecraftplayer1234

