Scrapy框架的安装和使用

https://github.com/Python3WebSpider/Python3WebSpider/blob/master/13.2-Scrapy%E5%85%A5%E9%97%A8.md

安装Scrapy 需要先安装 lxml pyOpenSSL Twisted PyWin32
安装好上述模块以后 pip install Scrapy

验证安装及创建一个Scrapy项目 如果提示权限问题 可以加sudo运行该命令
在这里插入图片描述
在这里插入图片描述

创建spider

在这里插入图片描述

执行完毕后 spiders文件夹中多了一个quotes,py的文件
在这里插入图片描述

name: 每个项目唯一的名字 用来区分spider
allowed_domains : 允许爬取的域名 如果初始或者后续请求链接不是这个域名下的请求会被过滤掉
start_urls : 包含了spider在启动时爬取的url列表 初始请求由它来定义
parse() : start_urls中的链接请求完成下载执行后 的结果会作为唯一的参数传递给这个方法 该方法负责解析返回的响应 提取数据 或进一步生成要处理的请求

创建Item

item保存爬取数据的容器
需要继承 scrapy.item 类 定义类型为Field的字段
修改刚刚创建的项目中的 item.py 文件 定义三个字段

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

import scrapy


class  QuoteItem(scrapy.Item):
    #define the fields for your item here like:
    # name = scrapy.Field()
    text = scrapy.Field()
    author = scrapy.Field()
    tags = scrapy.Field()
  

解析Response

修改 spider.py中的parse()函数 并使用 Item

import scrapy


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

    def parse(self, response):
        quotes = response.css('.quote')
        for quote in quotes:
            item = QuoteItem()
            item['text'] = quote.css('.text::text').extract_first()
            item['author'] = quote.css('.author::text').extract_first()
            item['tags'] = quote.css('.tags.tag::text').extract()
            yield item

抓取下一页内容的Request

构造请求时需要用到scarpy.Request 传递两个参数 url:请求链接
callback: 请求完成之后回调函数 引擎会将响应作为参数传递给这个回调 函数,回调函数做解析或生成新的请求

import scrapy
from tutorial.items import QuoteItem


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

    def parse(self, response):
        quotes = response.css('.quote')
        for quote in quotes:
            item = QuoteItem()
            item['text'] = quote.css('.text::text').extract_first()
            item['author'] = quote.css('.author::text').extract_first()
            item['tags'] = quote.css('.tags .tag::text').extract() #之前在.tags.tag之间没加空格  爬出来的tags就为空
            yield item
        next  = response.css('.pager.next a::attr("href")').extract_first()
        url = response.urljoin(next)   # 为什么是response.urljoin()  response不是响应的结果吗  不应该是一个base_url.urljoin()吗
        yield scrapy.Request(url=url,callback=self.parse)###self.parse不用加括号吗  parse()不是一个方法吗


进入目录 scrapy crawl quotes 运行

爬取到的部分数据
在这里插入图片描述

保存爬取结果到文件

可以保存为多种文件格式
scrapy crawl quotes -o quotes.json
scrapy crawl quotes -o quotes.csv
scrapy crawl quotes -o quotes.marshal
scrapy crawl quotes -o quotes.xml
scrapy crawl quotes -o quotes.pickle
scrapy crawl quotes -o ftp://user:pass@ftp.example.com/path/to/quotes.csv
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用Item Pipeline

如果对爬取结果进行一些操作 比如筛选啊 清洗啊 就可以使用Item Pipeline
使用Item Pipeline只需在一个类中实现 process_item() 方法 该方法有两个参数 一个是item 每次Spider生成的item都会作为参数传递过来 另一个参数是spider的实例

修改项目中的pipeline.py文件

# 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
from scrapy.exceptions import DropItem
import  pymongo


class TextPipeline:
    def __init__(self):
        self.limit = 50

    def process_item(self, item, spider):
        if(item['text']):
            if len(item['text']) > self.limit:
                item['text'] = item['text'][0:self.limit].rstrip()+'...'  ##[0:self.limit] 中间是冒号
            return  item
        else:
            return DropItem('Missing Text')

class MongoPipeline:
    def __init__(self,mongo_uri,mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db

    @classmethod
    def from_crawler(cls,crawler):
        '''
        从settings.py文件传参数
        '''
        return cls(
            mongo_uri  = crawler.settings.get('MONGO_URI'),
            mongo_db = crawler.settings.get('MONGO_DB')
        )
    def open_spider(self,spider): ###我感觉这个函数用不到spider对象啊
        '''
        建立mongodb数据库
        '''
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]   ###这里是中括号

    def process_item(self,item,spider):
        '''
        实现Item Pipeline 需要在一个类中实现这个方法
        '''
        name = item.__class__.__name__  #实例调用__class__属性时会指向该实例对应的类,然后可以再去调用其它类属性,类属性由类调用
        self.db[name].insert(dict(item))  ###用name 作为collection 的名字 想mongodb中插入数据
        return item

    def closed(self):
        self.db.close()

classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。

class A(object):
    bar = 1
    def func1(self):  
        print ('foo') 
    @classmethod
    def func2(cls):
        print ('func2')
        print (cls.bar)
        cls().func1()   # 调用 foo 方法
 
A.func2()               # 不需要实例化

在这里插入图片描述

在settings.py文件中增加如下内容

ITEM_PIPELINES={
    'tutorial.pipelines.TextPipeline':300,
    'tutorial.pipelines.MongoPipeline':400,  ###键名是类名 键值为优先级 数字越小 优先级越高
}
MONGO_URI='localhost'
MONGO_DB='tutorial'

重新运行 scrapy crawl quotes
mongodb中成功插入数据
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值