Python报错TypeError:需传入字符串/字符流而非列表的解决方法
解决
TypeError: Parser must be a string or character stream, not list问题 这个错误的根源很直白:你用dateutil.parser.parse()处理了一个列表,但这个函数只能接受单个字符串类型的时间参数。你的m_time是通过列表推导式生成的[item['datetime'] for item in time],本身就是一个包含多个时间字符串的列表,直接扔给parse()肯定会触发报错。
修正步骤
你需要遍历m_time里的每一个时间字符串,逐个解析并格式化,再把结果收集成新的列表,最后转成Pandas Series。
方法1:循环逐个处理(可读性更高)
把你代码里的时间处理部分替换成:
# 初始化空列表存格式化后的时间 formatted_times = [] for time_str in m_time: # 逐个解析时间字符串 unf_time = dateutil.parser.parse(time_str) # 转成你需要的格式 formatted_time = unf_time.strftime('%m-%d-%Y:%H:%M:%S') formatted_times.append(formatted_time) # 生成对应Series s7 = pd.Series(formatted_times, name='Time Posted')
方法2:列表推导式(更简洁)
如果偏好简洁写法,也可以用一行完成时间格式化:
formatted_times = [dateutil.parser.parse(ts).strftime('%m-%d-%Y:%H:%M:%S') for ts in m_time] s7 = pd.Series(formatted_times, name='Time Posted')
额外优化:循环内的DataFrame拼接
另外,你现在在for循环里每次都用pd.concat拼接DataFrame,多次拼接会影响效率,建议先把每页的数据存到列表里,循环结束后再一次性合并:
# 先创建空列表存储每页的数据 all_page_data = [] for page in range(1, int(no_pages)): req = requests.get(url3 + str(page)) soup = BeautifulSoup(req.content, 'html.parser') time_tags = soup.find_all('time', {"class":"timeago b-card--el-agency-time"}) m_time = [item['datetime'] for item in time_tags] # 格式化时间 formatted_times = [dateutil.parser.parse(ts).strftime('%m-%d-%Y:%H:%M:%S') for ts in m_time] s7 = pd.Series(formatted_times, name='Time Posted') # 拼接当前页的所有数据 page_df = pd.concat([s1, s2, s3, s7, s4, s6+s5], axis=1) all_page_data.append(page_df) # 最后合并所有页的数据,ignore_index=True重置索引 df = pd.concat(all_page_data, ignore_index=True)
这样处理后,你就能得到符合预期的输出格式:
Time Posted 0 08-25-2020:09:44:06 1 08-22-2020:09:44:06 2 08-29-2020:09:44:06 3 08-21-2020:09:44:06 ...
内容的提问来源于stack exchange,提问作者Tvnyl
相关产品推荐
相关产品推荐

