yb775802151 2016-11-06 10:55 采纳率: 0%
浏览 7510

关于python3.5中的bytes-like object和str

最近学scrapy爬虫的时候,用CsvItemExporter将Item写入csv文件时,报错

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

代码如下:

 class StockPipelineCSV(object):

 def open_spider(self,spider):
     self.file = open('stocks_01.csv', 'w')
     self.exporter = CsvItemExporter(self.file)
     self.exporter.start_exporting()

 def close_spider(self,spider):
     self.exporter.finish_exporting()
     self.file.close()

 def process_item(self, item, spider):
     self.exporter.export_item(item)
     return item

然后找到exporters的CsvItemExporter类中的export_item()函数以及其他相关函数:

 #exporters.py
 def export_item(self, item):
      if self._headers_not_written:
          self._headers_not_written = False
          self._write_headers_and_set_fields_to_export(item)

      fields = self._get_serialized_fields(item, default_value='',
                                           include_empty=True)
      values = list(self._build_row(x for _, x in fields))
      self.csv_writer.writerow(values)

  def _build_row(self, values):
      for s in values:
          try:
              yield to_native_str(s, self.encoding)
          except TypeError:
              yield s
 #python.py
 def to_native_str(text, encoding=None, errors='strict'):
 """ Return str representation of `text`
 (bytes in Python 2.x and unicode in Python 3.x). """
 if six.PY2:
     return to_bytes(text, encoding, errors)
 else:
     return to_unicode(text, encoding, errors)

发现这里没问题已经将item转换成存放str对象的一个list了,不知道问题究竟出在哪里?scrapy是初学,不知道是不是scrapy的itempipeline.py代码的问题?
网上查了半天说是要用w+b二进制方式打开,这样确实不会报错了,但写进去之后是乱码,顺序也随机(这个可能是我settings.py里没有设置)

然后我自己写了小程序测试,自己open一个csv文件,以w+b打开

 # coding: utf-8

import csv

csvfile = open('D://t.csv', 'w+b')
writer = csv.writer(csvfile)
writer.writerow([str.encode('列1'), str.encode('列2'), str.encode('列3')])

data = [
    str.encode('值1'), str.encode('值2'), str.encode('值3')
]
writer.writerow(data)

csvfile.close()

结果报错:

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

但我明明把他转换成bytes了啊。最后换了一种方式,去掉str.encode(),用w方式写入,正常了。但对bytes-like object和str者二者很困惑,不理解之前的方式为什么会报错。

  • 写回答

1条回答 默认 最新

  • oyljerry 2016-11-06 13:13
    关注

    python3中,byte字符串就是ansi字符串。str是unicode字符串。所以写文件的时候需要注意文件编码格式

    评论

报告相同问题?

悬赏问题

  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler