Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
5.1k views
in Technique[技术] by (71.8m points)

python - Why does the same way of opening and writing a file gives me error the second time? ValueError: I/O operation on closed file

I am trying to write the title of a opened youtube video on "api obs.txt" and its URL on "link obs.txt". The title gets written but it says "ValueError: I/O operation on closed file." when writing the URL.

while True:
    atual = driver.current_url
    with open('link obs.txt', 'r') as file:
        linksalvo = file.readline()

  #if current is different than the saved url
if atual != linksalvo: 
    #write the new title on the file for the api to read
    with open('api obs.txt', 'w') as f:
        sys.stdout = f
        html = urlopen(atual)
        html = BeautifulSoup(html.read().decode('utf-8'), 'html.parser')
        print(html.title.get_text())
        #write the URL of the current video to the file for comparison later
    with open('link obs.txt', 'w') as f:
        print(driver.current_url) #"ValueError: I/O operation on closed file." Happens on this line

        
    sys.stdout = original_stdout
  • Unrelated problem: the loop is a while true loop but if the page doesnt have a title it will give a error message and halt. I also dont know how to make the code ignore the error and keep looking until the current page has a title.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

After you do sys.stdout = f, any operation on f will also be done on sys.stdout. Leaving that with block closes f, so it also closes sys.stdout.

Then when you later do print(driver.current_url), it tries to write this to sys.stdout, but it's closed, so you get an error. You need to use sys.stdout = f again after opening the second file.

I recommend you don't redefine sys.stdout in the first place. You can use the file argument to print() to write to a specific file object.

if atual != linksalvo: 
    #write the new title on the file for the api to read
    with open('api obs.txt', 'w') as f:
        html = urlopen(atual)
        html = BeautifulSoup(html.read().decode('utf-8'), 'html.parser')
        print(html.title.get_text(), file=f)
        #write the URL of the current video to the file for comparison later
    with open('link obs.txt', 'w') as f:
        print(driver.current_url, file=f) #"ValueError: I/O operation on closed file." Happens on this line

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...