Scrapy学习笔记(一)

来自 https://docs.scrapy.org/en/latest/intro/tutorial.html

建立一个最简单的工程

这是固定步骤。

scrapy startproject tutorial

第一个Spider

在spider文件夹下建立py文件 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)

  1. name在工程内唯一,定义爬虫名。
  2. start_request()方法返回Request对象,
  3. parse()方法用于处理response,也能生成新的Request请求。
  4. 这里scrapy.Request是被自动调度的对象,其中指定了url和返回response后的回调函数parse。如果没有重写start_requests方法,那么会有一个默认的方法,这时候就只用写一个start_urls的list就行了,parse会被调用处理这些url。

运行Spider

scrapy crawl quotes

之后就能看到文件夹下面会出现几个爬取的网页。到此为止,下载的网页只是简单地保存成了文件,还没有进行处理。

shell中简单取出数据

使用scrapy的shell可以进行一些即时交互,便于调试和学习。

scrapy shell "http://quotes.toscrape.com/page/1/"

之后在shell中输入命令就能马上得到一些结果。css、xpath选择器是最常用的(re()正则方法也很重要),具体的语法用到的时候再学就行。实在摸不着头脑最好对网页和xml的结构进行一下复习。

css:

>>> response.css('title')
[<Selector xpath='descendant-or-self::title' data='<title>Quotes to Scrape</title>'>]

xpath:


>>> response.xpath('//title/text()').get()
'Quotes to Scrape'

Spider中取出数据

修改parse()方法,返回一个dict(parse()方法只能返回新的request、dict对象或者是None,如果返回不允许返回的类型,就会报错,具体可以参看文档),注意用yield关键字(与generator语法有关)。

  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(),
            }

到这里我们虽然的到了一些数据,但是我们想持久化存储这些爬到的数据该怎么办?首先试试json存一下(其实还有个jl文件,好奇可以搜索一下,是一个流类型的json格式):

scrapy crawl quotes -o quotes.json

然而,我们又会想,输出一个json就完事了?我们如果想对数据进行一些加工该怎么办呢?这时候pipelines.py就派上用场了。

跟踪超链接

urls太不方便!每个网址都放在list中,我如果爬一万个网页这是不方便的。假设网页里已经有了超链接(例如a标志),那么先把它取出来吧!

在shell中可以实验:

>>> response.css('li.next a::attr(href)').get()
'/page/2/'

把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(),
                '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)

注意这里urljoin()是把相对url转换成完整的url。然后由于这个yield,每个request完成后,下一个request就会加入调度中了。
凡是固定的语法都可以进行精简,对于框架来说自然是越简单越好,下面也能理解成是一个语法糖:

        if next_page is not None:
            yield response.follow(next_page, callback=self.parse)

命令行工具传参数之类的具体可以参看文档。另外yield返回的dict完全可以用一个返回dict的函数替换,这样可以使代码更加模块化。

总结(一)

世界上最好的教程就是官网的文档,无论学习什么框架,如果仅仅从网上随便搜到的教程上学习,一方面别人写的不一定好理解,另一方面框架的时效性是非常强的,如果看的是旧文档,最后发现版本和自己使用的不对头是非常令人扫兴的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值