Python爬虫:python2使用scrapy输出unicode乱码

简介: Python爬虫:python2使用scrapy输出unicode乱码

无力吐槽的python2,对中文太不友好了,不过在早期项目中还是需要用到


没办法,还是需要解决


我编写scrapy爬虫的一般思路:


创建spider文件和类

编写parse解析函数,抓取测试,将有用信息输出到控制台

在数据库中创建数据表

编写item

编写model(配合pipline将item写入数据库)

编写pipline

运行爬虫项目,测试保存的数据正确性

在第2步抓取测试的时候,我并没有创建数据库(因为我感觉在数据库中创建数据表比较麻烦,考虑的因素比较多),并不能保存数据到数据库,直接输出到控制台又不能很好地看到数据的整体效果


一个解决办法就是利用scrapy提供的数据导出中间件,将抓取的数据导出到json或者scv文件中


$ scrapy crawl spider_name -o person.json

额,python2。。。我的天,抓取的数据大概是这样的

[
{"name": "\u5f20\u4e39"},
{"name": "\u77bf\u6653\u94e7"},
{"name": "\u95eb\u5927\u9e4f"},
{"name": "\u9c8d\u6d77\u660e"},
{"name": "\u9648\u53cb\u658c"},
{"name": "\u9648\u5efa\u5cf0"}
]

好吧,英文能看懂,中文反而看不懂了,简直不能忍


接下来对它做点什么


1、找到scrapy默认配置文件


# scrapy.settings.default_settings
FEED_EXPORTERS_BASE = {
    'json': 'scrapy.exporters.JsonItemExporter',
    'jsonlines': 'scrapy.exporters.JsonLinesItemExporter',
    'jl': 'scrapy.exporters.JsonLinesItemExporter',
    'csv': 'scrapy.exporters.CsvItemExporter',
    'xml': 'scrapy.exporters.XmlItemExporter',
    'marshal': 'scrapy.exporters.MarshalItemExporter',
    'pickle': 'scrapy.exporters.PickleItemExporter',
}

2、看到json的导出类,按照路径找到这个类

# scrapy.exporters.JsonItemExporter
class JsonItemExporter(BaseItemExporter):
    def __init__(self, file, **kwargs):
        self._configure(kwargs, dont_fail=True)
        self.file = file
        self.encoder = ScrapyJSONEncoder(**kwargs)
        self.first_item = True
    def start_exporting(self):
        self.file.write(b"[\n")
    def finish_exporting(self):
        self.file.write(b"\n]")
    def export_item(self, item):
        if self.first_item:
            self.first_item = False
        else:
            self.file.write(b',\n')
        itemdict = dict(self._get_serialized_fields(item))
        self.file.write(to_bytes(self.encoder.encode(itemdict)))

看到最下面一句,写入文件,后面还对其进行了编码,我们就在这里做工作


3、改写JsonItemExporter

方法1:

import json
class MyJsonItemExporter(JsonItemExporter):
    def export_item(self, item):
        if self.first_item:
            self.first_item = False
        else:
            self.file.write(b',\n')
        itemdict = dict(self._get_serialized_fields(item))
        self.file.write(json.dumps(itemdict, ensure_ascii=False))

继承原有的JsonItemExporter类,将最下面的写入文件代码修改即可,这种方式比较直观,也比较简单


方式2:

我们注意到JsonItemExporter中的初始化函数有一个属性


self.encoder = ScrapyJSONEncoder(**kwargs)

下面写入的时候也用到了,顺藤摸瓜,依次找到下面两个类,部分代码省略

class ScrapyJSONEncoder(json.JSONEncoder):
    pass
class JSONEncoder(object):
    def __init__(self, skipkeys=False, ensure_ascii=True,
            check_circular=True, allow_nan=True, sort_keys=False,
            indent=None, separators=None, encoding='utf-8', default=None):

这样看来,我们也可以这么改写

class MyJsonItemExporter(JsonItemExporter):
    def __init__(self, file, **kwargs):
        super(MyJsonItemExporter, self).__init__(
            file, ensure_ascii=False, **kwargs
        )

仅仅只是添加了ensure_ascii=False, 这样看起来,逼格就高了许多


4、使用MyJsonItemExporter

可以在爬虫中单独设置,也可以设置在全局settings里边

custom_settings = {
    "FEED_EXPORTERS_BASE":{
            "json": "MyJsonItemExporter"
    }
}

再次运行爬虫,这次我能看懂中文了


[
{"name": "张丹"},
{"name": "闫大鹏"},
{"name": "瞿晓铧"},
{"name": "鲍海明"},
{"name": "陈友斌"},
{"name": "陈建峰"}
]
相关文章
|
8天前
|
数据采集 JavaScript 前端开发
构建你的首个Python网络爬虫
【9月更文挑战第8天】本文将引导你从零开始,一步步构建属于自己的Python网络爬虫。我们将通过实际的代码示例和详细的步骤解释,让你理解网络爬虫的工作原理,并学会如何使用Python编写简单的网络爬虫。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你打开网络数据获取的新世界。
|
8天前
|
数据采集 机器学习/深度学习 搜索推荐
Python爬虫技术基础与应用场景详解
本文介绍了爬虫技术的基本概念、原理及应用场景,包括数据收集、价格监测、竞品分析和搜索引擎优化等。通过一个实战案例展示了如何使用Python爬取电商网站的商品信息。强调了在使用爬虫技术时需遵守法律法规和道德规范,确保数据抓取的合法性和合规性。
|
11天前
|
数据采集 JavaScript 前端开发
打造你的Python爬虫:从基础到进阶
【9月更文挑战第5天】在数字信息泛滥的时代,掌握一项技能能让我们更好地筛选和利用这些资源。本文将带你了解如何用Python构建一个基本的网页爬虫,进而拓展到更复杂的数据抓取任务。无论你是编程新手还是有一定经验的开发者,跟随这篇文章的步伐,你将能够实现自动化获取网络数据的目标。准备好了吗?让我们一起潜入代码的世界,解锁新的可能!
WK
|
15天前
|
数据采集 XML 安全
常用的Python网络爬虫库有哪些?
Python网络爬虫库种类丰富,各具特色。`requests` 和 `urllib` 简化了 HTTP 请求,`urllib3` 提供了线程安全的连接池,`httplib2` 则具备全面的客户端接口。异步库 `aiohttp` 可大幅提升数据抓取效率。
WK
34 1
|
16天前
|
数据采集 JavaScript 前端开发
构建简易Python爬虫:抓取网页数据入门指南
【8月更文挑战第31天】在数字信息的时代,数据抓取成为获取网络资源的重要手段。本文将引导你通过Python编写一个简单的网页爬虫,从零基础到实现数据抓取的全过程。我们将一起探索如何利用Python的requests库进行网络请求,使用BeautifulSoup库解析HTML文档,并最终提取出有价值的数据。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你打开数据抓取的大门。
|
17天前
|
数据采集 存储 数据库
构建你的第一个Python爬虫:从入门到实践
【8月更文挑战第31天】在数字时代的浪潮中,数据如同新时代的石油,而网络爬虫则是开采这些数据的钻头。本文将引导初学者了解并实现一个基础的网络爬虫,使用Python语言,通过实际代码示例,展示如何收集和解析网页信息。我们将一起探索HTTP请求、HTML解析以及数据存储等核心概念,让你能够快速上手并运行你的首个爬虫项目。
|
16天前
|
数据采集 存储 JavaScript
Python 爬虫实战:从入门到精通
【8月更文挑战第31天】 本文将带你走进 Python 爬虫的世界,从基础的请求和解析开始,逐步深入到反爬策略的应对和数据存储。我们将通过实际案例,一步步构建一个功能完整的爬虫项目。无论你是编程新手还是有一定经验的开发者,都能在这篇文章中找到适合自己的学习路径。让我们一起探索数据的海洋,揭开网络信息的神秘面纱。
|
17天前
|
数据采集 存储 JavaScript
Python 爬虫实战:从入门到精通
【8月更文挑战第31天】 本文将带你走进 Python 爬虫的世界,从基础的请求和解析开始,逐步深入到反爬策略的应对和数据存储。我们将通过实际案例,一步步构建一个功能完整的爬虫项目。无论你是编程新手还是有一定经验的开发者,都能在这篇文章中找到适合自己的学习路径。让我们一起探索数据的海洋,揭开网络信息的神秘面纱。
|
17天前
|
数据采集 存储 数据库
Python中实现简单爬虫与数据解析
【8月更文挑战第31天】在数字化时代的浪潮中,数据成为了新的石油。本文将带领读者通过Python编程语言,从零开始构建一个简单的网络爬虫,并展示如何对爬取的数据进行解析和处理。我们将一起探索请求网站、解析HTML以及存储数据的基础知识,让每个人都能成为自己数据故事的讲述者。
|
17天前
|
数据采集 JavaScript 前端开发
构建你的第一个Python爬虫:抓取网页数据入门指南
【8月更文挑战第31天】在数字时代,数据是新的石油。本文将引导初学者通过简单的步骤,使用Python编程语言创建一个基础的网络爬虫程序。我们将探索如何从网络上提取信息,并理解背后的原理。无论你是编程新手还是想要扩展你的技术工具箱,这篇文章都将为你提供一条清晰的道路,让你学会编写能够自动获取网络数据的脚本。准备好开始你的网络数据抓取之旅了吗?让我们现在就开始吧!