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": "陈建峰"}
]
相关文章
|
5天前
|
数据采集 存储 开发者
如何动态调整Python爬虫的Request请求延迟
如何动态调整Python爬虫的Request请求延迟
|
12天前
|
数据采集 前端开发 JavaScript
Scrapy结合Selenium实现搜索点击爬虫的最佳实践
Scrapy结合Selenium实现搜索点击爬虫的最佳实践
|
2天前
|
数据采集 NoSQL 关系型数据库
Python爬虫去重策略:增量爬取与历史数据比对
Python爬虫去重策略:增量爬取与历史数据比对
|
5天前
|
数据采集 存储 缓存
Python爬虫与代理IP:高效抓取数据的实战指南
在数据驱动的时代,网络爬虫是获取信息的重要工具。本文详解如何用Python结合代理IP抓取数据:从基础概念(爬虫原理与代理作用)到环境搭建(核心库与代理选择),再到实战步骤(单线程、多线程及Scrapy框架应用)。同时探讨反爬策略、数据处理与存储,并强调伦理与法律边界。最后分享性能优化技巧,助您高效抓取公开数据,实现技术与伦理的平衡。
30 4
|
4天前
|
数据采集 Web App开发 iOS开发
Python 爬虫如何伪装 Referer?从随机生成到动态匹配
Python 爬虫如何伪装 Referer?从随机生成到动态匹配
|
9天前
|
数据采集 Web App开发 文字识别
Python爬虫多次请求后被要求验证码的应对策略
Python爬虫多次请求后被要求验证码的应对策略
|
15天前
|
数据采集 搜索推荐 API
Python 原生爬虫教程:京东商品列表页面数据API
京东商品列表API是电商大数据分析的重要工具,支持开发者、商家和研究人员获取京东平台商品数据。通过关键词搜索、分类筛选、价格区间等条件,可返回多维度商品信息(如名称、价格、销量等),适用于市场调研与推荐系统开发。本文介绍其功能并提供Python请求示例。接口采用HTTP GET/POST方式,支持分页、排序等功能,满足多样化数据需求。
|
17天前
|
数据采集 存储 JSON
用Python爬虫抓取数据并保存为JSON的完整指南
用Python爬虫抓取数据并保存为JSON的完整指南
|
18天前
|
数据采集 存储 NoSQL
如何避免Python爬虫重复抓取相同页面?
如何避免Python爬虫重复抓取相同页面?
|
15天前
|
数据采集 API 数据格式
Python 原生爬虫教程:京东商品详情页面数据API
本文介绍京东商品详情API在电商领域的应用价值及功能。该API通过商品ID获取详细信息,如基本信息、价格、库存、描述和用户评价等,支持HTTP请求(GET/POST),返回JSON或XML格式数据。对于商家优化策略、开发者构建应用(如比价网站)以及消费者快速了解商品均有重要意义。研究此API有助于推动电商业务创新与发展。
下一篇
oss创建bucket