ddd

Scrapy 1.5.0发布日期是2017.12.29

书写一个自己的教程

1. Scrapy是什么

1.1 Scrapy的定义

Scrapy是一个用来爬取网页并抽取结构化数据的应用框架,从而实现数据挖掘、信息处理或历史备份。

个人总结:Scrapy最坑的地方就是xpath()解析,没有之一

1.2 Scrapy的框架

Scrapy包括五大组件,Engine,Scheduler,Downloader,Spider,Item Pipeline
1. Engine 引擎
2. Scheduler 调度器
3. Downloader 下载器
4. Spider 爬虫
5. Item Pipeline 管道

图片

1.3 Scrapy的项目结构

待补充

1.4 Scrapy的工作原理

待补充

1.5 临时存放点

当你运行命令scrapy runspider quotes_spider.py,scrapy会通过引擎来运行这个文件,首先将start_urls属性中定义的URLs包装成requests,然后调用默认的回调方法parse(),并将response对象作为参数传递给它。在parse回调中,先通过使用CSS选择器来循环遍历quote元素,生成Python字典(包含结构化的quote text和author),并寻找下一页的链接,然后调度另一个请求同样使用parse来作为回调。

scrapy的一个优点就是:异步地调度和处理。这就意味着Scrapy不需要等待一个request完成处理,它可以同时发送另一个请求或者做别的事情。这也意味着如果一些request失败了或者在处理的时候发生了异常,其他的requests可以继续执行。

2. Item类

写一个Scrapy爬虫项目的第一步就是定义好Item类。Item类相当于javabean,它定义了爬取的数据的类型和所拥有的属性。所以在写Scrapy的时候首先要明确爬取的结果是什么,明确需求。Scrapy要求我们把它定义在Item中,爬取数据对象的每一个属性都通过Scrapy.Field()来定义

import scrapy


class MyscrapyItem(scrapy.Item):  # 自定义的Item类必须继承Scrapy.Item
    student_id = scrapy.Field()
    student_name = scrapy.Field()

3. Spider类

在Scrapy框架中,Engine是核心,但是它的任务已经由Scrapy框架完成了。在实际项目中,我们的核心是怎么实现Spider类。

Spider类对应于五大组件中的爬虫,它需要指明三个属性和一个方法:

属性/方法解释
name指明当前爬虫的名字,通过命令行运行爬虫时可以直接使用名字
allowed_domain(可省略)指明爬虫活动的域名范围,如果爬取的时候超出了范围,则停止继续深入
start_urls以列表的形式定义初始的URLs,它其实就已经充当了Scheduler的URL初步队列了
parse(response)解析网页并将需要保存的数据包装成Item对象给Pipeline,或者解析出下一个需要爬取的网页的url给调度器

3.1 定义name和allowed_domain

通过name属性来定义爬虫名字,通过allowed_domain属性来定义爬虫爬取的域名范围

3.2 定义初始url

(1) 通过start_urls属性来定义初始url列表
start_urls = ['http://quotes.toscrape.com/tag/humor/',]
(2) 通过start_requests(self)方法来生成初始url

scrapy调度爬虫类中start_requests方法返回的scrapy.Request对象,每当收到一个request的response,scrapy就会实例化Response对象并调用回调方法

def start_requests(self):  # 必须返回一个Requests的迭代器(返回一个列表或者一个生成器函数)
    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)
        # 简便写法
        # yield scrapy.Request(url, self.parse)

3.3 parse()

parse()有两个任务,解析数据给pipelines用于存储,解析下一个要爬取的网页的url生成request给Scheduler调度。

Engine从Downloader获取得到的每一个response都是交给parse()来处理的,这个是默认设置好的。爬取页面解析出的新request可以指定自定义parse()方法来解析。详见本节任务二。

展示一个简单的例子:

import scarpy # 导入scrapy包

class QuotesSpider(scrapy.Spider):  # 定义一个爬虫类,必须继承于scrapy中的Spider类
    name = 'quotes'  # 给爬虫类取个名字,用于区分其他的爬虫类
    start_urls = ['http://quotes.toscrape.com/tag/humor/',]  # 给爬虫类定义一个初始的url列表

    def parse(self, response):  
        for quote in response.css('div.quote'):
            yield {  # 生成一个字典并返回
                'text': quote.css('span.text::text').extract_first()
                'author': quote.xpath('span/small/text()').extract_first(),
            }

        next_page = response.css('li.next a::attr("href")').extract_first()
        if next_page is not None:
            yield response.follow(next_page, self.parse)
任务一:解析页面数据——xpath()解析和css()解析

两种解析方式返回值的类型是SelectorList(Selector对象组成的列表)

# 两个例子展示css解析
response.css('title::text').extract_first()
response.css('title::text')[0].extract()
response.css('title::text').re(r'Q\w+')

response.xpath('//title/text()').extract_first()

title::text表示我们只取title标签的text属性,否则就直接获取整个标签,为[Quotes to Scrape]

re()和extract()都可以实现转码的作用

任务二:生成下一个request
next_page = response.css('li.next a::attr(href)').extract_first()
if next_page is not None:
    # urljoin()将当前response.url和next_page拼接在一起
    next_page = response.urljoin(next_page)
    yield scrapy.Request(next_page, callback=self.parse)

next_page是下一个页面的Url,Request()将这个url封装成request交给Scheduler,等request发送完毕后,获取的response将按照call_back定义的parse()方法来执行解析。

上述方法的简便方法:

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

这里follow相当于采用相对路径,直接当前response.url和next_page作拼接,便省去了urljoin()

自定义parse()
class AuthorSpider(scrapy.Spider):
    name = 'author'

    start_urls = ['http://quotes.toscrape.com/']

    # 解析下一页
    def parse(self, response):
        # 将call_back设计成位置参数可以减少代码长度,对scrapy.Request()同样适用
        for href in response.css('.author + a::attr(href)'):
            yield response.follow(href, self.parse_author)

        for href in response.css('li.next a::attr(href)'):
            yield response.follow(href, self.parse)

    # 解析作者信息,并将作者信息传递给pipeline
    def parse_author(self, response):
        def extract_with_css(query):
            return response.css(query).extract_first().strip()

        yield {
            'name': extract_with_css('h3.author-title::text'),
            'brithdate': extract_with_css('h3.author-born-date::text'),
            'bio': extract_with_css('h3.author-description::text'),
        }

3.4 爬虫参数

设置爬虫参数,就可以在通过命令运行爬虫的时候,传递参数了。

class QuotesSpider(scrapy.Spider):
    # 其余部分省略
    def start_requests(self):
        url = 'http://quotes.toscrape.com/'
        tag = getattr(self, 'tag', self.parse)
        if tag is not None:
            url = url + 'tag/' + tag
        yield scrapy.Request(url, self.parse)

运行爬虫时 scrapy crawl quotes -o quotes-humor.json -a tag=humor,这时爬虫就只会访问 http://quotes.toscrape.com/tag/humor

4. Pipelines类

Pipelines是Scrapy中专门负责数据存储的部分,如果存储操作很简单,在spider中就可以直接存储,甚至都无须使用Item类。

Pipelines使用前注意:要在settings里面将Pipelines的注释反注释一下(后面的那个数字代表优先级,仅有一个Pipeline的时候不用管它是多少)

4.1 init(self) = start_spider(self, spider)

添加在爬虫执行前的一些存储准备工作,比如打开文件

def __init__(self):
    self.file = open(filename, 'w', encoding='utf8')

4.2 process_item(self, item, spider)

定义收到item后如何处理

def process_item(self, item, spider):
    # ... 存储的方式
    return item # 返回给engine告诉它存储完毕,然后继续调用parse()

4.3 close_spider(self, spider)

定义爬虫结束的收尾工作,比如关闭文件

def close_spider(self, spider)(self):
    self.file.close()

5. 命令行工具

命令包括scrapy全局命令和project命令,使用格式为:

scrapy [option] [args]

还可以通过在命令后面加-h来查看该命令的使用帮助

scrapy -h

5.1 scrapy全局命令

bench 测试

scrapy bench 测试当前机器的性能

fetch 获取response

用法:通过Downloader获取的response来测试url是否正确

scrapy fetch [option]

Options:

-spider=SPIDER 使用SPIDER爬虫类

genspider 创建爬虫

scrapy genspider [options]

Options:

–list, -l 列表显示可用的模板

–template=TEMPLATE, -t TEMPLATE 使用某个模板(basic, crawl, csvfeed, xmlfeed)

runspider 运行爬虫

在没有创建project的情况下指定一个爬虫文件并运行

scrapy runspider [options]

Options:

–output=FILE, -o FILE 指定输出文件

举例:scrapy runspider quotes_spider.py -o quotes.json

settings 设置

查看某个设置的值

scrapy settings [options]

shell

可以用来测试xpath()

scrapy shell [url|file]

注意:要设置好header,(windows下)url必须用双引号括起来

version 查看版本

scrapy version

view

垃圾功能,不用

5.2 project命令

crawl

运行一个spider

scrapy crawl [options]

Options:

--output=FILE, -o FILE 定义输出文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值