rbutrnz
rbutrnz

Reputation: 393

How to write multiple for loop print results into a single line in a text file in python and beautifulsoup

The snippet below is working though not very presentable. I cant figure out how to write what is on display into outputfile.txt file. I want the snippet to write what is on display into a text file.

import requests
from bs4 import BeautifulSoup
from itertools import groupby

url = "https://bscscan.com/tokentxns"
soup = BeautifulSoup(requests.get(url).content, "html.parser")

data = []
for tr in soup.select("tr:has(td)"):
    tds = [td.get_text(strip=True) for td in tr.select("td")]
    _, txn_hash, tm, age, from_, _, to_, value, token = tds
    a = tr.select("a")[-1]["href"][7:]
    data.append((a, value, token))

data = sorted(data)
for _, g in groupby(data, lambda k: k[2]):
    g = list(map(list, g))
    trans = [f"{len(g)} TRANS", *[""] * (len(g) - 1)]
    total = sum(float(s.replace(",", "")) for _, s, *_ in g)
    total = [f"{total} TOTAL", *[""] * (len(g) - 1)]
    
    for subl in g[0:]:
        subl[1] = ""
        subl = ' '.join(map(str, subl))
    print(subl, end="\r")
    

    for tr, t, subl in zip(trans, total, g):
        print ("\t\t" + str(tr) + "   "  + str(t))

Current Output: Saved in the outputfile.txt - not presentable

['0x088bebef4e371757509e64d3508b6da6f376e2ac', '', 'DrakeBall To...(DBall)']    
['0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82', '', 'PancakeSwap ...(Cake)']    
['0x154a9f9cbd3449ad22fdae23044319d6ef2a1fab', '', 'CryptoBlades...(SKILL)']    
['0x3621f5b9786dfa52759c0392a72ac6818ed2c84f', '', 'EQIFI (EQX)']  1 TRANS  182513805147.0 TOTAL
['0x363621cb1b32590c55f283432d91530d77cf532f', '', 'BABYCAKE_Div...(BABYCA...)']  1 TRANS  37840.385 TOTAL
['0x4fd6d315bef387fad2322fbc64368fc443f0886d', '', 'Pancake LPs (Cake-L...)']    

Wanted Output Written to outputfile.txt:

0x9c65ab58d8d978db963e63f2bfb7121627e3a739  MDX Token (MDX)         1 TRANS   97.10128249433292 TOTAL
0xacb8f52dc63bb752a51186d1c55868adbffee9c1  BunnyPark (BP)          3 TRANS   340.2936687126161 TOTAL
0xb7dba4c673bedb174dc3ff7ec65d17c863d39b16  FAT CAKE (FATCAK...)    2 TRANS   6408272.9511043355 TOTAL
0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c  Wrapped BNB (WBNB)      2 TRANS   0.4472397706686812 TOTAL
0xdae18b46e0dbfecd441c47de1a6d7b57455a83ee  Pancake LPs (Cake-L...) 1 TRANS   0.22360679774997796 TOTAL

Upvotes: 0

Views: 114

Answers (2)

Ananth
Ananth

Reputation: 831

Since the first value in your output is a list you can just join the values to make it a single string. If you want these two values in separate variables then you can just split them again and store it as you wish. Now since you are just writing into a txt you can just save the last print statement in a variable and write it into the file directly.

I have made 2 changes to your code above:

  1. used join command
  2. changed where subl was printed and aligned that print statement by multiplying spaces.
import requests
from bs4 import BeautifulSoup
from itertools import groupby

url = "https://bscscan.com/tokentxns"
soup = BeautifulSoup(requests.get(url).content, "html.parser")

data = []
for tr in soup.select("tr:has(td)"):
    tds = [td.get_text(strip=True) for td in tr.select("td")]
    _, txn_hash, tm, age, from_, _, to_, value, token = tds
    a = tr.select("a")[-1]["href"][7:]
    data.append((a, value, token))

data = sorted(data)

for _, g in groupby(data, lambda k: k[2]):
    g = list(map(list, g))
    trans = [f"{len(g)} TRANS", *[""] * (len(g) - 1)]
    total = sum(float(s.replace(",", "")) for _, s, *_ in g)
    total = [f"{total} TOTAL", *[""] * (len(g) - 1)]
    
    for subl in g[0:]:
        subl[1] = ""
        subl = ' '.join(map(str, subl))

    g = [' '.join(i) for i in g]        # join to change the 2D list to 1D
    i =0
    for tr, t, subl in zip(trans, total, g):
        if i ==0:    # removes duplicates in the for loop
            # multiplying the space value based on the max len of the values of lsit g
            print (subl + ' '* (70-len(subl)) +  "\t " + str(tr) + "\t "  + str(t))
            i+=1
    print()

# 70 is max length a value inside list g had so I am subtracting it with current values len
# to make the spaces next column start at the same point

This was the output I got:

enter image description here

Upvotes: 1

Jack Fleeting
Jack Fleeting

Reputation: 24930

A somewhat simpler possible approach:

tab = soup.select_one('table')
data = []
for entry in tab.select('table tbody tr'):
    cells = entry.select('td')
    token = cells[-1].select_one('a')['href'].split('token/')[1]
    data.append([cells[-1].text,cells[-2].text,token])

for k, g in groupby(sorted(data), lambda k: k[0]):
    g = list(map(list, g))
    tot = sum([float(i[1].replace(',','')) for i in g ])    
    print(k,',',g[0][2],',',len(g),"TRANS",',',tot,'TOTAL')

At the time I ran it, the output was something like:

 BABY DOGE BI... (BABYDB) , 0x6d9fb3332f62fc044d5075feeea597a92f1ce0ad , 1 TRANS , 60634807618.46239 TOTAL
 BLADE KNIGHT (BK) , 0x2bfe217caa076027ac24af0e261ed311478ddf78 , 1 TRANS , 4.800279067385619 TOTAL
 Binance-Peg ... (BSC-US...) , 0x55d398326f99059ff775485246999027b3197955 , 1 TRANS , 15.242784023721224 TOTAL

etc.

Upvotes: 1

Related Questions