H
H
haniaman2020-06-02 12:47:25
Python
haniaman, 2020-06-02 12:47:25

How to make it so that when a new line is output to the console, it is instantly written to csv?

Hello, there is a Selunium script that outputs data to the console when it appears (that is, new data appeared - output, appeared again - output). I need to make sure that they are written to a csv file in the same rhythm. Namely, I could just make a record (that is, the script worked out its own, the data was written), but how can I make it so that when a new line is output to the console, it is instantly written to csv?

It's just that something may not go according to plan and all data is a kerdyk: D

The data is displayed in the style:
1) Last game: 3.13 Time: 03:15:16
2) Last game: 21.89 Time: 03:15:57
3) Last game : 1.14 Time: 03:16:08
...

Code:

from selenium import webdriver
import time

driver = webdriver.Chrome()

driver.get("https://rublix.best/")

f = open('games.csv', 'a+')

prev_bet = 0
a = 1

time.sleep(12)
while True:
    # Находит блок с "Историей игр"
    all_bets = driver.find_elements_by_xpath("//div[contains(@class, 'history-line')]")

    # Определение времени на данный момент
    named_tuple = time.localtime() # получить struct_time
    time_string = time.strftime("Время: %H:%M:%S", named_tuple)

    # Выбирает последнюю из списка игру
    if all_bets:
        last_bet = all_bets[0].text

        # Выводит на экран последнюю игру в формате: ''' 1) Last game: 1.22 Время: 04:50:16 '''
        if last_bet != prev_bet:
            prev_bet = last_bet
            t = str(a) + ') ' + 'Last game: {0} {1}'.format(last_bet, time_string)
            print(t)
            a+=1
            f.write(t + '\n')
    time.sleep(1)
    
f.close()

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
Sergey Pankov, 2020-06-02
@haniaman

This can be (and more correctly) done from the outside:
./my_script.py | tee the.csv
This way you will get all the output both in the terminal and in the file.
But it is possible in another way. for example, make your own custom print:

with open('the.csv', 'w') as f:
    def my_print(s):
        print(s)
        print(s, file=f)
        f.flush()
    
    for i in range(1000):
        my_print(i)
        time.sleep(12)

You can make your own class that supports the write protocol (write) and receives a set of input / output streams into the constructor to which it will write.
class IOFork:
    def __init__(self, *streams, flush=True):
        self.streams = streams
        self._flush = flush

    def write(self, s: str):
        for stream in self.streams:
            stream.write(s)
            if self._flush:
                stream.flush()
# ...
import sys 
import time 
with open('the.csv', 'w') as f:
     io = IOFork(f, sys.stderr) 
     for i in range(100): 
         print(i, file=io) 
         time.sleep(1)

You can make sure that everything is written on time if you eavesdrop on the output file in a nearby terminal:
tail -F the.csv

S
soremix, 2020-06-02
@SoreMix

It's just that something may not go according to plan and all the given kerdyk: D

It would be best to use the context manager.
Do this: remove all openings and closings of files, plus Replaced with
f.write(t + '\n')
with open('games.csv', 'a') as f:
    f.write(t + '\n')

In this case, the file will open, write new data and close

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question