爬虫采集到的数据保存到CSV文件中乱码问题的解决办法

本文介绍了解决Python在Windows环境下处理大量CSV数据时出现乱码的问题,通过分两次打开文件,先写入BOM_UTF8防止乱码,再进行数据写入。

         以下的几种错误就是我在解决CSV文件中乱码问题时遇到的:

  • TypeError: write() argument must be str, not bytes;

  • TypeError: a bytes-like object is required, not 'str';

         还有一些是调试的时候出的错误,但是有点忘了,大意就是在用某种方法解决一个错误时引发的下一个错误,主要原因还是没找到根本原因,因此错误不断。

由于我用的的是python3,windows系统,乱码前文件读写操作是这样写的:

with open('文件路径.csv', 'a+', encoding='utf-8', errors='ignore', newline="") as f:
      writer = csv.writer(f)
      writer.writerow(csvHeader)  # 这个是写CSV文件的文件头
      writer.writerow(infoList)   # 这个是将数据按行写到文件中

        一般情况下这样写是没有问题,因为之前这样写拿到的csv文件也是没有乱码的,但这次由于爬取的数据量较大,前面还不会乱码,到了一定数量之后出现了乱码;经过多方查找原因最后是这样解决的:

with open('路径.csv', 'ab+') as fileopen:
     fileopen.write(codecs.BOM_UTF8)   # 为了防止在windows下直接打开csv文件出现乱码

with open('./*****.csv', 'a+', encoding='utf-8', errors='ignore', newline="") as f:
      writer = csv.writer(f)
      writer.writerow(csvHeader)
      writer.writerow(infoList)

          网上搜索解决办法时都没有说清楚,我边看边理解最后终于弄明白了:

           如果我们使用 Linux/Unix 生成CSV文件,按原来的方式写不会出现乱码问题,想要在Windows上面打开并且不乱码,我们就要显试的写入那几个确认编码的字符:fileopen.write(codecs.BOM_UTF8);但是这句话在python2和python3的写法上有区别,python2种可以直接这么写:

with open('路径.csv', 'ab+') as f:
      f.write(codecs.BOM_UTF8)
      writer = csv.writer(f)
      writer.writerow(csvHeader)
      writer.writerow(infoList)

         但是要注意必须用二进制的方式打开文件,并且open()里没有这些参数 ” encoding='utf-8', errors='ignore', newline="" “;python3这么写的话就会报上面的这些错误,因为 fileopen.write(codecs.BOM_UTF8) 这个必须在二进制打开文件的时候才可用,而python3在使用二进制打开文件并且在执行writer.writerow()写入数据时必须写二进制数据,这就与我们拿到的文本数据数据不符,如果把每个字段都改成二进制的话非常麻烦,所以这里就采用了将文件分两次打开的方式,第一次改形式防止乱码(注意用二进制的方式),第二次写数据(注意用非二进制方式),这样就解决了。

        注意!!!!:当使用两次打开文件的方式时注意一定都用追加的方式打开,我就是以为第一次打开文件只是改格式用”wb“就够了,结果导致我拿到的几万条数据全部被抹掉了,欲哭无泪啊,同志们要注意啊,记得备份!!!!

 

<think>好的,用户现在想要把爬取数据保存到桌面上的“评论内容.csv文件中。之前我提供的改进代码已经将文件保存在桌面的“红楼梦评论”文件夹里,并且文件名包含了评论数量,比如“douban_comments_4000条.csv”。但用户现在希望直接保存到桌面,文件名改为“评论内容.csv”,不需要子文件夹。 首先,我需要回顾之前的代码。在之前的代码中,我设置了路径配置部分,使用`os`模块来构建桌面路径,并创建了一个名为“红楼梦评论”的文件夹。然后,文件路径是结合这个文件夹和动态生成的文件名。现在用户的要求更简单,只需要保存到桌面,文件名固定为“评论内容.csv”。 接下来,我需要修改代码中的路径部分。原来的代码中,`file_path`是通过`os.path.join(folder, ...)`生成的,现在需要直接指向桌面,而不需要子文件夹。所以,应该将`file_path`改为`os.path.join(desktop, '评论内容.csv')`,同时可以删除创建文件夹的部分,或者保留`os.makedirs`但路径改为桌面,不过用户可能不需要创建子文件夹,所以直接保存到桌面更合适。 然后检查代码中的保存部分。原来的代码使用`folder`变量来指定路径,现在需要删除这个变量,直接使用`desktop`变量。同时,确保`os.makedirs`不会创建不必要的目录。不过,桌面路径通常已经存在,所以可能不需要创建,但为了保险起见,可以保留`os.makedirs(desktop, exist_ok=True)`,但更简单的方法是直接保存到桌面,不需要创建目录,因为桌面本身肯定存在。 另外,用户可能希望覆盖现有的“评论内容.csv文件,或者每次运行都生成一个新的,但根据用户的需求,只需要保存到该文件即可,不需要版本控制或数量标记。因此,文件名固定为“评论内容.csv”。 然后需要考虑编码问题,原来的代码使用`utf-8-sig`编码,这样可以避免Excel打开时的乱码问题,这点需要保留。CSV的写入部分没有问题,保持原来的`writerow`和`writerows`即可。 可能还需要测试一下路径是否正确。在Windows系统中,`os.path.expanduser('~')`会指向用户目录,比如C:\Users\Username,然后拼接'Desktop'得到桌面路径。确保在不同操作系统下也能正确指向桌面,但用户可能使用的是Windows,所以暂时假设没有问题。 此外,用户可能没有安装`fake_useragent`库,但之前的代码已经提到需要安装,所以用户可能已经处理了。如果用户遇到问题,可能需要提示安装该库,或者改用固定的User-Agent,但原代码已经处理了随机User-Agent,这部分保持不变。 总结修改步骤: 1. 删除创建文件夹的部分,或者调整路径直接指向桌面。 2. 修改文件路径为桌面下的“评论内容.csv”。 3. 确保保存代码正确,没有语法错误。 最后,检查代码是否简洁,是否去除了不必要的部分,比如原来的`folder`变量和相关目录创建,确保代码直接保存到桌面,文件名正确。同时,注释和打印信息中的路径也需要更新,以反映新的文件位置。 可能还需要考虑异常处理,比如文件写入权限问题,但原代码中已经有基本的异常处理,所以暂时保持现状。最终,提供一个修改后的代码,满足用户将CSV文件直接保存到桌面,文件名为“评论内容.csv”的需求。</think>以下是专门针对保存路径优化的代码版本,直接将CSV文件保存到桌面并命名为`评论内容.csv`: ```python import os import time import requests from bs4 import BeautifulSoup import csv from fake_useragent import UserAgent # 获取桌面路径(跨平台兼容) desktop_path = os.path.join(os.path.expanduser('~'), 'Desktop') # 爬虫配置 book_id = '1007305' base_url = f'https://book.douban.com/subject/{book_id}/comments/' target_count = 4000 file_path = os.path.join(desktop_path, '评论内容.csv') # 直接定位桌面 ua = UserAgent() # 请求头配置 headers = { 'User-Agent': ua.random, 'Referer': base_url } def fetch_comments(page): """智能分页抓取""" try: response = requests.get( url=base_url, params={'start': page*20, 'limit': 20}, headers=headers, timeout=10 ) response.raise_for_status() soup = BeautifulSoup(response.text, 'html.parser') return [comment.text.strip() for comment in soup.select('.comment-item .short')] except Exception as e: print(f'第{page+1}页抓取异常:{str(e)}') return [] # 执行抓取 comments = [] current_page = 0 while len(comments) < target_count: print(f'进度:{len(comments)}/{target_count}') page_data = fetch_comments(current_page) if not page_data: print(f'第{current_page+1}页无数据,终止采集') break comments.extend(page_data) current_page += 1 time.sleep(1.5 + current_page%3*0.2) # 动态延时策略 # 写入CSV(自动覆盖原有文件) with open(file_path, 'w', newline='', encoding='utf-8-sig') as f: csv.writer(f).writerows([[c] for c in comments[:target_count]]) print(f'文件保存至桌面:{file_path}') ``` **核心修改说明(使用LaTeX公式表示路径逻辑):** 1. **路径生成算法** 桌面路径计算: $$ \text{desktop\_path} = \text{os.path.join}(\text{os.path.expanduser}('~'), \text{'Desktop'}) $$ 文件定位: $$ \text{file\_path} = \text{os.path.join}(\text{desktop\_path}, \text{'评论内容.csv'}) $$ 2. **智能延时策略** 动态间隔时间公式: $$ \Delta t = 1.5\text{s} + (\text{current\_page} \mod 3) \times 0.2\text{s} $$ 该设计使得请求间隔在1.5-2.1秒之间波动,既符合反爬要求又提升效率 3. **文件写入优化** - 使用`utf-8-sig`编码解决Excel中文乱码问题 - 自动截取目标数量:$$ \text{comments}[:4000] $$ - 直接覆盖写入模式(无需判断文件存在性) **执行效果验证:** 当代码运行成功后,可立即在桌面看到生成的CSV文件: $$ \text{文件图标} \in \text{Desktop} \land \text{文件名} = \text{评论内容.csv} $$ **扩展建议:** 若需要追加数据而不是覆盖,可修改写入模式: ```python # 将'w'改为'a'(append模式) with open(file_path, 'a', newline='', encoding='utf-8-sig') as f: # 写入时添加时间戳 csv.writer(f).writerows([[time.strftime('%Y-%m-%d'), c] for c in new_comments]) ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值