2012-02-07 37 views
22

Đây là nhện của tôiscrapy văn bản mã hóa

from scrapy.contrib.spiders import CrawlSpider,Rule 
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor 
from scrapy.selector import HtmlXPathSelector 
from vrisko.items import VriskoItem 

class vriskoSpider(CrawlSpider): 
    name = 'vrisko' 
    allowed_domains = ['vrisko.gr'] 
    start_urls = ['http://www.vrisko.gr/search/%CE%B3%CE%B9%CE%B1%CF%84%CF%81%CE%BF%CF%82/%CE%BA%CE%BF%CF%81%CE%B4%CE%B5%CE%BB%CE%B9%CE%BF'] 
    rules = (Rule(SgmlLinkExtractor(allow=('\?page=\d')),'parse_start_url',follow=True),) 

    def parse_start_url(self, response): 
     hxs = HtmlXPathSelector(response) 
     vriskoit = VriskoItem() 
     vriskoit['eponimia'] = hxs.select("//a[@itemprop='name']/text()").extract() 
     vriskoit['address'] = hxs.select("//div[@class='results_address_class']/text()").extract() 
     return vriskoit 

Vấn đề của tôi là chuỗi trả về là unicode và tôi muốn để mã hóa chúng để utf-8. Tôi không biết đó là cách tốt nhất để làm điều này. Tôi đã thử nhiều cách mà không có kết quả.

Cảm ơn bạn trước!

Trả lời

32

Chuỗi trả về bị lơ lửng trong unicode, chứ không phải ascii. Để mã hóa tất cả các chuỗi để utf-8, bạn có thể viết:

vriskoit['eponimia'] = [s.encode('utf-8') for s in hxs.select('//a[@itemprop="name"]/text()').extract()] 

Nhưng tôi nghĩ rằng bạn mong đợi một kết quả khác. Mã của bạn trả lại một mục có tất cả kết quả tìm kiếm. Để trở về mục cho mỗi kết quả:

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 

Cập nhật

JSON xuất khẩu viết ký tự unicode thoát (ví dụ \u03a4) theo mặc định, bởi vì không phải tất cả các dòng có thể xử lý unicode. Nó có tùy chọn để viết chúng dưới dạng unicode ensure_ascii=False (xem tài liệu cho json.dumps). Nhưng tôi không thể tìm cách chuyển tùy chọn này đến nhà xuất khẩu nguồn cấp dữ liệu tiêu chuẩn.

Vì vậy, nếu bạn muốn các mục được xuất sẽ được viết bằng mã hóa utf-8, ví dụ: để đọc chúng trong trình soạn thảo văn bản, bạn có thể viết đường dẫn mục tùy chỉnh.

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() 

Đừng quên thêm đường ống này để settings.py:

ITEM_PIPELINES = ['vrisko.pipelines.JsonWithEncodingPipeline'] 

Bạn có thể tùy chỉnh đường ống để ghi dữ liệu ở định dạng có thể đọc được con người hơn, ví dụ bạn có thể tạo một số báo cáo được định dạng. JsonWithEncodingPipeline chỉ là ví dụ cơ bản.

+0

tôi đã làm những gì bạn đã viết, nhưng tôi vẫn nhận được kết quả tương tự: các ký tự unicode. Cách duy nhất để có được utf-8, là sử dụng in vrisko ['eponimia'] thay vì thu nhập hoặc trả lại. – mindcast

+0

@mindcast, Bạn đã tải nó ở đâu? Bạn làm gì với các mục (lưu vào nguồn cấp dữ liệu json, nguồn cấp dữ liệu csv hoặc có thể là đường dẫn tùy chỉnh)? – reclosedev

+0

thu thập dữ liệu cặn bã vrisko -o scraped_data.json -t json hoặc thậm chí thu thập dữ liệu vrisko và xem kết quả trên màn hình của tôi. Tôi biết tôi nhớ một cái gì đó nhưng tôi không thể tìm ra nó. Cảm ơn bạn đã nỗ lực của bạn. – mindcast

4

Tôi gặp nhiều vấn đề do mã hóa bằng python và scrapy. Để chắc chắn để tránh tất cả các vấn đề mã hóa giải mã, điều tốt nhất để làm là viết:

unicode(response.body.decode(response.encoding)).encode('utf-8') 
1

Tôi tìm thấy một cách đơn giản để làm điều đó. Nó tiết kiệm dữ liệu json để 'SpiderName'.json với '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 
0

Như đã đề cập trước đó, JSON xuất khẩu viết ký tự unicode thoát và nó có tùy chọn để viết chúng như unicode ensure_ascii=False.

Để xuất các mặt hàng trong utf-8 mã hóa, bạn có thể thêm video này vào tập tin settings.py của dự án của bạn:

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', 
} 

Sau đó chạy:

scrapy crawl spider_name -o output.jl 
34

Kể từ Scrapy 1.2.0, a new setting FEED_EXPORT_ENCODING is introduced. Bằng cách chỉ định nó là utf-8, đầu ra JSON sẽ không được thoát.

Đó là để thêm vào settings.py của bạn:

FEED_EXPORT_ENCODING = 'utf-8' 
+3

Đây là cách tốt nhất. cảm ơn bạn :) – Jalal

3

Câu trả lời đúng là Lacek câu trả lời, thêm vào các thiết lập của bạn:

FEED_EXPORT_ENCODING = 'utf-8'

Và thử lại, làm việc cho tôi.

0

Hãy thử thêm dòng sau vào file cấu hình cho Scrapy (ví dụ: settings.py):

FEED_EXPORT_ENCODING = 'utf-8' 
Các vấn đề liên quan