Python(bs4)爬虫写入CSV:连续换行致单元格拆分的解决问询
解决CSV写入时连续换行导致内容错位的问题
问题根源
你遇到的问题是因为仅替换了单个\n换行符,但没有处理连续换行、回车符(\r)等其他空白字符,再加上手动拼接CSV内容时未对特殊字符做转义,残留的换行符被当成了新行的分隔符,导致内容跑到下一行的单元格里。
快速修复方案:用正则统一处理空白字符
Python的re模块可以一次性匹配所有空白序列(包括单个/连续换行、回车、空格、制表符等),将其替换为单个空格,彻底避免残留换行的问题。
步骤如下:
- 先导入正则模块:
import re
- 修改文本处理的代码(或者在拼接时替换):
# 爬取并处理文本时直接用正则替换 beschreibung_container = container.find_all("pre", {"class":"is24qa-objektbeschreibung text-content short-text"}) beschreibung = re.sub(r'\s+', ' ', beschreibung_container[0].get_text().strip()) if beschreibung_container else "" ausstattung_container = container.find_all("pre", {"class":"is24qa-ausstattung text-content short-text"}) ausstattung = re.sub(r'\s+', ' ', ausstattung_container[0].get_text().strip()) if ausstattung_container else "" lage_container = container.find_all("pre", {"class":"is24qa-lage text-content short-text"}) lage = re.sub(r'\s+', ' ', lage_container[0].get_text().strip()) if lage_container else ""
或者如果你想保留原有的文本处理逻辑,仅在拼接时替换:
# 拼接时用正则替换所有空白序列 f.write(objektid + "##" + titel + "##" + adresse + "##" + criteria.replace(" ", ";") + "##" + preis.replace(" ", ";") + "##" + energie.replace(" ", ";") + "##" + re.sub(r'\s+', ' ', beschreibung) + "##" + re.sub(r'\s+', ' ', ausstattung) + "##" + re.sub(r'\s+', ' ', lage) + "\n")
更规范的长期方案:使用Python内置csv模块
手动拼接CSV字符串很容易踩坑(比如字段包含分隔符、换行符等),Python内置的csv模块会自动处理这些特殊情况,自动用引号包裹含特殊字符的字段,从根源避免格式错误。
示例代码:
import csv import re from bs4 import BeautifulSoup # 假设你已经有爬取到的container数据 with open('immobilien.csv', 'w', newline='', encoding='utf-8') as csv_file: # 指定分隔符为你用的## writer = csv.writer(csv_file, delimiter='##') # 写入表头(可选,根据你的需求调整) writer.writerow(["ObjektID", "Titel", "Adresse", "Kriterien", "Preis", "Energie", "Beschreibung", "Ausstattung", "Lage"]) try: # 你的爬取逻辑... objektid = "..." # 替换为你的实际数据 titel = "..." adresse = "..." criteria = "..." preis = "..." energie = "..." # 处理文本字段 beschreibung_container = container.find_all("pre", {"class":"is24qa-objektbeschreibung text-content short-text"}) beschreibung = re.sub(r'\s+', ' ', beschreibung_container[0].get_text().strip()) if beschreibung_container else "" ausstattung_container = container.find_all("pre", {"class":"is24qa-ausstattung text-content short-text"}) ausstattung = re.sub(r'\s+', ' ', ausstattung_container[0].get_text().strip()) if ausstattung_container else "" lage_container = container.find_all("pre", {"class":"is24qa-lage text-content short-text"}) lage = re.sub(r'\s+', ' ', lage_container[0].get_text().strip()) if lage_container else "" # 写入一行数据 writer.writerow([ objektid, titel, adresse, criteria.replace(" ", ";"), preis.replace(" ", ";"), energie.replace(" ", ";"), beschreibung, ausstattung, lage ]) except Exception as e: print(f"Es gab einen Fehler: {str(e)}")
为什么原代码失效?
你的replace("\n", " ")只能替换单个\n,但如果文本里存在\r\n(Windows系统换行)、\n\n(连续换行)或者\r(单独回车),这些字符不会被替换,会被CSV解析器当成新行的分隔符,导致内容错位。而正则的\s+会匹配所有空白字符,一次性将任意数量的空白替换为单个空格,彻底解决这个问题。
内容的提问来源于stack exchange,提问作者Juli Goe
相关产品推荐
相关产品推荐

