BeautifulSoup仅读取表头与首行问题排查(Ubuntu17.04)
先梳理几个核心问题,这应该就是导致你在Ubuntu 17.04上只能读取表头和第一行数据的原因:
1. HTML结构存在语法错误
你提供的HTML片段里,第一行数据的最后一个<td>标签错误地用了</th>闭合:
<td height=5px> </th></tr>
这种畸形的标签嵌套,在不同版本的HTML解析器中处理逻辑差异很大。Ubuntu 14.04使用的Python 3版本较低,内置的html.parser对错误HTML的容错性更强;而Ubuntu 17.04的Python 3版本更高,html.parser对语法错误的处理更严格,导致解析到这里就中断了表格行的识别。
修复建议:
- 如果有权限修改目标页面的HTML,把错误的
</th>改成</td>。 - 如果无法修改页面,改用容错性更好的解析器(比如
lxml或html5lib),它们能更好地处理不规范的HTML结构。
2. Python 3兼容性问题
你的代码开头用了#!/usr/bin/env python3,但导入了urllib2——这个模块在Python 3中已经被拆分到urllib.request里了。Ubuntu 14.04可能因为环境兼容(比如你实际运行的是Python 2)没暴露这个问题,但Ubuntu 17.04的Python 3环境会直接触发异常,不过你说能读取部分数据,可能是环境里有兼容包,但这依然是潜在的隐患。
修复代码中的urllib部分:
# 替换原来的urllib2导入语句 import urllib.request as urllib2
3. 改用更健壮的HTML解析器
默认的html.parser对错误HTML的处理能力有限,建议安装并使用lxml或html5lib:
安装解析器
# 安装lxml解析器 sudo apt-get install python3-lxml # 或者安装html5lib解析器 sudo apt-get install python3-html5lib
修改BeautifulSoup初始化代码
# 改用lxml解析器 soup = BeautifulSoup(page, "lxml") # 或者改用html5lib解析器 soup = BeautifulSoup(page, "html5lib")
4. CSV读写与数据库插入的Python 3兼容优化
你的代码里还有一些Python 2风格的写法,在Python 3中可能导致异常或数据丢失:
修复CSV写入逻辑
Python 3中写CSV建议用文本模式w并指定newline='',避免生成额外的空行:
with open('/home/hirdesh/cronrun/iop_status.csv', 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(headers) writer.writerows(row for row in rows if row)
修复CSV读取与数据库插入逻辑
Python 3中file()函数已被废弃,改用open(),同时注意编码问题,另外原代码用itertools.islice的写法可以简化:
# 替换原来的csv_data读取与插入逻辑 with open('/home/hirdesh/cronrun/iop_status.csv', 'r', encoding='utf-8') as f: csv_data = csv.reader(f) next(csv_data) # 跳过表头行,因为不需要插入数据库 for row in csv_data: # 注意row的索引对应关系,确保和数据库字段匹配 CIRCLE = row[1] SSA= row[2] Switch= row[3] CES_NAME= row[4] CES_IP = row[5] IOP_A_STATUS = row[6] IOP_B_STATUS = row[7] IOP_TESTING_DATE= row[8] IOP_STATUS = row[9] CURNT_DATE= row[10] values = (CIRCLE, SSA, Switch,CES_NAME, CES_IP, IOP_A_STATUS, IOP_B_STATUS, IOP_TESTING_DATE, IOP_STATUS,CURNT_DATE) cursor.execute(query2,values)
5. 日志文件写入的Python 3兼容优化
Python 3中写文本文件建议用文本模式,避免字节串和字符串混用:
with open("/home/hirdesh/cronrun/iop_stauslog.txt", 'w', encoding='utf-8') as file: # 计算实际插入的行数(减去表头行) with open('/home/hirdesh/cronrun/iop_status.csv', 'r', encoding='utf-8') as csv_file: total_rows = len(list(csv.reader(csv_file))) - 1 file.write(f"2.{total_rows} Rows Inserted\n") file.write(f"Current date & time {time.strftime('%c')}\n") file.write("*****************\n")
总结执行步骤
- 优先修复目标HTML的标签错误(如果可行)。
- 安装
lxml或html5lib解析器。 - 修改代码中的Python 3兼容问题(urllib导入、CSV读写、日志写入)。
- 替换BeautifulSoup的解析器为
lxml或html5lib。
按照上面的步骤调整后,应该就能解决Ubuntu 17.04上只能读取表头和第一行的问题了。
内容的提问来源于stack exchange,提问作者user224681

