【问题标题】:Scrapy IOError: [Errno 22] invalid mode ('wb') or filenameScrapy IOError:[Errno 22] 无效模式('wb')或文件名
【发布时间】:2015-08-28 14:31:52
【问题描述】:
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.selector import HtmlXPathSelector
import os
from Erowid.items import ErowidItem
import codecs

class ExperiencesSpider(CrawlSpider):
    name = "experiences"
    allowed_domains = ["www.erowid.org"]
    start_urls = ['https://www.erowid.org/experiences/exp_list.shtml']
    rules = [ 
        Rule(LinkExtractor(allow =('subs/exp_[a-zA-Z]+.shtml')), follow = True), 
        Rule(LinkExtractor(allow=r'/experiences/exp\.php\?ID=\d+$'),callback='parse_item', follow = True)
    ]
    def parse_item(self, response):
        selectors = response.css('div')
        for selector in selectors:
            experience = ErowidItem()
            experience['Author'] = selector.xpath('//div[@class="author"]/a/text()').extract()
            experience['Title'] = selector.xpath('//div[@class="title"]/text()').extract()
            experience['Substance'] = selector.xpath('//div[@class="substance"]/text()').extract()
            experience['Text'] = selector.xpath("//div[@class = 'report-text-surround']/text()").extract()
            experience['Title'] =  str(experience['Title']).replace('\\' , "")
            experience['Title'] =  str(experience['Title']).replace('?' , "")

            directory = os.path.join('Erowid/archive/',experience['Substance'][0].strip().lower())
            filename = os.path.join(directory,experience['Title'][0]+'.txt')

            if not os.path.exists(directory):
                os.makedirs(directory)

            with codecs.open(filename, encoding = 'utf-8', mode= 'wb') as fid:
                for symbols in experience['Text']:
                    fid.write(symbols) 
        yield experience

我正在尝试抓取 Erowid,到目前为止,这段代码是为了创建一个目录并主要根据体验的名称和文本编写一个文件。 (根据经验,我指的是我从 Erowid 中删除的信息。)

问题在于,某些体验的名称中包含无法写入文件的字符,因为它们包含无法在windows filenames 中使用的保留字符。

我正在尝试删除所有这些保留字符,它们是

  • 以下保留字符:

    • <(小于)
    • >(大于)
    • :(冒号)
    • "(双引号)
    • /(正斜杠)
    • \(反斜杠)
    • |(竖条或竖管)
    • ?(问号)
    • *(星号)

我试着用线条做点什么

 experience['Title'] =  str(experience['Title']).replace('\\' , "")
 experience['Title'] =  str(experience['Title']).replace('?' , "")

(大部分错误来自“\”和“?”)但我仍然收到错误

IOError: [Errno 22] invalid mode ('wb') or filename: u'Erowid/archive/syrian rue\\Meditative Help?.txt'

或我知道的其他文件名是错误的,因为不应该有问号或反斜杠。

我做错了什么导致这些错误?

【问题讨论】:

    标签: python file file-io scrapy


    【解决方案1】:

    您未能替换特殊字符。试试这个:

    filename = os.path.join(directory,experience['Title'][0]+'.txt')
    filename = filename.replace('\\' , "").replace('?' , "")
    

    更新

    您只想指定一个合法的文件名。所以我想出了一个这样的想法。

    directory = os.path.join('Erowid/archive/',experience['Substance'][0].strip().lower())
    filename = experience['Substance']+experience['Title'][0]+'.txt'
    filename = "".join([i for i in filename if i in string.ascii_letters]) 
    #only use ascii letters as file name 
    filename = os.path.join(directory, filename)
    

    string.ascii_letters

    下面描述的 ascii_lowercase 和 ascii_uppercase 常量的串联。此值不依赖于语言环境。

    【讨论】:

    • 我认为这是一段时间的答案,但这是因为包含特殊字符的此类文件的数量非常少。我仍然收到与文件命名不当有关的错误/变体。
    • IOError: [Errno 22] 无效模式('wb')或文件名:与上述相同,但文件名不同
    • 没关系。命名中有更多我尚未删除的保留字符。很抱歉出现问题。
    • 我更新了我的答案,以另一种方式解决问题。试试看。
    猜你喜欢
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 2016-10-24
    • 1970-01-01
    • 2014-04-25
    • 1970-01-01
    相关资源
    最近更新 更多