Python-爬虫(六)scrapy快速入门案例-爬取糗事百科

目录

 

一:安装

二:快速入门

三:开始爬取

 四:存储数据

优化导出数据方式


一:安装

window环境通过命令行安装: pip install scrapy

在winodw下使用这个框架还要安装一个它依赖的包,不然运行的时候会报错: pip install pypiwin32

二:快速入门

安装成功之后可以通过:scrapy  命令查看相关命令。

我们使用startproject命令创建一个新项目。: scrapy startproject first_start

用pycharm打开这个项目看下生成的目录。

项目创建好之后,我们开始创建一个爬虫。创建一个爬虫需要用到一个命令: genspider

进入我们项目的spiders目录下用命令行创建: scrapy genspider  qiushibaike  "qiushibaike.com"

qiushibaike  ---爬虫的名字    qiushibaike.com---爬虫需要的域名

自动创建的内容:

开始之前先设置一些东西。

1)settings.py中设置:

我们解释下自动生成的py文件中的一些数据的作用。

我们运行爬虫也是要命令行,进入到spiders目录下面执行:scrapy crawl qiushibaike--自定义爬虫的名字

我们主要使用response对象来过滤xpath。我们看下

返回的是个SelectorList类型。它是可以遍历,并且可以继续使用xpath函数进行提取的。

但是使用命令行执行爬虫不是很方便,我们可以使用python文件来启动。在项目的根目录下创建一个新文件,在里面使用:

from scrapy import cmdline
#传入我们的启动命令
cmdline.execute("scrapy crawl qiushibaike".split())

后面我们可以直接运行这个文件就可以启动爬虫程序了。 

三:开始爬取

我们看到页面内容:

可以根据class='recmd-right'来定位

 我们来得到作者:

分析页面,可以知道,在上面我们得到div之后,在div下面的span标签内存着作者,所以通过如下方式获取。

    def parse(self, response):
        # response是一个HtmlResponse对象,可以用它获取返回的内容response.text,使用xpath获取内容response.xpath("..")
        print("*************************")
        responseContent = response.xpath("//div[@class='recmd-right']")

        for i in responseContent:
            print(i.xpath(".//span[@class='recmd-name']/text()").get())
        print("******************************")

 四:存储数据

我们现在试着把爬取到的内容存储到json文件。scrapy中爬取和存储是分开两个模块处理。我们的爬取程序是在spiders下面,但是对爬取下来的数据处理是在pipelines中的。

首页我们需要把在spiders中把爬取的数据yield出去,然后在pipelines中接收处理。

spiders中:

注意我们这里使用yield,也可以把所有的数据都准备好之后直接return出来。

    def parse(self, response):
        # response是一个HtmlResponse对象,可以用它获取返回的内容response.text,使用xpath获取内容response.xpath("..")
        print("*************************")
        responseContent = response.xpath("//div[@class='recmd-right']")

        for i in responseContent:
            author=i.xpath(".//span[@class='recmd-name']/text()").get()
            title=i.xpath(".//a[@class='recmd-content']/text()").get()
            #把数据转为字典
            data={"author": author,"title":title}
            #把数据转给pipelines,需要使用 yield,  代表把数据转给底层框架,然后框架会转给pipelines.py文件中
            yield data

pipelines中:
 

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
import json

class FirstProjectPipeline:

    #初始化函数,打开一个文件,也可以在open_spider方法中
    def __init__(self):
         self.fp=open("data.json","w",encoding="utf-8")

     #爬虫程序启动的时候执行这个函数
    def open_spider(self,spider):
        print('爬虫开始')
     #我们在spiders中yield 的数据 会传递给 item这个参数,然后执行process_item中的逻辑
    def process_item(self, item, spider):
        #在spider中yield是个字典型数据  我们转成json  dumps不需要文件参数,ensure_ascii关闭掉可以存储中文
        item_json=json.dumps(item,ensure_ascii=False)
        self.fp.write(item_json+'\n')
        return item
     #这个爬虫程序执行完成之后执行的方法
    def close_spider(self,spider):
        print('爬虫结束')

但是要让pipelines生效配置文件中还要有个内容放开注释:

默认是注释掉的。

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
    #key是类路径,value是优先级,越小优先级越高
   'first_project.pipelines.FirstProjectPipeline': 300,
}

运行程序看到出来的json文件:


上面我们是在爬虫程序里返回是个字典型数据给pipelines的,但是在scrapy中有更专业的写法,就是用包装类。

首先我们要在items.py中定义包装数据的类,items.py中就是专门放这些包装类的。

item.py:
 

import scrapy


class FirstProjectItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    author=scrapy.Field()
    title=scrapy.Field()

在spiders中引入使用:

注意引入的方式,从我们的项目名下的item引入。

from first_project.items import FirstProjectItem

 def parse(self, response):
        # response是一个HtmlResponse对象,可以用它获取返回的内容response.text,使用xpath获取内容response.xpath("..")
        print("*************************")
        responseContent = response.xpath("//div[@class='recmd-right']")

        for i in responseContent:
            author=i.xpath(".//span[@class='recmd-name']/text()").get()
            title=i.xpath(".//a[@class='recmd-content']/text()").get()
            #把数据转为字典
            # data={"author": author,"title":title}
            data=FirstProjectItem(author=author,title=title)
            #把数据转给pipelines,需要使用 yield,  代表把数据转给底层框架,然后框架会转给pipelines.py文件中
            yield data

 pipelines中我们要稍微改动下,因为传入的是个对象,我们存入json文件的时候,转为字典。

 def process_item(self, item, spider):
        #在spider中yield是个字典型数据  我们转成json  dumps不需要文件参数,ensure_ascii关闭掉可以存储中文
        item_json=json.dumps(dict(item),ensure_ascii=False)
        self.fp.write(item_json+'\n')
        return item

这样就可以继续使用了。

优化导出数据方式

上面我们使用Json来导出爬取的数据,还要转换为字典型,不太方便,其实scrapy中给我们提供的有导出器可以使用更方便数据导出。

pipelines中的代码改为如下内容:
 


# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
#引入Json导出器
from scrapy.exporters import  JsonItemExporter

class FirstProjectPipeline:

    #初始化函数,打开一个文件,也可以在open_spider方法中
    def __init__(self):
        #同样时打开一个文件,但是这里要以wb字节的形式打开,因为导出器是处理字节数据的而且不用指定编码格式
         self.fp=open("data.json","wb")
        #传入上面定义的文件对象,禁用ascii码  使用utf-8编码
         self.export=JsonItemExporter(self.fp,ensure_ascii=False,encoding='utf-8')
        #开启导出
         self.export.start_exporting()
     #爬虫程序启动的时候执行这个函数
    def open_spider(self,spider):
        print('爬虫开始')
     #我们在spiders中yield 的数据 会传递给 item这个参数,然后执行process_item中的逻辑
    def process_item(self, item, spider):

        #爬虫哪里得到的item可以直接使用,不用转换为字典
        self.export.export_item(item)
        return item
     #这个爬虫程序执行完成之后执行的方法
    def close_spider(self,spider):
        # 完成导入之后关闭导出器,才会真正的写入文件中取,存入文件的内容为一个列表,列表里是一个个字典
        self.export.finish_exporting()
        print('爬虫结束')

内容:

这种方式是会把爬取到的内容都先在内存中存储一个列表中,列表中存储爬取的item,最后在写入文件中,如果爬取的内容很多,会很占内存。

还有一种导出方式,按行来导出,而不是占用内存最后再导出。

#引入Json导出器
from scrapy.exporters import  JsonLinesItemExporter

class FirstProjectPipeline:

    #初始化函数,打开一个文件,也可以在open_spider方法中
    def __init__(self):
        #同样时打开一个文件,但是这里要以wb字节的形式打开,因为导出器是处理字节数据的而且不用指定编码格式
         self.fp=open("data.json","wb")
        #传入上面定义的文件对象,禁用ascii码  使用utf-8编码
         self.export=JsonLinesItemExporter(self.fp,ensure_ascii=False,encoding='utf-8')

     #爬虫程序启动的时候执行这个函数
    def open_spider(self,spider):
        print('爬虫开始')
     #我们在spiders中yield 的数据 会传递给 item这个参数,然后执行process_item中的逻辑
    def process_item(self, item, spider):

        #爬虫哪里得到的item可以直接使用,不用转换为字典
        self.export.export_item(item)
        return item
     #这个爬虫程序执行完成之后执行的方法
    def close_spider(self,spider):
       
        print('爬虫结束')

导入内容:

一个字典占用一行,而不是一个列表了。数量大的时候可以使用这个方式,而且不用start,和finish了。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姑苏冷

您的打赏是对原创文章最大的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值