scrapy 实战练习

Scrapy publisher01 46℃

爬取百思不得姐

首先一步一步来,我们先从爬最简单的文本开始。这里爬取的就是百思不得姐的的段子,都是文本。

首先打开段子页面,用F12工具查看元素。然后用下面的命令打开scrapy shell。

scrapy shell http://www.budejie.com/text/

稍加分析即可得到我们要获取的数据,在介绍scrapy的第一篇文章中我就写过一次了。这次就给上次那个爬虫加上一个翻页功能。

要获取的是用户名和对应的段子,所以在items.py中新建一个类。

class BudejieItem(scrapy.Item):
    username = scrapy.Field()
    content = scrapy.Field()

爬虫本体就这样写,唯一需要注意的就是段子可能分为好几行,这里我们要统一合并成一个大字符串。选择器的extract()方法默认会返回一个列表,哪怕数据只有一个也是这样。所以如果数据是单个的,使用extract_first()方法。

import scrapy
from scrapy_sample.items import BudejieItem
class BudejieSpider(scrapy.Spider):
    """百思不得姐段子的爬虫"""
    name = 'budejie'
    start_urls = ['http://www.budejie.com/text/']
    total_page = 1
    def parse(self, response):
        current_page = int(response.css('a.z-crt::text').extract_first())
        lies = response.css('div.j-r-list >ul >li')
        for li in lies:
            username = li.css('a.u-user-name::text').extract_first()
            content = '\n'.join(li.css('div.j-r-list-c-desc a::text').extract())
            yield BudejieItem(username=username, content=content)
        if current_page < self.total_page:
            yield scrapy.Request(self.start_urls[0] + f'{current_page+1}')

导出到文件

利用scrapy内置的Feed功能,我们可以非常方便的将爬虫数据导出为XML、JSON和CSV等格式的文件。要做的只需要在运行scrapy的时候用-o参数指定导出文件名即可。

scrapy crawl budejie -o f.json
scrapy crawl budejie -o f.csv
scrapy crawl budejie -o f.xml

如果出现导出汉字变成Unicode编码的话,需要在配置中设置导出编码。

FEED_EXPORT_ENCODING = 'utf-8'

保存到MongoDB

有时候爬出来的数据并不想放到文件中,而是存在数据库中。这时候就需要编写管道来处理数据了。一般情况下,爬虫只管爬取数据,数据是否重复是否有效都不是爬虫要关心的事情。清洗数据、验证数据、保存数据这些活,都应该交给管道来处理。当然爬个段子的话,肯定是用不到清洗数据这些步骤的。这里用的是pymongo,所以首先需要安装它。

pip install pymongo

代码其实很简单,用scrapy官方文档的例子稍微改一下就行了。由于MongoDB的特性,所以这部分代码几乎是无缝迁移的,如果希望保存其他数据,只需要改一下配置就可以了,其余代码部分几乎不需要更改。

import pymongo
class BudejieMongoPipeline(object):
    "将百思不得姐段子保存到MongoDB中"
    collection_name = 'jokes'
    def __init__(self, mongo_uri, mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db
    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            mongo_uri=crawler.settings.get('MONGO_URI'),
            mongo_db=crawler.settings.get('MONGO_DATABASE', 'budejie')
        )
    def open_spider(self, spider):
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]
    def close_spider(self, spider):
        self.client.close()
    def process_item(self, item, spider):
        self.db[self.collection_name].insert_one(dict(item))
        return item

这个管道需要从配置文件中读取数据库信息,所以还需要在settings.py中增加以下几行。别忘了在ITEM_PIPELINES中吧我们的管道加进去。

转载请注明:Python量化投资 » scrapy 实战练习

喜欢 (0)or分享 (0)