什么是框架

集成了很多功能,并且具有很强通用性的一个项目模板。(或理解成一个项目的半成品)

scrapy框架

爬虫中封装好的一个明星框架。

功能:

  1. 高性能的持久化存储操作
  2. 异步的数据下载
  3. 高性能的数据解析
  4. 分布式

环境安装

Mac & Linux

pip isntall scrapy

Windows

1、 wheel
pip install wheel
2、下载Twisted

https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted 下载自己对应得版本(我的是py3.9)
python 对象 持久化 python数据库持久化框架_配置文件
输入pip install 将下载的文件拖入安装

pip install d:\Users\YQ17454\Downloads\Twisted-20.3.0-cp39-cp39-win_amd64.whl
pywin32
pip install pywin32
scrapy
pip install scrapy
测试安装成功

终端中输入 scrapy,无报错及成功,不成功的注意版本

python 对象 持久化 python数据库持久化框架_ide_02

scrapy基本使用

基本使用

创建一个工程

终端输入:

scrapy startproject demo

python 对象 持久化 python数据库持久化框架_python 对象 持久化_03

UA伪装

在配置文件中

USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36'

python 对象 持久化 python数据库持久化框架_配置文件_04

切换到项目文件中
cd .\first\
在spiders文件下,创建一个爬虫文件(必须有)

spider是爬虫类(spiders下的爬虫文件)的父类

scrapy genspider first_demo www.baidu.com

python 对象 持久化 python数据库持久化框架_配置文件_05


自动生成的first_demo.py:

import scrapy


class FirstDemoSpider(scrapy.Spider):
	# 爬虫文件的名称 唯一标识
    name = 'first_demo'
    
    # 允许的域名: 用来限制start_urls 中可以发送请求的url,基本不使用
    # allowed_domains = ['www.baidu.com']
    
    # 起始的url列表(可有多个):自动的被scrapy进行请求
    start_urls = ['http://www.baidu.com/', 'http://www.qq.com/']

	# 用作于数据解析,response为请求成功后响应的响应对象。
	# parse 会被调用多次,取决于请求的url个数(start_urls )
    def parse(self, response):
        print(response)
执行工程
scrapy crawl first_demo

输出的很多是 log日志

不输出log日志

scrapy crawl first_demo --nolog

执行后,并没有打印响应数据,原因是配置文件:

python 对象 持久化 python数据库持久化框架_ide_06


ROBOTSTXT_OBEY = True,遵从robots协议

python 对象 持久化 python数据库持久化框架_配置文件_07


学习过程中,修改为 ROBOTSTXT_OBEY = False

再次运行工程

python 对象 持久化 python数据库持久化框架_python_08

完全不显示日志信息,出错了也不会提示,所以在配置文件中添加 LOG_LEVEl = ‘ERROR’

只输出错误类型的log

python 对象 持久化 python数据库持久化框架_ide_09

scrapy数据解析

爬取糗事百科的作者和内容

https://www.qiushibaike.com/text/

创建一个工程,配置文件

python 对象 持久化 python数据库持久化框架_python 对象 持久化_10


爬虫文件源码:

import scrapy


class QsbkSpider(scrapy.Spider):
    name = 'qsbk'
    # allowed_domains = ['https://www.qiushibaike.com/']
    start_urls = ['https://www.qiushibaike.com/text/']

    def parse(self, response):
        # 解析段子 作者的名称和内容
        author = response.xpath(
            '//*[@id="qiushi_tag_123876908"]/div[1]/a[2]/h2/text()')[0].extract()
        content = response.xpath(
            '//*[@id="qiushi_tag_123876908"]/a[1]/div/span//text()').extract()
        content = ''.join(content)
        print(author, content)

python 对象 持久化 python数据库持久化框架_ide_11

scrapy持久化存储

基于终端指令

好处:简洁高效便捷
缺点:局限性比较强(数据存储指定类型)

要求:只可以将parse方法的返回值存储到本地的文本文件中

只可以存储这几种类型的数据:

‘json’, ‘jsonlines’, ‘jl’, ‘csv’, ‘xml’, ‘marshal’, ‘pickle’

python 对象 持久化 python数据库持久化框架_ide_12

import scrapy


class QsbkSpider(scrapy.Spider):
    name = 'qsbk'
    # allowed_domains = ['https://www.qiushibaike.com/']
    start_urls = ['https://www.qiushibaike.com/text/']

    def parse(self, response):
        # 解析段子 作者的名称和内容
        author = response.xpath(
            '//div[@id="content"]/div/div[2]/div/div[1]//h2/text()').extract()
        content = response.xpath(
            '//div[@id="content"]/div/div[2]/div/a[1]/div/span[1]//text()').extract()
        print(author, content)
        dic = {
            'author': author,
            'content': content
        }
        return dic

终端执行命令:

scrapy crawl qsbk -o ./qiubai.csv
基于管道

好处:通用性强(数据库、本地)
确定:些许繁琐

编码流程
  1. 数据解析
  2. 在item类(文件 items.py)中定义相关属性
  3. 将解析到的数据封装存储到item类型的对象
  4. 将item类型的对象提交给管道进行持久化存储操作
  5. 在管道类(文件 pipelines.py)的process_item中将接收到的item对象中的数据进行持久化存储
  6. 配置文件中开启管道

python 对象 持久化 python数据库持久化框架_ide_13


items.py

import scrapy


class QiushiItem(scrapy.Item):
    # define the fields for your item here like:
    author = scrapy.Field()
    content = scrapy.Field()
    # pass

pipelines.py

from itemadapter import ItemAdapter


class QiushiPipeline:
    fp = None

    def open_spider(self, spider):  # 重写父类的一个方法:该方法只在开始爬虫的时候被调用一次
        print('start')
        self.fp = open('./qiubai.txt', 'w', encoding='utf-8')

    def process_item(self, item, spider): # 每调用一次执行一次
        author = item['author']
        content = item['content']
        self.fp.write('作者们:' + author + '\n' + '内容:' + content)
        return item

    def close_spider(self, spider): # 父类结束中调用一次
        print('end')
        self.fp.close()

修改 settings.py

ITEM_PIPELINES = {
   'qiushi.pipelines.QiushiPipeline': 300,
}

python 对象 持久化 python数据库持久化框架_python_14


爬虫文件:

import scrapy
from qiushi.items import QiushiItem


class QsbkSpider(scrapy.Spider):
    name = 'qsbk'
    # allowed_domains = ['https://www.qiushibaike.com/']
    start_urls = ['https://www.qiushibaike.com/text/']

    def parse(self, response):
        # 解析段子 作者的名称和内容
        author = response.xpath(
            '//div[@id="content"]/div/div[2]/div/div[1]//h2/text()').extract()
        content = response.xpath(
            '//div[@id="content"]/div/div[2]/div/a[1]/div/span[1]//text()').extract()
            
        # 将解析到的数据封装存储到item类型的对象
        item = QiushiItem()
        item['author'] = ''.join(author)
        item['content'] = ''.join(content)

        # 将item提交给管道
        yield item