Scrapy学习过程之三:tutorial

本文详细介绍Scrapy爬虫框架的使用方法,包括创建工程、编写爬虫、数据提取、跟踪链接、参数传递等核心功能。通过实例演示如何启动爬虫、解析网页数据、存储抓取结果,并展示如何递归爬取网站。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:tutorial

贴出架构架构图以便参考:

Scrapy architecture

本tutorial涉及到的内容:

  • 创建一个scrapy工程
  • 写一个spider爬网页并提取数据
  • 使用命令行导出scrapy数据
  • 将spider改成递归跟踪链接
  • 给spider传递参数

Creating a project

自己先创建一个目录,然后运行如下命令:

scrapy startproject tutorial

此命令根据内置的模板成生一个目录及部分文件:

tutorial/
    scrapy.cfg            # deploy configuration file

    tutorial/             # project's Python module, you'll import your code from here
        __init__.py

        items.py          # project items definition file

        middlewares.py    # project middlewares file

        pipelines.py      # project pipelines file

        settings.py       # project settings file

        spiders/          # a directory where you'll later put your spiders
            __init__.py

tutorial/spider目录下边放spider的代码,spider是一个类定义,必需是scrapy.Spider的子类,直接或者间接。

spider代码实现的功能包括:向ENGINE提供初始的request,如何处理response中的链接、以及如何从response中提取想要的数据这三件事情。

在这个目录下边创建文件quotes_spider.py,并添加如下代码:

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"

    def start_requests(self):
        urls = [
            'http://quotes.toscrape.com/page/1/',
            'http://quotes.toscrape.com/page/2/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        page = response.url.split("/")[-2]
        filename = 'quotes-%s.html' % page
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log('Saved file %s' % filename)
  • name成员:SPIDER的唯一标识,在整个工程中不能重复。从架构图上可以看出来,每个SPIDER都在向ENGINE提交REQUEST,ENGINE会将REQUEST放入SCHEDULER队列,同时ENGINE会将RESPONSE交给parse处理,在这里name起到一个标识的作用,相当于消息系统中的定阅发布系统。
  • start_request方法:生成初始request的地方。这个方法即可以返回request列表,也可以是一个持续不断生成request的生成器
  • parse方法:解析拿到的response。通常包含两个功能,一个是提取数据,另一个是从RESPONSE中采集链接生成新REQUEST,然后交给ENGINE。

运行SPIDER:

scrapy crawl quotes

上边的例子只有两个起始url,在parse中没有提取数据,也没有跟踪新的连接,只是把response保存成文件,因此在生成两个文件后,此spider就结束运行了。

Extracting data in our spider

在parse方法中可以通过CSS选择器或者XPATH表达式提取数据:

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/',
        'http://quotes.toscrape.com/page/2/',
    ]

    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').get(),
                'author': quote.css('small.author::text').get(),
                'tags': quote.css('div.tags a.tag::text').getall(),
            }

可以看到,提取出来以后,组装成dict,然后yield,最终ENGINE会拿到这个数据。

Storing the scraped data

运行如下命令,Scrapy会将dict转换成json格式并输出到本地文件系统:

scrapy crawl quotes -o quotes.json

这个命令在每次运行时会将原始的文件替换掉,如果运行如下命令,则是在原始旧文件的基础上追加数据:

scrapy crawl quotes -o quotes.jl

Following links

代码如下:

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        'http://quotes.toscrape.com/page/1/',
    ]

    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').get(),
                'author': quote.css('small.author::text').get(),
                'tags': quote.css('div.tags a.tag::text').getall(),
            }

        next_page = response.css('li.next a::attr(href)').get()
        if next_page is not None:
            next_page = response.urljoin(next_page)
            yield scrapy.Request(next_page, callback=self.parse)

parse在提取数据的同时,还会将其中的链接提取出来并交给ENGINE去调度。

这里的新连接提取比较简单,还应该包含连接整形、过滤、去重、提交限速等问题,这些应该会在后边介绍到。

A shortcut for creating Requests

parse方法在提交新链接的请求时目前大概有两种方式,一种是上例中的scrapy.Request方法,这个方法里边的参数next_page是绝对路径。

另一个是response.follow方法,这个里边的参数next_page是相对路径。

Using spider arguments

带参数的命令:

scrapy crawl quotes -o quotes-humor.json -a tag=humor

-a tag=humor就是参数。

参数会被传递给scrapy.Spider的__init__方法,并且默认会成为SPIDER的属性。

下边的代码表示了访问传入参数的方法:

import scrapy


class QuotesSpider(scrapy.Spider):
    name = "quotes"

    def start_requests(self):
        url = 'http://quotes.toscrape.com/'
        tag = getattr(self, 'tag', None)
        if tag is not None:
            url = url + 'tag/' + tag
        yield scrapy.Request(url, self.parse)

    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').get(),
                'author': quote.css('small.author::text').get(),
            }

        next_page = response.css('li.next a::attr(href)').get()
        if next_page is not None:
            yield response.follow(next_page, self.parse)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值