scrapy练习笔记

scrapy练习

在这里插入图片描述

一、scrapy安装

官网:https://www.scrapy.org/
官方文档:https://docs.scrapy.org/en/latest/

首先创建一个新环境:

conda create -n pachong python==3.10
#激活环境
conda activate pachong

我用的是官方文档提供的conda下载指令:

conda install -c conda-forge scrapy

二、scrapy基本流程

2.1 学习目标

1.创建一个 Scrapy 项目,熟悉 Scrapy 项目的创建流程。
2.编写一个 Spider 来抓取站点和处理数据,了解 Spider 的基本用法。
3.初步了解 Item Pipeline 的功能,将抓取的内容保存到 MongoDB 数据库。
4.运行 Scrapy 爬虫项目,了解 Scrapy 项目的运行流程。

以 Scrapy 官方推荐的练习项目为例进行实战演练,抓取的目标站点为:https://quotes.toscrape.com/,页面如下图所示:
这个站点包含了一系列名人名言、作者和标签,我们需要使用 Scrapy 将其中的内容爬取并保存下来。
在这里插入图片描述

2.2 创建一个新项目

scrapy startproject ScrapyQuotes

运行完毕后,当前文件夹下会生成一个名为 ScrapyQuotes 的文件夹:
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/17a6156dcbeb436
eaddf05f3db429da2.png)
创建 Spider: Spider 是自己定义的类,Scrapy 用它来从网页里抓取内容,并解析抓取结果。不过这个类必须继承 Scrapy 提供的 Spider 类 scrapy.Spider,还要定义 Spider 的名称和起始 Request,以及怎样处理爬取后的结果的方法。也可以使用命令行创建一个 Spider,比如要生成 Quotes 这个 Spider,可以执行如下命令:
在这里插入图片描述

scrapy genspider quotes https://quotes.toscrape.com/

spiders 文件夹中多了一个 quotes.py,它就是刚刚创建的 Spider,内容如下所示:

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["quotes.toscrape.com"]
    start_urls = ["https://quotes.toscrape.com/"]

    def parse(self, response, **kwargs):
        pass

'''name: 是每个项目唯一的名字,用来区分不同的 Spider
allowed_domains: 是允许爬取的域名,如果初始或后续的请求链接不是这个域名下的,则请求链接会被过滤掉
start_urls: 包含了 Spider 在启动时爬取的 URL 列表,初始请求是由它来定义的
parse: Spider 的一个方法。在默认情况下,start_urls 里面的链接构成的请求完成下载后,parse 方法就会被调用,返回的响应就会作
为唯一的参数传递给 parse 方法。该方法负责解析返回的响应、提取数据或者进一步生成要处理的请求。
'''

修改配置文件,不然生成的quotes.py文件没有这个参数==**kwargs==,或者手动在quotes.py文件里加上
在这里插入图片描述

2.3 创建Item

Item 是保存爬取数据的容器,定义了爬取结果的数据结构。它的使用方法和字典类似。不过相比字典,Item 多了额外的保护机制,可以避免拼写错误或者定义字段错误。创建 Item 需要继承 scrapy 的 Item 类,并且定义类型为 Field 的字段,这个字段就是我们要爬取的字段。

观察目标网站,我们可以获取到的内容有下面几项:

text: 文本,即每条名言的内容,是一个字符串
author: 作者,即每条名言的作者,是一个字符串
tags: 标签,即每条名言的标签,是字符串组成的列表

这样的话,每条爬取数据就包含这3个字段,那么我们就可以定义对应的 Item,此时将 items.py 修改如下:
这里我们声明了 ScrapyQuotesItem,继承了 Item 类,然后使用 Field 定义了3个字段,爬取时我们就会用到这个 Item

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

import scrapy


# 
class ScrapyQuotesItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    text = scrapy.Field()  # 每条名言的内容
    author = scrapy.Field()  # 作者
    tags = scrapy.Field()  # 标签

2.4 解析 Response

关于 Response 更详细的解释可以参考官方文档:https://docs.scrapy.org/en/latest/topics/request-response.html#response-objects

# ① url:Request URL
# ② status:Response 状态码,一般情况下请求成功状态码为200
# ③ headers:Response Headers,是一个字典,字段是一一对应的
# ④ body:Response Body,这个通常就是访问页面之后得到的源代码结果了,比如里面包含的是HTML或者JSON字符串,但注意其结果是 
# bytes 类型。与requests模块请求后得到的响应属性content类似
# ⑤ request:Response 对应的 Request 对象
# ⑥ certificate:是twisted.internet.ssl.Certifucate类型的对象,通常代表一个SSL证书对象
# ⑦ ip_address:是一个ipaddress.IPv4Address或IPv6Address类型的对象,代表服务器的IP地址
# ⑧ urljoin:是对URL的一个处理方法,可以传入当前页面的相对URL,该方法处理后返回的就是绝对URL
# urljoin 其实使用的就是: from urllib.parse import urljoin 可以去看源码
# ⑨ follow/follow_all:是一个根据URL来生成后续Request的方法,和直接构造Request不同的是,该方法接收的url可以是相对URL,不必
# 一定是绝对URL,因为follow方法中有做url拼接的操作,源码如下:
if isinstance(url, Link):
   url = url.url
elif url is None:
   raise ValueError("url can't be None")
url = self.urljoin(url)

# ① text: 同body属性,但结果是str类型
# ② encoding: Response的编码,默认是utf-8
# ③ selector: 根据Response的内容构造而成的Selector对象,利用它我们可以进一步调用xpath、css等方法进行结果的提取
# ④ xpath()方法: 传入XPath进行内容提取,等同于调用selector的xpath方法
# ⑤ css()方法: 传入CSS选择器进行内容提取,等同于调用selector的css方法
# ⑥ json()方法: 是Scrapy2.2新增的方法,利用该方法可以直接将text属性转换为JSON对象,本质其实使用的就是json.loads,源码如下:
if self._cached_decoded_json is _NONE:
    self._cached_decoded_json = json.loads(self.body)
return self._cached_decoded_json

改写quotes.py的parse函数

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["quotes.toscrape.com"]
    start_urls = ["https://quotes.toscrape.com/"]
'''
这里首先利用 CSS 选择器选取所有的 quote 并将其赋值为 quotes 变量,然后利用 for 循环遍历每个 quote, 
解析每个 quote 的内容。单独调用 css 方法我们得到的是 Selector 对象组成的列表;调用 extract 方法会进
一步从 Selector 对象里提取其内容,再加上 ::text 则会从 HTML 代码中提取出正文文本。因此对于 text,我
们只需要获取结果的第一个元素即可,所以使用 extract_first 方法,得到的就是一个字符串。而对于 tags,
我们想要获取所有结果组成的列表,所以使用 extract 方法,得到的就是所有标签字符串组成的列表。
'''
    def parse(self, response, **kwargs):
    quotes = response.css("div.quote")
    for quote in quotes:
       text = quote.css("span.text::text").extract_first("")
       author = quote.css("small.author::text").extract_first("")
       tags = quote.css("div.tags a.tag::text").extract()

2.5 使用 Item

之前已经定义好了 ScrapyQuotesItem,接下来就要使用它了。我们可以把 Item 理解为一个字典,和字典还不太相同,其本质是一个类,所以在使用的时候需要实例化。实例化之后,我们依次用刚才解析的结果赋值 Item 的每一个字段,最后将 Item 返回。QuotesSpider 的改写如下所示:

from ScrapyQuotes.ScrapyQuotes.items import ScrapyQuotesItem
import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["quotes.toscrape.com"]
    start_urls = ["https://quotes.toscrape.com/"]

    def parse(self, response, **kwargs):
        quotes = response.css("div.quote")
        for quote in quotes:
            item = ScrapyQuotesItem()
            item["text"] = quote.css("span.text::text").extract_first("")
            item["author"] = quote.css("small.author::text").extract_first("")
            item["tags"] = quote.css("div.tags a.tag::text").extract()
            yield item

2.6 开始爬取

首先使用cd命令转到当前文件夹
在这里插入图片描述

cd C:\Users\zpysz\Desktop\pythonproject\scrapy_pachong\ScrapyQuotes

运行下面的指令,会把爬取结果存放在quotes.json文件夹里

scrapy crawl quotes -o quotes.json

在这里插入图片描述

三、爬取多页

3.1 练习

在第二章学习了爬取第一页内容,接下来学习爬取多页内容
在这里插入图片描述

这里发现有一个 Next 按钮,查看一下源代码,可以看到它的链接是 /page/2/,实际上全链接是 https://quotes.toscrape.com/page/2/,通过这个链接我们就可以构造下一个 Request 了。
接下来我们要做的就是利用选择器得到下一页链接并生成请求,在 parse 方法后追加如下的代码:

from ScrapyQuotes.items import ScrapyQuotesItem
import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["quotes.toscrape.com"]
    start_urls = ["https://quotes.toscrape.com"]

    def parse(self, response, **kwargs):
        quotes = response.css("div.quote")
        for quote in quotes:
            item = ScrapyQuotesItem()
            item["text"] = quote.css("span.text::text").extract_first("")
            item["author"] = quote.css("small.author::text").extract_first("")
            item["tags"] = quote.css("div.tags a.tag::text").extract()
            yield item
        href = response.css("li.next a::attr(href)").extract_first("")
        next_url = response.urljoin(href)
        yield scrapy.Request(url=next_url, callback=self.parse)

运行

scrapy crawl quotes -o quotes.json

在这里插入图片描述

3.2 输出格式

Feed Exports 支持输出的格式还有很多,例如 csv、xml、pickle、marshal 等,同时它支持 ftp、s3 等远程输出,另外还可以通过自定义 ItemExporter 来实现其他的输出。例如,下面命令对应的输出分别为 csv、xml、pickle、marshal 格式以及 ftp 远程输出:

scrapy crawl quotes -o quotes.csv
scrapy crawl quotes -o quotes.xml
scrapy crawl quotes -o quotes.pickle
scrapy crawl quotes -o quotes.marshal
scrapy crawl quotes -o ftp://user:pass@ftp.example.com/path/to/quotes.csv

3.3 使用 Item Pipeline

清洗 HTML 数据
验证爬取数据,检查爬取字段
查重并丢弃重复内容
将爬取结果存储到数据库

暂时到这

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值