Если вам абсолютно нужна локальная копия файла, вам нужно будет открыть InputStream
копию содержимого в локальный файл, в котором вы знаете путь, а затем перейти оттуда. Sidenote: Guava ByteStreams#copy
- это простой способ выполнить это.
Конечно, этот файл больше не поддерживается исходным источником Uri, поэтому я не думаю, что это то, что вы хотите. Вместо этого вы должны работать с API-интерфейсом Uri. Взгляните на Storage Access Framework
Изменить
Вот как вы можете получить InputStream
из вашего Uri
InputStream inputStream = getContentResolver().openInputStream(uri);
Scrapy возвращает строки в юникоде, а не в ascii. Чтобы закодировать все строки в utf-8, вы можете написать:
vriskoit['eponimia'] = [s.encode('utf-8') for s in hxs.select('//a[@itemprop="name"]/text()').extract()]
Но я думаю, что вы ожидаете другого результата. Ваш код возвращает один элемент со всеми результатами поиска. Чтобы вернуть элементы для каждого результата:
hxs = HtmlXPathSelector(response)
for eponimia, address in zip(hxs.select("//a[@itemprop='name']/text()").extract(),
hxs.select("//div[@class='results_address_class']/text()").extract()):
vriskoit = VriskoItem()
vriskoit['eponimia'] = eponimia.encode('utf-8')
vriskoit['address'] = address.encode('utf-8')
yield vriskoit
Обновить
Экспортер JSON по умолчанию записывает экранированные символы Unicode (например, \u03a4
), поскольку не все Потоки могут обрабатывать Unicode. Он имеет возможность записать их как Unicode ensure_ascii=False
(см. Документы для json.dumps ). Но я не могу найти способ передать эту опцию стандартному экспортеру кормов.
Итак, если вы хотите, чтобы экспортированные элементы были записаны в кодировке utf-8
, например, для чтения их в текстовом редакторе вы можете написать собственный конвейер элементов.
pipelines.py:
import json
import codecs
class JsonWithEncodingPipeline(object):
def __init__(self):
self.file = codecs.open('scraped_data_utf8.json', 'w', encoding='utf-8')
def process_item(self, item, spider):
line = json.dumps(dict(item), ensure_ascii=False) + "\n"
self.file.write(line)
return item
def spider_closed(self, spider):
self.file.close()
Не забудьте добавить этот конвейер в settings.py:
ITEM_PIPELINES = ['vrisko.pipelines.JsonWithEncodingPipeline']
Вы можете настроить конвейер для записи данных в более удобочитаемом формате. например, Вы можете создать некоторый форматированный отчет. JsonWithEncodingPipeline
это просто базовый пример.
У меня было много проблем из-за кодирования с помощью python и scrapy. Чтобы избежать проблем кодирования, лучше всего написать:
unicode(response.body.decode(response.encoding)).encode('utf-8')
Попробуйте добавить следующую строку в файл конфигурации для Scrapy (например, settings.py ):
FEED_EXPORT_ENCODING = 'utf-8'
Начиная с Scrapy 1.2.0, вводится новая настройка FEED_EXPORT_ENCODING
. Указав его как utf-8
, вывод JSON не будет экранирован.
То есть добавить в ваш settings.py
:
FEED_EXPORT_ENCODING = 'utf-8'
Я нахожу простой способ сделать это. Он сохраняет данные json в 'SpiderName'.json с' utf8 '
from scrapy.exporters import JsonItemExporter
class JsonWithEncodingPipeline(object):
def __init__(self):
self.file = open(spider.name + '.json', 'wb')
self.exporter = JsonItemExporter(self.file, encoding='utf-8', ensure_ascii=False)
self.exporter.start_exporting()
def spider_closed(self, spider):
self.exporter.finish_exporting()
self.file.close()
def process_item(self, item, spider):
self.exporter.export_item(item)
return item
Как было упомянуто ранее, экспортер JSON записывает экранированные символы Unicode и имеет возможность записывать их как Unicode ensure_ascii=False
.
Чтобы экспортировать элементы в кодировке utf-8, вы можете добавить их в файл settings.py
вашего проекта:
from scrapy.exporters import JsonLinesItemExporter
class MyJsonLinesItemExporter(JsonLinesItemExporter):
def __init__(self, file, **kwargs):
super(MyJsonLinesItemExporter, self).__init__(file, ensure_ascii=False, **kwargs)
FEED_EXPORTERS = {
'jsonlines': 'yourproject.settings.MyJsonLinesItemExporter',
'jl': 'yourproject.settings.MyJsonLinesItemExporter',
}
Затем запустить:
scrapy crawl spider_name -o output.jl