Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何避免JSON百分比编码和\u转义?_Python_Json_Unicode_Scrapy - Fatal编程技术网

Python 如何避免JSON百分比编码和\u转义?

Python 如何避免JSON百分比编码和\u转义?,python,json,unicode,scrapy,Python,Json,Unicode,Scrapy,当我解析文件时 <html> <head><meta charset="UTF-8"></head> <body><a href="Düsseldorf.html">Düsseldorf</a></body> </html> 我以\u转义结束 [{ "name": "D\u00fcsseldorf", "url": "D\u00fcsseldorf.htm

当我解析文件时

<html>
    <head><meta charset="UTF-8"></head>
    <body><a href="Düsseldorf.html">Düsseldorf</a></body>
</html>
我以
\u
转义结束

[{
    "name": "D\u00fcsseldorf",
    "url": "D\u00fcsseldorf.html"
}]
或使用百分比编码字符串

D%C3%BCsseldorf
描述的

以及相应的提要导出器设置

FEED_EXPORTERS = {
    'json': 'myproj.exporter.UnicodeJsonLinesItemExporter',
}
不要帮忙

如何获得utf-8编码的JSON输出

我在重申/扩展一个新的目标

更新

与刮屑正交,注意无需设置

export PYTHONIOENCODING="utf_8"
运行

> echo { \"name\": \"Düsseldorf\", \"url\": \"Düsseldorf.html\" } > dorf.json
> python -c'import fileinput, json;print json.dumps(json.loads("".join(fileinput.input())),sort_keys=True, indent=4, ensure_ascii=False)' dorf.json > dorf_pp.json
将以失败告终

Traceback (most recent call last):
  File "<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 16: ordinal not in range(128)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
UnicodeEncodeError:“ascii”编解码器无法对位置16中的字符u'\xfc'进行编码:序号不在范围内(128)
更新


我的问题无法回答。UnicodeJsonLinesItemExporter可以工作,但管道的另一部分是罪魁祸首:作为漂亮打印JSON输出的后处理,我使用了
python-mjson.tool in.JSON>out.JSON

这似乎对我来说很有效

>>> a = [{
    "name": "D\u00fcsseldorf",
    "url": "D\u00fcsseldorf.html"
}]
>>> a
[{'url': 'Düsseldorf.html', 'name': 'Düsseldorf'}]
>>> json.dumps(a, ensure_ascii=False)
'[{"url": "Düsseldorf.html", "name": "Düsseldorf"}]'
# -*- coding: utf-8 -*-
import scrapy
import urllib

class SimpleItem(scrapy.Item):
    name = scrapy.Field()
    url = scrapy.Field()

class CitiesSpider(scrapy.Spider):
    name = "cities"
    allowed_domains = ["sitercity.info"]
    start_urls = (
        'http://en.sistercity.info/countries/de.html',
    )

    def parse(self, response):
        for a in response.css('a'):
            item = SimpleItem()
            item['name'] = a.css('::text').extract_first()
            item['url'] = urllib.unquote(
                a.css('::attr(href)').extract_first().encode('ascii')
                ).decode('utf8')
            yield item
使用您问题中引用的提要导出器,它也可以使用另一个存储

# -*- coding: utf-8 -*-
import json
import io
import os
from scrapy.contrib.exporter import BaseItemExporter
from w3lib.url import file_uri_to_path

class CustomFileFeedStorage(object):

    def __init__(self, uri):
        self.path = file_uri_to_path(uri)

    def open(self, spider):
        dirname = os.path.dirname(self.path)
        if dirname and not os.path.exists(dirname):
            os.makedirs(dirname)
        return io.open(self.path, mode='ab')

    def store(self, file):
        file.close()

class UnicodeJsonLinesItemExporter(BaseItemExporter):

    def __init__(self, file, **kwargs):
        self._configure(kwargs)
        self.file = file
        self.encoder = json.JSONEncoder(ensure_ascii=False, **kwargs)

    def export_item(self, item):
        itemdict = dict(self._get_serialized_fields(item))
        self.file.write(self.encoder.encode(itemdict) + '\n')
(必要时删除注释)


这似乎对我有用

# -*- coding: utf-8 -*-
import scrapy
import urllib

class SimpleItem(scrapy.Item):
    name = scrapy.Field()
    url = scrapy.Field()

class CitiesSpider(scrapy.Spider):
    name = "cities"
    allowed_domains = ["sitercity.info"]
    start_urls = (
        'http://en.sistercity.info/countries/de.html',
    )

    def parse(self, response):
        for a in response.css('a'):
            item = SimpleItem()
            item['name'] = a.css('::text').extract_first()
            item['url'] = urllib.unquote(
                a.css('::attr(href)').extract_first().encode('ascii')
                ).decode('utf8')
            yield item
使用您问题中引用的提要导出器,它也可以使用另一个存储

# -*- coding: utf-8 -*-
import json
import io
import os
from scrapy.contrib.exporter import BaseItemExporter
from w3lib.url import file_uri_to_path

class CustomFileFeedStorage(object):

    def __init__(self, uri):
        self.path = file_uri_to_path(uri)

    def open(self, spider):
        dirname = os.path.dirname(self.path)
        if dirname and not os.path.exists(dirname):
            os.makedirs(dirname)
        return io.open(self.path, mode='ab')

    def store(self, file):
        file.close()

class UnicodeJsonLinesItemExporter(BaseItemExporter):

    def __init__(self, file, **kwargs):
        self._configure(kwargs)
        self.file = file
        self.encoder = json.JSONEncoder(ensure_ascii=False, **kwargs)

    def export_item(self, item):
        itemdict = dict(self._get_serialized_fields(item))
        self.file.write(self.encoder.encode(itemdict) + '\n')
(必要时删除注释)


这似乎确实是一种方式,正如你在问题中看到的那样,它已经被纳入到物品出口商中。为什么输出仍然是U编码和百分比编码字符串的混合?我会考虑包括<代码> URLLIB。PARSE。你能举一个例子,其中既有\u编码的字符串,也有百分比编码的字符串吗?我已经尝试在项目导出器的
export\u item
中使用
urlib.parse.unquote
。这个框架的问题是有太多的代码层和钩子,所以不清楚如何获得一些简单的工作。这似乎确实是一种方式,并且它已经包含在项目导出器中,正如您在问题中看到的。为什么输出仍然是U编码和百分比编码字符串的混合?我会考虑包括<代码> URLLIB。PARSE。你能举一个例子,其中既有\u编码的字符串,也有百分比编码的字符串吗?我已经尝试在项目导出器的
export\u item
中使用
urlib.parse.unquote
。这个框架的问题在于有太多的代码层和钩子,所以不清楚如何获得一些简单的工作方式。Scrapy 1.2(尚未发布)将有一个
FEED\u EXPORT\u ENCODING
设置选项:请参阅。同时,您可以使用Scrapy的主分支。还有一个实现:Scrapy 1.2(尚未发布)将有一个
FEED\u EXPORT\u ENCODING
设置选项来执行以下操作:请参阅。同时,您可以使用scrapyThere的主分支也有这样的实现:行
a.css('::attr(href)).extract_first().encode('ascii')
(第一个解决方案)给出了
UnicodeCodeerror:'ascii'编解码器无法对位置1的字符u'\xfc'进行编码:序号不在范围内(128)
。自定义提要
CustomFileFeedStorage
不会出现在
feed\u STORAGES
挂钩中。你把它挂起来了吗?是的,请删除注释部分,你能添加一个示例url来复制你的错误吗?为了最大程度地再现性,我正在使用一个本地文件(我通过
file:///path/to/file.html
)。我就是这样开始提问的。现在,这一切都很好,尽管在使用envvar设置时遇到了困难(
PYTHONIOENCODING
LC\u ALL
LANG
似乎需要使用默认设置以外的设置)。当我使用
http://domain
URL,几乎相同的文件集失败。有些神秘的东西潜伏着。这就好像整个可用的工具链(在最近的OS X/MacPorts安装上)被不支持unicode的部分污染了一样。好笑。。我只是跳过了代码中注释掉的行。现在我明白了为什么要保留
CustomFileFeedStorage
的代码了。行
a.css('::attr(href)').extract_first().encode('ascii')
(第一种解决方案)给我提供了
UnicodeEncodeError:'ascii'编解码器无法在位置1对字符u'\xfc'进行编码:序号不在范围内(128)
。自定义提要
CustomFileFeedStorage
不会出现在
feed\u STORAGES
挂钩中。你把它挂起来了吗?是的,请删除注释部分,你能添加一个示例url来复制你的错误吗?为了最大程度地再现性,我正在使用一个本地文件(我通过
file:///path/to/file.html
)。我就是这样开始提问的。现在,这一切都很好,尽管在使用envvar设置时遇到了困难(
PYTHONIOENCODING
LC\u ALL
LANG
似乎需要使用默认设置以外的设置)。当我使用
http://domain
URL,几乎相同的文件集失败。有些神秘的东西潜伏着。这就好像整个可用的工具链(在最近的OS X/MacPorts安装上)被不支持unicode的部分污染了一样。好笑。。我只是跳过了代码中注释掉的行。现在我明白你为什么保留
CustomFileFeedStorage
的代码了。
FEED_EXPORTERS = {
    'json': 'myproj.exporter.UnicodeJsonLinesItemExporter'
}
#FEED_STORAGES = {
#   '': 'myproj.exporter.CustomFileFeedStorage'
#}
FEED_FORMAT = 'json'
FEED_URI = "out.json"