Currently I am working on some selenium
code and I wrote a code to simply go to some website, search for a few products and then list them. Everything works good except one thing. I want to print the products in this format:
1. <name>\t<price>
2. <name>\t<price> ...
The problem is that some of the products (in my particular case one of them) names are longer than the other, which produces output like this:
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ł
As you can see, if I just add one or two \\t
s, it would be okay, but I don't think it's a particularly good way to do this.
So the question is: How do I align text in column-way without manually calculating the size of the longest record in the column? (Maybe there is a standard lib-way to do this, or maybe 3rd party lib?)
Edit: I've added the code:
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-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()
I actually found the answer myself: humanfriendly
library.
Just added this code:
from humanfriendly.tables import format_pretty_table
Changed my Product
class to:
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 __iter__(self):
return iter((self.name, self.price))
And printed it out:
column_names = ['Name', 'Price']
print(format_pretty_table(products, column_names))
where products
is a list of objects of type Product
.
Given output:
-------------------------------------------------
| Name | Price |
-------------------------------------------------
| Nóż Benchmade 62 Balisong | 1 275,00 zł |
| Nóż Benchmade 63 Balisong Bowie | 1 290,00 zł |
| Nóż Benchmade 67 Balisong | 1 295,00 zł |
| Nóż Benchmade 87 Ti Balisong | 2 235,00 zł |
-------------------------------------------------
And I didn't have to use fixed-size strings (total waste and it just looks ugly) plus I didn't have to calculate by hand. So I guess that would be an answer to my question, so happy to find that library
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.