ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

爬虫技术-Scrapy框架介绍

2022-09-14 22:01:47  阅读:274  来源: 互联网

标签:框架 self 爬虫 Spider Scrapy com class def 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 实战演示

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 目标地址

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

标签:框架,self,爬虫,Spider,Scrapy,com,class,def,scrapy
来源: https://www.cnblogs.com/feng0815/p/16691177.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有