极客4321 发表于 2022-1-29 11:39:44

openpyxl报错求助

本帖最后由 极客4321 于 2022-1-29 12:04 编辑

从网上爬取几百页网页信息(数据量可能有点大)存入excel表中,可以运行一段时间,也保存了十几页的网页内容。
但是运行着就会报:PermissionError: Permission denied: '***.xlsx'的错误。
从网上也搜索了,有说是openpyxl没有自动回收内存的,我也弄手动回收了(应该)。
常规写法报错,我还搞了openpyxl的“只写模式”,也不能解决问题
还有说是因为打开文件后没有关闭excel导致的,但是为什么程序是在保存了几个.xlsx文件后才报错的?

而且每一次运行后保存的.xlsx文件的数量是不一样的,即不是在同一个地方报错。

我是爬取网页的一个栏目。并且把这个栏目当成我的execl文件名,这个栏目的前22页都能正常保存到execl里面
报错后程序生成的execl里面也有前22页的内容
报错代码:http://img7.ng8855.com/ima/2022/01/29/j0q8hy.png
下面是我保存execl的代码,麻烦各位大佬看看写法有哪些问题?
def save_excel(i,title,name,star,count,sold,min,max):

    if i != 0:
      wb = openpyxl.load_workbook('./{}.xlsx'.format(title))
      ws = wb.active
      long = len(name)
      for i in range(long):
            ws.append(), star, count, sold,
                     str(min / 10000) + '~' + str(max / 10000)])
      wb.save('{}.xlsx'.format(title))
      wb.close()
      del wb, ws
      gc.collect()
    else:
      wb = openpyxl.Workbook(write_only = True)
      ws = wb.create_sheet()
      ws.append(['商品名称','评分','评价数量','销量','售价'])
      col = ws.column_dimensions['A']
      col.width = 50
      col = ws.column_dimensions['B']
      col.width = 15
      col = ws.column_dimensions['C']
      col.width = 15
      col = ws.column_dimensions['D']
      col.width = 15
      col = ws.column_dimensions['E']
      col.width = 25
      long = len(name)
      for i in range(long):
            ws.append(),star,count,sold,str(min/10000)+'~'+str(max/10000)])
      wb.save('{}.xlsx'.format(title))
      wb.close()
      del wb, ws
      gc.collect()

isdkz 发表于 2022-1-29 11:45:16

方便贴一下完整的报错信息吗?

hrp 发表于 2022-1-29 11:47:27

本帖最后由 hrp 于 2022-1-29 11:52 编辑

新建xlsx前增加一个环节,验证要做文件名的字符串是否符合系统的命名规则(是否全部都是可用做文件名的字符),以下字符在windows上不能用做文件名:< > / \ | : " * ?

极客4321 发表于 2022-1-29 11:50:26

isdkz 发表于 2022-1-29 11:45
方便贴一下完整的报错信息吗?

http://img7.ng8855.com/ima/2022/01/29/j0q8hy.png

isdkz 发表于 2022-1-29 11:54:02

极客4321 发表于 2022-1-29 11:50


你那个Permission denied的文件在你的操作系统里面确实能创建成功的吗?你试试手动建一个这样的文件看看能不能成功

极客4321 发表于 2022-1-29 11:54:28

hrp 发表于 2022-1-29 11:47
新建xlsx前增加一个环节,验证要做文件名的字符串是否符合系统的命名规则(是否全部都是可用做文件名的字符)

应该不是这个问题,因为我是把网页的栏目名称当成文件名,一个栏目比如说有30页,前20页它都能正常保存下来,21页就报错了

hrp 发表于 2022-1-29 11:59:25

极客4321 发表于 2022-1-29 11:54
应该不是这个问题,因为我是把网页的栏目名称当成文件名,一个栏目比如说有30页,前20页它都能正常保存下 ...

这个原因有点多,有可能是爬取的页数多了爬到不数据,返回了特殊字符,导致用特殊字符做文件名创建文件失败,都是有可能的,你可以先调试一下看看第21返回了什么。不管怎么说,创建文件前验证文件名的合法性都是有必要的,文件名不合法就得给他指定一个新文件名。

极客4321 发表于 2022-1-29 12:01:11

isdkz 发表于 2022-1-29 11:54
你那个Permission denied的文件在你的操作系统里面确实能创建成功的吗?你试试手动建一个这样的文件看看 ...

可以的,虽然报错了但程序已经把前22页的内容保存在里面了

isdkz 发表于 2022-1-29 12:06:47

本帖最后由 isdkz 于 2022-1-29 12:08 编辑

或者是你要保存的那个表格文件你用其它的excel软件打开了,比如wps之类的,这些软件获取到文件句柄就会抓着不放直到软件关闭的

极客4321 发表于 2022-1-29 12:08:22

hrp 发表于 2022-1-29 11:59
这个原因有点多,有可能是爬取的页数多了爬到不数据,返回了特殊字符,导致用特殊字符做文件名创建文件失 ...

文件名这个是没问题的,因为title是我自己定死的
不过是否爬取多了返回的数据不对得去看看

极客4321 发表于 2022-1-29 12:17:05

isdkz 发表于 2022-1-29 12:06
或者是你要保存的那个表格文件你用其它的excel软件打开了,比如wps之类的,这些软件获取到文件句柄就会抓着 ...

我电脑都没wps{:5_100:}

我确定在爬取过程中没有动过电脑打开文件

我就怀疑是不是我的代码里面有问题,比如写入第20页的内容execl还没有关闭,而第21页的时候又要打开execl,造成了资源竞争{:10_266:}

翼是孤独 发表于 2022-1-29 12:25:53

极客4321 发表于 2022-1-29 12:17
我电脑都没wps

我确定在爬取过程中没有动过电脑打开文件


确实有可能,sleep等一会看看有没有效果

isdkz 发表于 2022-1-29 12:32:18

本帖最后由 isdkz 于 2022-1-29 12:41 编辑

极客4321 发表于 2022-1-29 12:17
我电脑都没wps

我确定在爬取过程中没有动过电脑打开文件


这个不会,openpyxl会自动释放资源的,只能是其它软件跟它竞争,
你可以在命令提示符自己测试一下,打开多个进程用openpyxl同时对同一个文件进行操作,
你也可以打开openpyxl的源码看一下,凡是有写操作的地方它都自动关闭文件了

极客4321 发表于 2022-1-29 13:40:41

翼是孤独 发表于 2022-1-29 12:25
确实有可能,sleep等一会看看有没有效果

sleep了没有效果

难道是有本地软件在读取我的execl{:10_277:}

翼是孤独 发表于 2022-1-29 16:06:29

极客4321 发表于 2022-1-29 13:40
sleep了没有效果

难道是有本地软件在读取我的execl

找到一个测试文件是否被占用的代码,写23页之前测试一下,看看是不是被占用了
>>> import win32file
>>> def is_used(file_name):
        try:
                vHandle = win32file.CreateFile(file_name, win32file.GENERIC_READ, 0, None, win32file.OPEN_EXISTING, win32file.FILE_ATTRIBUTE_NORMAL, None)
                return int(vHandle) == win32file.INVALID_HANDLE_VALUE
        except:
                return True
        finally:
                try:
                        win32file.CloseHandle(vHandle)
                except:
                        pass
               
>>> fn = r'D:\temp\csdn\t.py'
>>> is_used(fn)
False
>>> fp = open(fn, 'a+')
>>> is_used(fn)
True
>>> fp.close()
>>> is_used(fn)
False

极客4321 发表于 2022-1-29 19:41:22

翼是孤独 发表于 2022-1-29 16:06
找到一个测试文件是否被占用的代码,写23页之前测试一下,看看是不是被占用了

谢谢大佬,已经解决了。
是因为上面我怀疑的资源抢占,由于我电脑性能拉跨,用sleep(10)就不会报错了

翼是孤独 发表于 2022-1-29 23:28:00

极客4321 发表于 2022-1-29 19:41
谢谢大佬,已经解决了。
是因为上面我怀疑的资源抢占,由于我电脑性能拉跨,用sleep(10)就不会报错了

查到到底是什么占用了没{:5_106:}

翼是孤独 发表于 2022-1-29 23:28:32

翼是孤独 发表于 2022-1-29 23:28
查到到底是什么占用了没

有点好奇
页: [1]
查看完整版本: openpyxl报错求助