初识 scrapy 框架

发布时间:2022-06-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了初识 scrapy 框架脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

在使用 scrapy 之前,我们先要用 pip 安装这个模块

pip install scrapy

安装好之后我们就可以建立爬虫项目了,在终端建立项目爬虫

scrapy startPRoject myspider

其中 myspider 是爬虫项目的名称

cd 进入这个项目

cd myspider

创建一个爬虫文件

scrapy genspider ITcast itcast.cn

其中 itcast 是爬虫的名字, itcast.cn 是允许爬虫爬取的域名

在 spiders 目录下我们可以找到这个爬虫文件 itcast.py ,在这个文件里面我们可以写我们的爬虫代码

import scrapy
From ..items import MyspiderItem


class ItcastSpider(scrapy.Spider):
    # 爬虫的名字
    name = 'itcast'
    # 允许爬虫爬取的域名范围
    Allowed_domains = ['itcast.cn']
    # 爬虫的起始 url
    start_urls = ['https://www.itcast.cn/channel/teacher.shtML#ajavaee']

    def parse(self, response, **kwargs):
        # 分组
        li_list = response.xpath('//div[@class="tea_con"]//li')
        for li in li_list:
            item = MyspiderItem()
            item["name"] = li.xpath(".//h3/text()").extract_First()
            item["title"] = li.xpath('.//h4/text()').extract_first()
            yield item

里面的 name 是爬虫的名字,allowed_domains 是允许爬虫爬取的域名,start_urls 是爬虫开爬的起始 url 地址

在 parse 函数中传过来的 response 我们可以直接 xpath 等解析器解析,这里可以和我们写的爬虫一样操作。

如果你真就在把提取和存储的工作给做完了,那就格局小了,这时候我们把格局打开

这里说一下的是,为什么我提取数据的时候不是按照常规的选择下标将数据提取出来而是用 extrast_first() 方法,你可以打印一下 li_lita 这个变量看看,这个不是平时我们用的列表,而是经过 scrapy 处理过的列表,所以我们可以用这个方法把他提取出来。其实用 extrast() 方法是可以将里面的文本内容提取出来的,但是我们还需要判断是否有空值,有空值的话,我们是不是给他赋值为 null ,所以我们就直接使用 extrast_first() 方法,他是提取第一个值,如果为空就直接标记为 None ,这样我们就不需要去判断是否为空了。

后续我们对数据做存储是在管道(piPElines.py)中进行的,所以我们在这里将数据进行传输,注意这位我们用的是 yield 而不是用的 return。

如何将数据进行传输呢,这里我们需要去设置一下,在 settings.py 里面找到 ITEM_PIPELINES 大概在 64 行

# configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'myspider.pipelines.MyspiderPipeline': 300,
}

我们将这个注释打开,这样就可以将数据传输到管道里面了,上面的 value 300,这个值是用来控制优先级的,值越小,优先级就越大,这个以后再说。

在爬虫文件中用 yield 传输数据是有要求的,具体是什么要求,原谅我忘记了,这里我们说说用字典传输吧

在 items.py 文件中,我们可以语言准备好我们要取的字段

# define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy


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

上面已经告诉了我们如何创建,我们们只需要按照上面的实例跟着创建就好了

如何我们回到爬虫文件 itcast.py

import scrapy
from ..items import MyspiderItem


class ItcastSpider(scrapy.Spider):
    # 爬虫的名字
    name = 'itcast'
    # 允许爬虫爬取的域名范围
    allowed_domains = ['itcast.cn']
    # 爬虫的起始 url
    start_urls = ['https://www.itcast.cn/channel/teacher.shtml#ajavaee']

    def parse(self, response, **kwargs):
        # 分组
        li_list = response.xpath('//div[@class="tea_con"]//li')
        for li in li_list:
            item = MyspiderItem()
            item["name"] = li.xpath(".//h3/text()").extract_first()
            item["title"] = li.xpath('.//h4/text()').extract_first()
            yield item

现在我们将 items 中的 MyspiderItem 导入这个文件中

from ..items import MyspiderItem

这里我们就不用再创建字典了,直接创建 MyspiderItem 这个对象,然后将我们获取的值存进去,这里要注意的是,我们的键必须和刚才定义的 Items 中的键一样,否则就会失去效果

这一切都做完后,我们就可以用 yield 将文件传入管道(pipelines)中,在 pipelines.py 中将 item 打印一下就可以看到我们获取到的内容了,同时我们也在这里对数据进行存储。

# 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


class MyspiderPipeline:
    def process_item(self, item, spider):
        print(item)
        return item

这里要说明一下如何去运行这个爬虫,在终端执行下面这个命令

scrapy crawl itcast --noLOG

这里是无日志运行,当然如果你想看到这个日志,你只需要将 --nolog 去掉就可以了

管道(pipelines)的使用

从 pipelines 的字典形式可以看出,pipeline 可以有多个,而且确实它可以定义多个。

多个 spider,不容的 pipeline 处理不同的 item 内容

一个 spider 的内容可能要做不同的操作,比如存入如同数据库

值得注意的时候 pipeline 的权重越小,优先级别越高,pipelines 中的 process_item 方法名不能修改为其他的名称

开启多个 pipeline 的时候我们需要去 settings 里面设置一下,继续找到之前设置 pipeline 的地方

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'myspider.pipelines.MyspiderPipeline': 300,
}

在这个字典里我们可以看出,这个键就是 pipeline 的位置,后面的值就是相对应的权重

先说的简单的例子,例如我们用 scrapy genspider 建立了多个爬虫,我们可以在爬虫文件中在字典中增加这样一个键值

item["come_from"] = "itcast"

然后在不同的爬虫里面建立同键不同值的键值对,这样我们是不是就可以在 pipeline 中进行判断了

class MyspiderPipeline:
    def process_item(self, item, spider):
        if item["come_from"] === "itcast":
       elif item["come_from"] === "xxx":
       else:
       xxx
        return item

这我们可以对他们做区分

除了这样,我们查看码的时候可以发现,pipeline 中传递了一个 spider 参数过来,我们在爬虫文件中有一个 name 的属性,这里传过来的 spider 是将整个爬虫传过来的,这样我们就可以使用 spider.name 来进行判断,当然除此判断之外,还可以在 pipelins 中定义多个 pipeline 类,只要 process_item 的方法名不改变,在 settings 中设置好就可以了

实现翻页功能

在爬虫文件中,在我们将一整也的数据用 yield 传输完之后,找到下一页的链接,根据网页结构来处理,比如我这里,他只是给出了后面的,那么

page_next_url = response.xpath("xxx").extract_first()
next_url = "http://xxx.xxx.xxx" + page_next_url
yield scrapy.Request(
	next_url,
	callback=self.paser
)

我们利用 Request 这个构造方法,将链接传输过去,这样就可以实现我们的翻页了

User-Agent 的设置

前面有提到 UA 是在 settings 里面有设置,所以我们进到 settings.py 里面,大概是在第 15 行

# Crawl responsibly by identifying yourself (and your website) on the user-agent
# USER_AGENT = 'myspider (+http://www.yourdomain.COM)'

我们只需要将 UA 的值放进去就可以了。

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Applewebkit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36'

对于 scrapy.Request()

scrapy.Request() 中的参数

scrapy.Request(utl, callbake, method='GET', headers, body, meta, cookies, meta, dont_filter=False)

这里面除了 url 外,其他的参数都是可选参数

scrapy.Request() 常用参数为:

callbake: 指定传入的 url 交给哪个解析函数去处理

meta: 实现在不同的解析函数中传递数据,meta 默认会携带部分信息,比如下载延迟,请求的深度等

dont_filter: 让 scrapy 的去重失效,对于需要重复请求的 url 有重要的作用

这里我们可以自己定义一个 headers 和 cookies 放进去,这里值得注意的是,这里既然给了我们传递 cookie 的位置,我们就不能将 cookie 放到 headers 中了。

这里的 body 该做何解释呢,上面的 method='GET', 也就是说,nethod 可以指定为以 post 为请求去访问这个网页,既然是以 post 请求去反问,那么就会有请求需要的参数,所以聪明的你就已经想到这个 body 就是用来存放 post 请求的时候所存放的参数的。

items 类

前面我们了解到了我们在爬虫类里面用 yield 传递一个字典的时候,会先在 items 里面定义好我们需要提取的字段,在源码的注释里面也清楚的告诉了我们,这么做的目的就是为了避免重复创建字典

在我们创建字典的时候可以看出,后面的 .Field() 只是占了个位置,是没有实际值的

name = scrapy.Field()

值得注意的是:我们在 items 里面定义的字段,在后面没有用灭关系,但是如果用了一个没有定义过的字段,程序就会报错。

还有一点值得注意的就是,这个程序里面的 item 看起来像是一个字典,但是它并不是一个正在的字典,不过我们可以用 IDCt() 来转换

脚本宝典总结

以上是脚本宝典为你收集整理的初识 scrapy 框架全部内容,希望文章能够帮你解决初识 scrapy 框架所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。