前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >爬虫框架Scrapy(一)

爬虫框架Scrapy(一)

作者头像
小闫同学啊
发布2019-07-18 14:47:16
1.1K0
发布2019-07-18 14:47:16
举报
文章被收录于专栏:小闫笔记小闫笔记

正文共: 5670字 10图 预计阅读时间: 15分钟

每日分享

Absorb what is useful. Discard what is not. Add what is uniquely your own.

汲取有用的东西,丢弃没用的,然后再加点你自己独特的东西进去。

小闫语录

世界很大,知识很多,事情很杂,去其糟粕取其精华。如果将我们每个人比作一个容器,容量是固定不变的,我们为里面装什么才能让自己变得优秀呢?答案可想而知,尽量的多装有用、实用的东西。不要贪多,没有用的东西只会成为你的累赘,阻碍你前进。有所舍弃,方能成功。

爬虫框架Scrapy(一)

1.scrapy

框架的优点

1.提供了整套项目的打包方案,开发速度快。

2.使用scrapy框架开发的项目,稳定性极高。

3.scrapy框架的底层实现非常优秀,性能优越。

4.使用scrapy框架分布式爬虫简单。

1.1scrapy的工作流程

1.起始的url,调度器会把URL等信息封装成请求对象。

2.调度器会把请求对象返回给引擎,引擎会将请求对象给下载器,发送请求,获取响应。

3.下载器把响应给引擎,引擎把响应数据给爬虫,解析数据。

4.解析结果返回引擎,引擎会判断数据,给item管道,进行保存,或给调度器再次发送请求。

我们可以根据爬虫的运行原理来理解scrapy框架的运行原理:

图1 爬虫流程

图2 爬虫流程改写

1.2Scrapy组件功能

引擎:处理整个系统各模块之间的信号,数据流等。

下载器(get_data):接受请求,返回响应。

调度器(构造URL):接受请求(封装了url)压入队列;引擎再次请求时返回请求。

爬虫(parse_data):定义起始url;定义如何爬取一个网站。

item管道(save_data):数据的后续处理(作用相当于模型类)。

下载器中间件:主要处理引擎与下载器之间的请求及响应(反反爬)。

爬虫中间件:处理spider的响应输入和请求输出。

Spider爬虫和ItemPipeline管道是需要自己手写的部分。

1.3总结

1.scrapy的概念:Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。

2.scrapy框架的运行流程以及数据传递过程

2.1爬虫中起始的url构造成request对象-->爬虫中间件-->引擎-->调度器。

2.2调度器把request-->引擎-->下载中间件--->下载器。

2.3下载器发送请求,获取response响应---->下载中间件---->引擎--->爬虫中间件--->爬虫。

2.4爬虫提取url地址,组装成request对象---->爬虫中间件--->引擎--->调度器,重复步骤2。

2.5爬虫提取数据--->引擎--->管道处理和保存数据。

3.scrapy框架的作用:通过少量代码实现快速抓取

4.掌握scrapy中每个模块的作用:

引擎(engine):负责数据和信号在不同模块间的传递

调度器(scheduler):实现一个队列,存放引擎发过来的request请求对象

下载器(downloader):发送引擎发过来的request请求,获取响应,并将响应交给引擎

爬虫(spider):处理引擎发过来的response,提取数据,提取url,并交给引擎

管道(pipeline):处理引擎传递过来的数据,比如存储

下载中间件(downloader middleware):可以自定义的下载扩展,比如设置代理ip

爬虫中间件(spider middleware):可以自定义request请求和进行response过滤,与下载中间件作用重复

2.scrapy的简单使用

安装scrapy命令:

代码语言:javascript
复制
sudo apt-get install scrapy 
或者:
pip install scrapy

创建scrapy项目的命令:

代码语言:javascript
复制
scrapy startproject <项目名字>

创建爬虫命令:在项目路径下执行:

代码语言:javascript
复制
scrapy genspider <爬虫名字> <允许爬取的域名>

示例:

代码语言:javascript
复制
cd myspider
scrapy genspider Ethanyan Ethanyan.cn

还可以手动创建,直接在内层的spiders目录下创建一个py文件即可。文件中需要手动书写相关必要代码。

运行项目:

代码语言:javascript
复制
scrapy crawl 项目名 [--nolog]

添加--nolog是启动之后不输出日志,不添加则会有日志输出。

2.1案例-百度小爬虫

爬虫创建的步骤

1.在爬虫目录下,scrapy genspider 爬虫的名称 允许的域。

2.在爬虫目录下:运行爬虫,scrapy crawl 爬虫的名称。

代码

代码语言:javascript
复制
# -*- coding: utf-8 -*-
import scrapy

class BaiduSpider(scrapy.Spider):
    # 爬虫的名称
    name = 'baidu'
    # 允许的域,爬虫会爬取哪个域名下的网页数据
    allowed_domains = ['baidu.com']
    # 起始的url列表
    start_urls = ['http://baidu.com/']

    # 解析函数,函数名固定
    # response表示响应
    # 起始url---调度器---引擎---下载器---引擎---百度爬虫
    def parse(self, response):
        print("*"*100)
        print(response)
        print("*"*100)
        # 获取百度源码,类似于之前的response.content.decode()
        # print(response.text)
        # 查看请求信息
        # print(response.request.headers)
        # 查看响应对象有什么方法
        # print(dir(response))
        # 查看响应的字节类型,body类似于之前的response.content
        print(response.body)

3.框架的使用

使用框架实现一个爬虫的步骤

1.在items管道文件中建模,定义好需要存储的数据。

2.分析目标站点,提取数据,使用xpath测试。

3.打开爬虫文件,修改起始的url,检查允许的域。

4.保存数据到具体的文件当中,使用管道,必须到settings文件中67行开启管道。

代码语言:javascript
复制
ITEM_PIPELINES = {
   'myspider.pipelines.MyspiderPipeline': 300,
}

其中的300是权重值

注意

1.在pipelines文件中写函数保存文件的时候,可以使用 __init____del__这一对方法,也可以使用 open_spiderclose_spider

open_spider和closespider中必须接收一个形参item。否则会报错。

2.在终端运行爬虫项目的时候,一定要先进入到对应的虚拟环境中。

3.在pipelines文件中的 process_item方法中,json.dumps中的item必须转为字典才可以使用。而且 process_item方法必须返回 item实例。

代码语言:javascript
复制
def process_item(self, item, spider):
    # 把item字典数据转成json字符串,写入文件
    json_data = json.dumps(dict(item),ensure_ascii=False) + ',\n'
    self.file.write(json_data)
    return item

4. feed输出:在运行的时候可以指定输出文件的名字以及各式。

代码语言:javascript
复制
scrapy crawl 项目名 -o 文件名

此处的项目名指定的是创建的爬虫项目文件中 name指定的名称,并不是文件名。 文件名可以指定为xxx.csv或者xxx.html之类的。

5.在没有写爬虫项目之前可以使用 scrapy shell测试目标网站或者XPath,获取响应。

代码语言:javascript
复制
scrapy shell "url地址"

6.XPath是解析不了tbody。

7. scrapy shell也可以指定请求头中的用户代理:

代码语言:javascript
复制
scrapy shell -s USER_AGENT='用户代理'
# 进入到shell里面,获取响应
fetch(url) # 注意url使用引号。

scrapy还没有写爬虫呢,就可以用scrapy shell测试了。

4.scrapy.Spider类

功能

定义了如何爬取一个站点。

1.发起起始的请求。

2.解析响应,抽取数据和跟进的url。(定义了爬取行为、定义了数据抽取行为)

是最基本的类,所有编写的爬虫必须继承这个类

Spider类各模块的功能

4.1案例-腾讯招聘爬虫

Tencent/spiders/tencent.py

代码语言:javascript
复制
import scrapy
from Tencent.items import TencentItem # 导入Item,注意路径

class TencentSpider(scrapy.Spider):
    name = 'tencent'
    allowed_domains = ['hr.tencent.com']
    # 修改的起始URL
    start_urls = ['http://hr.tencent.com/position.php']
    def parse(self, response):
        # 解析响应数据,获取所有招聘信息的列表
        tr_list = response.xpath('//*[@class="tablelist"]//tr')[1:-1]
        for tr in tr_list:
            meta_dict = {}
            meta_dict['name'] = tr.xpath('.//a[1]/text()').extract_first()
            meta_dict['address'] = tr.xpath('./td[4]/text()').extract_first()
            meta_dict['time'] = tr.xpath('./td[5]/text()').extract_first()
            meta_dict['href'] = tr.xpath('.//a[1]/@href').extract_first()
            detail_url = 'https://hr.tencent.com/' + meta_dict['href']
            yield scrapy.Request(detail_url, callback=self.parse_detail, meta=meta_dict)

        # 提取下一页的href并拼接url
        next_url = 'https://hr.tencent.com/' + response.xpath('//a[text()="下一页"]/@href').extract_first()
        # 判断是否是最后一页
        if response.xpath('//a[text()="下一页"]/@href').extract_first() != 'javascript:;':
            # 构造scrapy.Request对象,并yield给引擎
            # 利用callback参数指定该Request对象之后获取的响应用哪个函数进行解析
            # 利用meta参数将本函数中提取的数据传递给callback指定的函数
            # 注意这里是yield
            yield scrapy.Request(next_url, callback=self.parse)

    def parse_detail(self,response):
        meta_dict = response.meta  # 获取传入的meta

        item = TencentItem()  # 实例化后可直接使用
        item['name'] = meta_dict['name']
        item['address'] = meta_dict['address']
        item['time'] = meta_dict['time']

        # 加入岗位职责数据
        item['job_content'] = response.xpath('//ul[@class="squareli"]/li/text()').extract()

        print(item)

extractfirst()和extract()的区别是:extractfirst()如果获取不到数据不报错。

Tencent/items.py

代码语言:javascript
复制
import scrapy

class TencentItem(scrapy.Item):
    name = scrapy.Field() # 招聘标题
    address = scrapy.Field() # 工作地址
    time = scrapy.Field() # 发布时间
    job_content = scrapy.Field() # 工作职责

Tencent/settings.py

代码语言:javascript
复制
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'

ROBOTSTXT_OBEY = False
总结

scrapy框架会自动发送请求,一般代码实现,只需要在parse函数中解析数据。如果遇到需要自己发送请求的爬虫,需要手动调用 scrapy.Request()发送请求。

小知识点

1.tornado(龙卷风)框架相对于flask和Django来说,是原生并发量支持最高的,还是是异步的框架。但是基于Linux才能支持高并发。tornado服务器中,IOLoop是调度的核心模块,tornado是基于epoll事件驱动模型,这也是为什么在Linux中支持高并发的原因。

2.scrapy是异步的爬虫框架,基于异步网络引擎实现,爬取数据效率高。

3.scrapy debug信息: 框架的版本、扩展的使用,中间件的启动信息,爬虫运行的信息,请求次数、请求方法、响应次数、响应大小、时间信息等。

优质文章推荐:

公众号使用指南

redis操作命令总结

前端中那些让你头疼的英文单词

Flask框架重点知识总结回顾

项目重点知识点详解

难点理解&面试题问答

flask框架中的一些常见问题

团队开发注意事项

浅谈密码加密

Django框架中的英文单词

Django中数据库的相关操作

DRF框架中的英文单词

重点内容回顾-DRF

Django相关知识点回顾

美多商城项目导航帖

项目重要技术点介绍

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈技术精选 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 每日分享
  • 爬虫框架Scrapy(一)
    • 1.scrapy
      • 1.1scrapy的工作流程
      • 1.2Scrapy组件功能
      • 1.3总结
    • 2.scrapy的简单使用
      • 2.1案例-百度小爬虫
    • 3.框架的使用
      • 4.scrapy.Spider类
        • 4.1案例-腾讯招聘爬虫
      • 小知识点
      相关产品与服务
      消息队列 TDMQ
      消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档