【问题标题】:Unable to delete some csv file conditionally无法有条件地删除某些 csv 文件
【发布时间】:2019-05-31 07:34:15
【问题描述】:

我在 python 中编写了一个脚本来从网页中获取一些表格内容并将其写入 csv 文件。我现在想做的是让我的脚本仅在该页面中可用表(可见为Top Mutual Fund Holders)时才将内容写入csv文件,否则它将删除已创建的csv文件。

该表在此webpage 中可用。

我要查找的表在此webpage 中不可用。

这是我的尝试:

import os
import csv
import requests
from bs4 import BeautifulSoup

url = "https://finance.yahoo.com/quote/UBER/holders?p=UBER"

def get_mutual_fund(soup):
    datalist = []
    for items in soup.select_one("h3:contains('Top Mutual Fund Holders')").find_next_sibling().select("table tr"):
        data = [item.text for item in items.select("th,td")]
        datalist.append(data)
    return datalist

def get_records(link):
    r = requests.get(link)
    soup_obj = BeautifulSoup(r.text,"lxml")
    try:
        item_one = get_mutual_fund(soup_obj)
    except AttributeError: 
        item_one = ""

    if item_one:
        writer.writerows(item_one)
    else:
        os.remove("mutual_fund.csv")
    return item_one

if __name__ == '__main__':
    with open("mutual_fund.csv","w",newline="") as f:
        writer = csv.writer(f)
        for elem in get_records(url):
            print(elem)

我已尝试使用没有该表的链接。但是,它会引发以下错误

while deleting the csv file:
Traceback (most recent call last):
  File "C:\Users\WCS\AppData\Local\Programs\Python\Python37-32\demo.py", line 33, in <module>
    for elem in get_records(url):
  File "C:\Users\WCS\AppData\Local\Programs\Python\Python37-32\demo.py", line 27, in get_records
    os.remove("mutual_fund.csv")
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'mutual_fund.csv'

当表格内容不存在时如何删除 csv 文件?

【问题讨论】:

  • 终止任何正在访问 csv 文件的进程,然后重试。或者,如果您正在从 Python 读取,请关闭打开的文件。我想你问的是XY problem
  • 您不应该使用全局writer 变量从get_records 函数中写入。它应该返回记录(如果有的话),然后才打开文件进行写入。
  • 哦,是的,我很笨,@buran 的建议是正确的。访问 csv 的进程完全是全局写入器。写入时不能删除文件。

标签: python python-3.x csv web-scraping


【解决方案1】:

您实际上是在打开可写入文件时删除该文件。

你应该相应地改变你的主要功能。

def get_records(link):
    r = requests.get(link)
    soup_obj = BeautifulSoup(r.text,"lxml")
    try:
        item_one = get_mutual_fund(soup_obj)
    except AttributeError: 
        item_one = None
    return item_one


if __name__ == '__main__':
    delete_file= False
    with open("mutual_fund.csv","w",newline="") as f:
        writer = csv.writer(f)
        try:
            for elem in get_records(url):
                print(elem)    
        except TypeError:
            delete_file=True
    if delete_file:
        os.remove("mutual_fund.csv")

【讨论】:

  • @yadavanklit,当您立即删除文件时(如果其中有东西),写入文件的目的是什么? :-)
  • @buran 这个怎么样?
  • OP 从函数内部写入的整个想法是违反封装。他们需要重新考虑如何检索数据以及如何写入文件。其他一切(即适应他们解决此问题的方法的变通方法)都是浪费时间
【解决方案2】:

如果您保持现有逻辑不变并在 csv 中的内容为空时删除文件,则以下内容应该有效:

import os
import csv
import requests
from bs4 import BeautifulSoup

# url = "https://finance.yahoo.com/quote/fb/holders?p=FB"
url = "https://finance.yahoo.com/quote/UBER/holders?p=UBER"

def get_mutual_fund(soup):
    datalist = []
    for items in soup.select_one("h3:contains('Top Mutual Fund Holders')").find_next_sibling().select("table tr"):
        data = [item.text for item in items.select("th,td")]
        datalist.append(data)
    return datalist

def get_records(link):
    r = requests.get(link)
    soup_obj = BeautifulSoup(r.text,"lxml")
    try:
        item_one = get_mutual_fund(soup_obj)
    except AttributeError: 
        item_one = ""

    if item_one:
        writer.writerows(item_one)
    else:
        f.close()
        os.remove('mutual_fund.csv')

if __name__ == '__main__':
    with open("mutual_fund.csv","w",newline="") as f:
        writer = csv.writer(f)
        get_records(url)

【讨论】:

    猜你喜欢
    • 2020-08-11
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 2010-09-09
    • 2017-05-05
    • 2023-04-07
    • 2021-03-13
    • 2014-03-26
    相关资源
    最近更新 更多