鱼C论坛

 找回密码
 立即注册
查看: 1404|回复: 17

[已解决]openpyxl报错求助

[复制链接]
发表于 2022-1-29 11:39:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

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

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

我是爬取网页的一个栏目。并且把这个栏目当成我的execl文件名,这个栏目的前22页都能正常保存到execl里面
报错后程序生成的execl里面也有前22页的内容
报错代码:

                               
登录/注册后可看大图

下面是我保存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([ILLEGAL_CHARACTERS_RE.sub(r'', name[i]), star[i], count[i], sold[i],
                       str(min[i] / 10000) + '~' + str(max[i] / 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([ILLEGAL_CHARACTERS_RE.sub(r'',name[i]),star[i],count[i],sold[i],str(min[i]/10000)+'~'+str(max[i]/10000)])
        wb.save('{}.xlsx'.format(title))
        wb.close()
        del wb, ws
        gc.collect()
最佳答案
2022-1-29 12:25:53
极客4321 发表于 2022-1-29 12:17
我电脑都没wps

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

确实有可能,sleep等一会看看有没有效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-29 11:45:16 | 显示全部楼层
方便贴一下完整的报错信息吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-29 11:47:27 From FishC Mobile | 显示全部楼层
本帖最后由 hrp 于 2022-1-29 11:52 编辑

新建xlsx前增加一个环节,验证要做文件名的字符串是否符合系统的命名规则(是否全部都是可用做文件名的字符),以下字符在windows上不能用做文件名:< > / \ | : " * ?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-29 11:50:26 | 显示全部楼层
isdkz 发表于 2022-1-29 11:45
方便贴一下完整的报错信息吗?


                               
登录/注册后可看大图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-29 11:54:02 | 显示全部楼层

你那个Permission denied的文件在你的操作系统里面确实能创建成功的吗?你试试手动建一个这样的文件看看能不能成功
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

应该不是这个问题,因为我是把网页的栏目名称当成文件名,一个栏目比如说有30页,前20页它都能正常保存下来,21页就报错了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

这个原因有点多,有可能是爬取的页数多了爬到不数据,返回了特殊字符,导致用特殊字符做文件名创建文件失败,都是有可能的,你可以先调试一下看看第21返回了什么。不管怎么说,创建文件前验证文件名的合法性都是有必要的,文件名不合法就得给他指定一个新文件名。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

可以的,虽然报错了但程序已经把前22页的内容保存在里面了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-29 12:06:47 | 显示全部楼层
本帖最后由 isdkz 于 2022-1-29 12:08 编辑

或者是你要保存的那个表格文件你用其它的excel软件打开了,比如wps之类的,这些软件获取到文件句柄就会抓着不放直到软件关闭的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

文件名这个是没问题的,因为title是我自己定死的
不过是否爬取多了返回的数据不对得去看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

我电脑都没wps

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

我就怀疑是不是我的代码里面有问题,比如写入第20页的内容execl还没有关闭,而第21页的时候又要打开execl,造成了资源竞争
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-29 12:25:53 | 显示全部楼层    本楼为最佳答案   
极客4321 发表于 2022-1-29 12:17
我电脑都没wps

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

确实有可能,sleep等一会看看有没有效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-29 12:32:18 | 显示全部楼层
本帖最后由 isdkz 于 2022-1-29 12:41 编辑
极客4321 发表于 2022-1-29 12:17
我电脑都没wps

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


这个不会,openpyxl会自动释放资源的,只能是其它软件跟它竞争,
你可以在命令提示符自己测试一下,打开多个进程用openpyxl同时对同一个文件进行操作,
你也可以打开openpyxl的源码看一下,凡是有写操作的地方它都自动关闭文件了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-29 13:40:41 | 显示全部楼层
翼是孤独 发表于 2022-1-29 12:25
确实有可能,sleep等一会看看有没有效果

sleep了没有效果

难道是有本地软件在读取我的execl
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-29 19:41:22 | 显示全部楼层
翼是孤独 发表于 2022-1-29 16:06
找到一个测试文件是否被占用的代码,写23页之前测试一下,看看是不是被占用了

谢谢大佬,已经解决了。
是因为上面我怀疑的资源抢占,由于我电脑性能拉跨,用sleep(10)就不会报错了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

查到到底是什么占用了没
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-29 23:28:32 | 显示全部楼层
翼是孤独 发表于 2022-1-29 23:28
查到到底是什么占用了没

有点好奇
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-12 09:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表