C/C++教程

爬虫技术-Scrapy框架介绍

本文主要是介绍爬虫技术-Scrapy框架介绍,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Scrapy采集框架

1 学习目标

1、框架流程和结构设计原理

2、框架爬虫程序编写

3、框架日志模块使用

4、框架请求发送流程

2 scrapy简介

Scrapy是用纯Python实现一个为了爬取网站数据、提取结构性数据而编写的应用框架,用途非常广泛,用户只需要定制开发几个模块就可以轻松的实现一个爬虫,用来抓取网页内容以及各种图片,非常之方便。

2.0 单个爬虫编写

class Spider(object):
    def __init__(self):
        # 负责全局配置
        pass

    def url_list(self):
        # 负责任务池维护
        pass

    def request(self):
        # 负责网络请求模块
        pass

    def parse(self):
        # 负责解析数据模块
        pass

    def save(self):
        # 负责数据存储
        pass

    def run(self):
        # 负责模块调度
        pass

2.1 架构介绍

2.2.1 名词解析

2.2.2 运行逻辑图

3 框架使用

3.1 项目搭建

3.1.1 框架安装

查找历史版本:https://pypi.org/project/Scrapy/#history

pip install scrapy==2.3.0

3.1.2 项目创建

scrapy startproject xxxx

文件介绍

- scrapy.cfg:它是 Scrapy 项目的配置文件,其内定义了项目的配置文件路径、部署相关信息等内容。
- items.py:它定义 Item 数据结构,所有的 Item 的定义都可以放这里。
- pipelines.py:它定义 Item Pipeline 的实现,所有的 Item Pipeline 的实现都可以放这里。
- settings.py:它定义项目的全局配置。
- middlewares.py:它定义 Spider Middlewares 和 Downloader Middlewares 的实现。
- spiders:其内包含一个个 Spider 的实现,每个 Spider 都有一个文件。

3.1.3 创建爬虫

Spider 是自己定义的类,Scrapy 用它来从网页里抓取内容,并解析抓取的结果。不过这个类必须继承 Scrapy 提供的 Spiderscrapy.Spider,还要定义 Spider 的名称和起始请求,以及怎样处理爬取后的结果的方法

cd 项目路径
scrapy genspider  爬虫名称  目标地址

配置文件简介

# Scrapy settings for ScrapyDemo project

# 自动生成的配置,无需关注,不用修改
BOT_NAME = 'ScrapyDemo'
SPIDER_MODULES = ['ScrapyDemo.spiders']
NEWSPIDER_MODULE = 'ScrapyDemo.spiders'

# 设置UA,但不常用,一般都是在MiddleWare中添加
USER_AGENT = 'ScrapyDemo (+http://www.yourdomain.com)'

# 遵循robots.txt中的爬虫规则,很多人喜欢False,当然我也喜欢....
ROBOTSTXT_OBEY = True

# 对网站并发请求总数,默认16
CONCURRENT_REQUESTS = 32

# 相同网站两个请求之间的间隔时间,默认是0s。相当于time.sleep()
DOWNLOAD_DELAY = 3
# 下面两个配置二选一,但其值不能大于CONCURRENT_REQUESTS,默认启用PER_DOMAIN
# 对网站每个域名的最大并发请求,默认8
CONCURRENT_REQUESTS_PER_DOMAIN = 16
# 默认0,对网站每个IP的最大并发请求,会覆盖上面PER_DOMAIN配置,
# 同时DOWNLOAD_DELAY也成了相同IP两个请求间的间隔了
CONCURRENT_REQUESTS_PER_IP = 16

# 禁用cookie,默认是True,启用
COOKIES_ENABLED = False

# 请求头设置,这里基本上不用
DEFAULT_REQUEST_HEADERS = {
#   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
#   'Accept-Language': 'en',
}

# 配置启用Spider MiddleWares,Key是class,Value是优先级
SPIDER_MIDDLEWARES = {
    'ScrapyDemo.middlewares.ScrapydemoSpiderMiddleware': 543,
}

# 配置启用Downloader MiddleWares

DOWNLOADER_MIDDLEWARES = {
    'ScrapyDemo.middlewares.ScrapydemoDownloaderMiddleware': 543,
}

# 配置并启用扩展,主要是一些状态监控
EXTENSIONS = {
    'scrapy.extensions.telnet.TelnetConsole': None,
}

# 配置启用Pipeline用来持久化数据
ITEM_PIPELINES = {
   'ScrapyDemo.pipelines.ScrapydemoPipeline': 300,
}

3.2 执行爬虫

3.2.1 终端运行爬虫

  • 需要去到项目跟路径执行指令
scrapy crawl xxxx

3.2.2 脚本运行

  • Scrapy中有一个可以控制终端命令的模块cmdline。导入了这个模块,我们就能操控终端
  • execute方法能执行终端的命令行
from scrapy import cmdline

cmdline.execute("scrapy crawl xxxx".split())
cmdline.execute(["scrapy","crawl","xxxx"])

运行报错

ImportError: cannot import name 'HTTPClientFactory' from 'twisted.web.client' (unknown location)

解决:

# 降低Twisted版本
pip install Twisted==20.3.0

3.3 scrapy shell调试

基本使用

scrapy shell https://dig.chouti.com/

数据提取

datas =res.xpath('//div[@class="link-con"]/div')
for i in datas:
   print(i.xpath('.//a[@class="link-title link-statistics"]/text()').extract_first())

4 实战演示

  • 目标地址:https://book.douban.com/top250

4.1 spider结构

import scrapy
from scrapy import cmdline
import bs4

class TopSpider(scrapy.Spider):
    name = 'top'
    # allowed_domains = ['top.com']
    start_urls = ['https://book.douban.com/top250?start=0']

    def parse(self, response):
        #print(response.text)
        bs = bs4.BeautifulSoup(response.text, 'html.parser')
        datas = bs.find_all('tr', class_="item")
        for data in datas:
            item = {}
            item['title'] = data.find_all('a')[1]['title']
            item['publish'] = data.find('p', class_='pl').text
            item['score'] = data.find('span', class_='rating_nums').text
            print(item)
            
if __name__ == '__main__':
    cmdline.execute('scrapy crawl top'.split())

4.2 定义数据

scrapy中,我们会专门定义一个用于记录数据的类

import scrapy

class DoubanItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title = scrapy.Field()
    #定义书名的数据属性
    publish = scrapy.Field()
    #定义出版信息的数据属性
    score = scrapy.Field()

scrapy.Field()这行代码实现的是,让数据能以类似字典的形式记录。但记录的方式却不是字典,是是我们定义的DoubanItem,属于“自定义的Python字典”。

4.3 定义管道存储

4.3.1 配置管道

放开配置文件

ITEM_PIPELINES = {
   'douban.pipelines.DoubanPipeline': 300,
}

4.3.2 存储文件编写

import json

class DoubanPipeline:
    def process_item(self, item, spider):
        with open('da.json', 'a+', encoding='utf-8') as f:
            f.write(json.dumps(dict(item), ensure_ascii=False))
            f.write('\r\n')

4.3.3 配置日志

配置日志来做记录

LOG_LEVEL = 'WARNING'
LOG_FILE = './log.log'

配置日志为警告级别,如果有数据是警告级别那么将记录到文件

5 scrapy表单处理

5.1 目标地址

  • 首页:http://www.cninfo.com.cn/new/commonUrl?url=disclosure/list/notice#regulator
  • 接口:http://www.cninfo.com.cn/new/disclosure

5.2 程序编写

import scrapy

class PostTestSpider(scrapy.Spider):
    name = 'post_test'
    allowed_domains = ['cninfo.com']
    # start_urls = ['http://www.cninfo.com.cn/new/disclosure']

    def start_requests(self):
        url = 'http://www.cninfo.com.cn/new/disclosure'
        for i in range(1,5):
            form_data = {
                "column": "szse_gem_latest",
                "pageNum": str(i),
                "pageSize": "30",
                "sortName": "",
                "sortType": "",
                "clusterFlag": "true"
            }

            yield scrapy.FormRequest(url=url,formdata=form_data,meta={'page':form_data['pageNum']})

    def parse(self, response):
        print(f'正在采集第{response.meta.get("page")}页')

6 框架扩展

6.1 框架去重设计

dont_filter实现了框架去重的功能

import scrapy
import json

from scrapy import cmdline


class HuyaSpider(scrapy.Spider):
    name = 'huya'
    # allowed_domains = ['hy.com']

    def start_requests(self):
        url = ['https://www.huya.com/cache.php?m=LiveList&do=getLiveListByPage&gameId=1663&tagAll=0&page=2',
               'https://www.huya.com/cache.php?m=LiveList&do=getLiveListByPage&gameId=1663&tagAll=0&page=2']
        for i in url:
            # 框架默认对地址进行了去重
            yield scrapy.Request(url=i,dont_filter=False)


    def parse(self, response):
        items = json.loads(response.text)
        data = items.get('data').get('datas')
        print(len(data))

if __name__ == '__main__':
    cmdline.execute('scrapy crawl huya'.split())
这篇关于爬虫技术-Scrapy框架介绍的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!