【问题标题】:Error when trying to write unicode results from web scraping to CSV尝试将 Web 抓取的 unicode 结果写入 CSV 时出错
【发布时间】:2017-07-21 09:54:05
【问题描述】:

我正在使用网络抓取脚本(在 GitHub 上找到),并将结果写入 .csv 文件。一些结果(用户评论)是用日语或俄语编写的,因此我想将 unicode 写入 .csv 文件。

当我只使用 csv 模块时,代码可以正常工作,但这不会将 unicode 写入 csv。

这是我用于网络抓取的代码的一部分:

with open(datafile, 'w', newline='', encoding='utf8') as csvfile:

    # Tab delimited to allow for special characters
    datawriter = csv.writer(csvfile, delimiter=',')
    print('Processing..')
    for i in range(1,pages+1):

        # Sleep if throttle enabled
        if(throttle): time.sleep(sleepTime)

        page = requests.get(reviewPage + '&page=' + str(i))
        tree = html.fromstring(page.content)

        # Each item below scrapes a pages review titles, bodies, ratings and languages. 
        titles = tree.xpath('//a[@class="review-title-link"]')
        bodies = tree.xpath('//div[@class="review-body"]')
        ratings = tree.xpath('//div[@data-status]')
        langs = tree.xpath("//h3[starts-with(@class, 'review-title')]")
        dates = tree.xpath("//time[@datetime]")

        for idx,e in enumerate(bodies):

            # Title of comment
            title = titles[idx].text_content()

            # Body of comment
            body = e.text_content().strip()

            # The rating is the 5th from last element
            rating = ratings[idx].get('data-status').split(' ')[-5] 

            # Language is 2nd element of h3 tag
            lang = langs[idx].get('class').split(' ')[1]

            #Date
            date = dates[idx].get("datetime").split('T')[0]

            datawriter.writerow([title,body,rating,lang,date])
    print('Processed ' + str(ratingCount) + '/' + str(ratingCount) + ' ratings.. Finished!')

我试过import unicodecsv as csv,但这引发了一个TypeError:

TypeError                                 Traceback (most recent call last)
<ipython-input-4-2db937260285> in <module>()
     44             date = dates[idx].get("datetime").split('T')[0]
     45 
---> 46             datawriter.writerow([title,body,rating,lang,date])
     47     print('Processed ' + str(ratingCount) + '/' + str(ratingCount) + ' ratings.. Finished!')

~\lib\site-packages\unicodecsv\py3.py in writerow(self, row)
     26 
     27     def writerow(self, row):
---> 28         return self.writer.writerow(row)
     29 
     30     def writerows(self, rows):

C:\Users\Ebel\Anaconda3\lib\site-packages\unicodecsv\py3.py in write(self, string)
     13 
     14     def write(self, string):
---> 15         return self.binary.write(string.encode(self.encoding, self.errors))
     16 
     17 

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

我想为这个问题找到一个解决方案。提前致谢!

【问题讨论】:

  • 试试:with open(datafile, 'w', newline='', encoding='utf8') as csvfile: --> with open(datafile, 'wb', newline='', encoding='utf8') as csvfile:
  • 然后尝试去掉encoding参数 --> with open(datafile, 'wb', newline='') as csvfile:
  • 您的with 对Python 3 是正确的,而unicodecsv 仅对Python 2 是必需的。只需import csv(使用内置的)。您是什么意思“它不会将 unicode 写入 csv”?如果你在 Windows 上,你可以试试encoding='utf-8-sig'。如果没有 BOM 签名,Windows 记事本将无法正确显示 UTF-8 文件,Excel 也无法正确读取。
  • @MarkTolonen 你是对的,刚刚想通了。谢谢。
  • @Silveris 工作它现在不返回错误。谢谢!

标签: python python-3.x csv unicode web-scraping


【解决方案1】:

由于unicodecsv 正在写入字节而不是字符串,因此您希望将open() 写入binary mode 中的文件。注意binary mode不需要编码,需要去掉encoding参数。

with open(datafile, 'w', newline='', encoding='utf8') as csvfile:

然后变成:

with open(datafile, 'wb', newline='') as csvfile:

'wb' 中的 b 表示您要写入字节而不是字符串。

【讨论】:

    【解决方案2】:

    让评论成为答案。

    您的with 对 Python 3 是正确的,而 unicodecsv 仅对 Python 2 是必需的。只需 import csv(使用内置的)。在 Windows 上,使用 encoding='utf-8-sig'。如果没有 BOM 签名,Windows 记事本将无法正确显示 UTF-8 文件,并且 Excel 也无法正确读取它。

    【讨论】:

      猜你喜欢
      • 2011-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-10
      • 1970-01-01
      • 2021-10-03
      • 2015-02-18
      相关资源
      最近更新 更多