Python解析CSV文件时遭遇异常空格问题:requests处理URL报错的排查求助
解决CSV URL前导非标准空格导致requests报错的问题
我之前踩过几乎一模一样的坑!这种情况90%是因为CSV文件里藏着非普通空白字符——不是键盘输入的标准空格(ASCII 32),而是像不间断空格(NBSP,Unicode \u00A0)、全角空格(\u3000)或者UTF-8 BOM标记这类strip()默认不会处理的字符,导致URL看起来正常,但实际带了隐形前缀,让requests无法识别。
第一步:精准定位问题字符
你可以先在代码里加一段调试,打印每个字符的Unicode编码,搞清楚到底是什么字符在搞事:
with open('links.csv') as f: for line in f: strdomain = line.strip() print("Raw line content:", repr(line)) # repr会显示隐形字符 for idx, c in enumerate(strdomain): print(f"Position {idx}: Character '{c}' | Unicode code: {ord(c)}")
运行后如果看到Unicode code: 160,就是NBSP;如果是12288,就是全角空格;如果开头有65279,那就是UTF-8 BOM标记。
第二步:针对性解决空白字符问题
根据上面找到的字符类型,选对应的方法处理:
方法1:扩展strip()的移除范围
默认strip()只处理ASCII空白,我们手动加上Unicode空白字符:
import string # 包含所有标准空白 + NBSP + 全角空格 strip_chars = string.whitespace + '\u00A0\u3000' with open('links.csv') as f: for line in f: strdomain = line.strip(strip_chars) if not strdomain: continue # 后续逻辑...
方法2:用正则清除所有空白类字符
正则的\s会匹配所有Unicode空白字符,一步到位:
import re with open('links.csv') as f: for line in f: # 先strip再替换所有剩余空白 strdomain = re.sub(r'\s+', '', line.strip()) if not strdomain: continue # 后续逻辑...
方法3:处理UTF-8 BOM问题
如果调试发现开头有65279(BOM标记),那是因为CSV是用带BOM的UTF-8编码保存的,打开时指定编码为utf-8-sig就能自动移除:
with open('links.csv', encoding='utf-8-sig') as f: for line in f: strdomain = line.strip() # 后续逻辑...
第三步:优化URL处理逻辑(可选但推荐)
你现在的fix_domain处理有点繁琐,用urllib.parse解析URL会更可靠,还能避免拼接sitemap时出现重复斜杠的问题:
from urllib.parse import urlparse # 处理URL时确保scheme完整,避免无http/https的情况 parsed = urlparse(strdomain) if not parsed.scheme: strdomain = f"https://{strdomain}" # 生成sitemap URL时,先移除末尾的斜杠再拼接 sitemap_url = f"{strdomain.rstrip('/')}/sitemap.xml" map_content = find_sitemap.get_sitemap(sitemap_url)
修改后的完整代码参考
import string from urllib.parse import urlparse with open('links.csv', encoding='utf-8-sig') as f: for line in f: # 移除所有类型的空白字符 strdomain = line.strip(string.whitespace + '\u00A0\u3000') if not strdomain: continue # 确保URL有正确的http/https前缀 parsed = urlparse(strdomain) if not parsed.scheme: strdomain = f"https://{strdomain}" # 生成简洁的文件名 fix_domain = parsed.netloc.replace('www.', '').replace('.', '') ofile = f"{fix_domain}.txt" # 拼接正确的sitemap地址 sitemap_url = f"{strdomain.rstrip('/')}/sitemap.xml" map_content = find_sitemap.get_sitemap(sitemap_url) if not map_content: print(f"⚠️ Unable to fetch sitemap for {strdomain}") continue url_info = find_sitemap.parse_sitemap(map_content) print(f"✅ Found {len(url_info)} urls for {strdomain}") for u in url_info: print(u['loc']) # 打印具体的URL,而不是整个字典
另外,给你的find_sitemap.py加个小优化,捕获requests异常避免程序崩溃:
def get_sitemap(url): try: get_url = requests.get(url, timeout=10) get_url.raise_for_status() # 抛出4xx/5xx的错误 return get_url.text except requests.exceptions.RequestException as e: print(f'Unable to fetch sitemap: {url} | Error: {str(e)}') return None
内容的提问来源于stack exchange,提问作者user1193480
相关产品推荐
相关产品推荐

