scrapy框架(从安装到基本使用)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/masicro/article/details/89190740

1、scrapy安装

前提需要安装python,安装scrapy可以直接 pip install scrapy

pip install scrapy安装出现错误一般就是缺少Twisted组件

python大多数库组件以下网站都有:

https://www.lfd.uci.edu/~gohlke/pythonlibs/

安装Twisted:

windows下:进入下载对应的twisted组件,下载后使用cmd进入下载后文件的目录,使用pip install 下载的文件名 安装

linux下:下载Twisted源码,解压并进入安装

​ Twisted源码地址:https://pypi.org/simple/twisted/

tar -jvxf Twisted-10.1.0.tar.bz2
cd Twisted-10.1.0
python setup.py install

Twisted安装完成后在安装scrapy:pip install scrapy

倘若出现No module named _sqlite3的解决方案:

yum install sqlite-devel
在重新编译python环境

2、scrapy基本结构

scrapy是用纯Python实现的一个为了爬取网站数据、提取结构性数据而编写的应用框架,用途十分广泛。多用于抓取大量静态页面。
框架的力量:用户只要开发几个模块就可以轻松的实现一个爬虫,用来抓取页面内容以及各种图片,非常方便
Scrapy使用了Twisted(其主要对手是Tornado)异步网络框架来处理网络通讯,可以加快我们的下载速度,不用自己去实现异步框架,并且包含了各种中间件接口,可以灵活完成各种需求。

在这里插入图片描述

Scrapy Engine(引擎):负责Spider、ItemPipeline、Downloader、Schedule中间的通讯,信号,数据传递等。

Scheduler(调度器):它负责接收引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。

Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将获取到的response交还给Scrapy Engine(引擎),由引擎交给Spider来处理

Spider(爬虫): 它负责处理所有Responses,从中分析提取数据,获取Item字段所需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器)

Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行后期处理(详细分析、过滤、存储等)的地方。

Downloader Middlewares(下载中间件):你可以当做是一个可以自定义扩展下载功能的组件。

Spider Middlewares(Spider中间件):你可以理解为是一个可以自定义扩展和操作引擎和Spider中间通信的功能组件(比如进入Spider的Responses;和从Spider出去的Requests)

详细过程如图
在这里插入图片描述

3、scrapy的基本使用:

3.1、 新建项目(scrapy startproject ‘project_name’):新建一个怕从项目

在这里插入图片描述
下面介绍一个各个主要文件的作用:

	scrapy.cfg:项目的配置文件

	mySpider/:项目的Python模块,将会从这里引用代码

	myspider/items.py:项目的目标文件

	myspider/piplines.py:项目的管道文件

	myspider/settingd.py:项目的设置文件

	myspider/spiders/:存储怕从代码目录

3.2、明确目标(编写items.py):明确想要抓取的需要存储的数据字段

在这里插入图片描述

3.3、制作爬虫(spider/xxspider.py):制作爬虫开始爬取网页

创建爬虫文件:scrapy genspider ‘spider_name’ ‘url’

# -*- coding: utf-8 -*-
import scrapy
from ..items import TenxunItem

class TenxSpider(scrapy.Spider):
    name = 'tenx'
    allowed_domains = ['tentcent.com']
    start_urls = ['https://hr.tencent.com/position.php']
    base_url = 'https://hr.tencent.com/'

    def parse(self, response):
        # 匹配所有的tr标签
        tr_list = response.xpath('//table[@class="tablelist"]/tr')
        # 匹配下一页地址
        next_url = self.base_url+response.xpath('//a[@id="next"]/@href').extract()[0]
        yield scrapy.Request(url=next_url,callback=self.parse,dont_filter=True)
        for tr in tr_list[1:-1]:
            # 匹配数据
            items = TenxunItem()
            items['position_name'] = tr.xpath('./td[1]/a/text()').extract()
            items['position_url'] = '{}{}'.format(self.base_url,tr.xpath('./td[1]/a/@href').extract()[0])
            items['position_type'] = tr.xpath('./td[2]/text()').extract()
            items['position_num'] = tr.xpath('./td[3]/text()').extract()
            items['position_addr'] = tr.xpath('./td[4]/text()').extract()
            items['position_time'] = tr.xpath('./td[5]/text()').extract()
            # yield items
            # 将请求加入到队列
            yield scrapy.Request(url=items['position_url'],callback=self.detail_content,meta={'items':items},dont_filter=True)


    def detail_content(self,response):
        print("*"*30)
        items = response.meta.get('items')
        content = ''.join(response.xpath('//ul[@class ="squareli"]/li/text()').extract())
        items['position_content'] = content
        yield items

3.4、存储过程(pipelines.py):设计管道存储数据

设计本地存储为json数据

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json

class TenxunPipeline(object):
    def open_spider(self, spider):
        self.file = open('tencent.json','a',encoding='UTF-8')
    def process_item(self, item, spider):
        content = json.dumps(dict(item),ensure_ascii=False)+'\n'
        self.file.write(content)
        #return item

    def close_spider(self, spider):
        self.file.close()

还需在myspider/settings.py里面注册管道

# Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'tenxun.pipelines.TenxunPipeline': 300,
}

3.5、运行scrapy

scrapy list   

scrapy crawl spider_name

4、Scrapy shell

Scrapy终端是一个交互终端,我们可以在未启动spider的情况下尝试Scrapy shell调试代码,也可以用来测试XPath或者CSS表达式,查看他们的工作方式,方便我们爬取的网页中提取数据。

进入scrapy shell进行调试,建议安装ipython,该ipython可以提供智能自动完成和彩色输出

启动:scrapy shell

4.1、Selectors选择器(scrapy内置):

selector有四个基本的方法,最常用的还是XPath:

xpath():传入xpath表达式,返回该表达式所对应的所有节点的selector list 列表

extract():序列化该节点为Unicode字符串并返回list

css():传入CSS表达式,返回该表达式所对应的所有节点的selector list列表,语法同BeautifulSoup4

re():根据传入的正则表达式对数据进行提取,返回Unicode字符串list列表

xpath一般是提取结构化数据

5、spider简介

5.1、什么是spider

Spider类定义了如何爬取某个(或者)某些网站,包括了爬取的动作(如:是否跟进链接)以及如何从网页的内容中提取结构化数据(item)。换句话说,spider就是定义爬取的动作及分析某个网页(或者某些网页)并提取数据的地方

5.2、Spider主要的属性和方法

5.2.1、name:

定义spider名字的字符串。具有唯一性

5.2.2、allowed_domains:

包含了spider允许爬取的域名(domain)的列表,可选。如果爬取的网站不在这里面会抓取不到,

其中遇到了"Filtered offsite request to’hr.tencent.com’: <GET https://hr.tencent.com/positi" 这是由于request的地址和allow_domain里面的冲突,从而被过滤掉。可以停用过滤功能。在请求中添加dont_filter=True

5.2.3、strat_urls:

初始URL元祖/列表。当没有特定的URL时,spider姜葱该列表中开始进行爬取

5.2.4、start_requests(self):

该方法必须返回一个可迭代对象(Iterable)。该对象包含了spider用于爬取(默认实现是使用start_urls的url)的第一个request。当spider启动爬取并且未指定start_url时,该方法被调用。如果需要验证登陆是可以重写该方法

5.2.4parse(self,response):

当请求url返回网页没有指定回调函数时,默认的requset对象回调函数。用来处理网页返货的response,以及生成I特么或者Request对象

5.3、怎样编写spider爬取数据

例子:爬取腾讯招聘

# -*- coding: utf-8 -*-
import scrapy
from ..items import TenxunItem

class TenxSpider(scrapy.Spider):
    name = 'tenx'
    allowed_domains = ['tentcent.com']
    start_urls = ['https://hr.tencent.com/position.php']
    base_url = 'https://hr.tencent.com/'

    def parse(self, response):
        # 匹配所有的tr标签
        tr_list = response.xpath('//table[@class="tablelist"]/tr')
        # 匹配下一页地址
        next_url = self.base_url+response.xpath('//a[@id="next"]/@href').extract()[0]
        yield scrapy.Request(url=next_url,callback=self.parse,dont_filter=True)
        for tr in tr_list[1:-1]:
            # 匹配数据
            items = TenxunItem()
            items['position_name'] = tr.xpath('./td[1]/a/text()').extract()
            items['position_url'] = '{}{}'.format(self.base_url,tr.xpath('./td[1]/a/@href').extract()[0])
            items['position_type'] = tr.xpath('./td[2]/text()').extract()
            items['position_num'] = tr.xpath('./td[3]/text()').extract()
            items['position_addr'] = tr.xpath('./td[4]/text()').extract()
            items['position_time'] = tr.xpath('./td[5]/text()').extract()
            # yield items
            # 将请求加入到队列
            yield scrapy.Request(url=items['position_url'],callback=self.detail_content,meta={'items':items},dont_filter=True)


    def detail_content(self,response):
        print("*"*30)
        items = response.meta.get('items')
        content = ''.join(response.xpath('//ul[@class ="squareli"]/li/text()').extract())
        items['position_content'] = content
        yield items

5.4、在函数间传递参数item

#meta属性传递参数items
yield scrapy.Request(url=items['position_url'],callback=self.detail_content,meta={'items':items},dont_filter=True)
def jieshou(self,response):
	#接收items
    items = response.meta.get('items')

6、crawlspider

CrawlSpider使用rules来决定爬虫的爬取规则,并将匹配后的url请求交给引擎。所以正常情况下,CrawlSpider不需要单独手动返回请求了——只需要自己定义好规则后,爬虫自动爬取定义好的规则的内容

在rules中包含一个或多个rule对象,每个rule对爬取网站的动作定义了某种操作,比如提取当前相应内容里的特定链接,是否对提取的连接跟进爬取,对提交的请求设置回调函数等。

如果多个rule匹配了相同的链接,则根据规则在本集合中被定义的顺序,第一个会被使用

规则常用的是正则

6.1、CrawlSpider重要方法有哪些----》Rules

class scrapy.spider.Rule(
	Link_extractor,
    callback = None,
    cb_kwargs = None,
    follow = None,
    process_links = None,
    process_request = None
)
  • Link_extractor: 是一个Link Extractor对象,用于定义需要提取的链接

  • callback:从Link_extractor中每获取到链接时,参数所指定的值作为回调函数,该回调函数接收一个response作为其第一个参数

    注意:当编写爬虫规则时,避免使用parse作为回调函数。由于CrawlSpider使用parse方法来实现其逻辑,如果覆盖了parse方法,CrawlSpider将会运行失败

  • follow:是一个布尔(boolean)值,制定了根据该规则从response提取的链接是否需要跟进。如果callback为None,follow默认设置为True,否则默认为False。

  • process_links:指定该spider中那个函数会被调用,从Link_extractor中获取到链接列表时将会调用该函数。该方法主要是用来过滤

  • process_request:指定该spider中那个函数将会被调用,该规则提取到每个request是都会调用该函数(用来过滤request)

6.2、CrawlSpider重要方法有哪些? ----》LinkExtractors

class scrapy.linkextractors.LinkExtractor(
    allow = (),
    deny = (),
    allow_domains = (),
    deny_domains = (),
    deny_extensions = None,
    restrict_xpaths = (),
    tags = ('a','area'),
    attrs = ('href'),
    canonicalize = True,
    unique = True,
    process_value = None
)

主要参数:

allow:满足括号中“正则表达式”的URL会被提取,如果为空,则全部匹配。
**deny:**满足括号中“正则表达式”的URL一定不提取(优先级高于allow)。
**allow_domains:**会被提取的链接的domains。
**deny_domains:**一定不会被提取链接的domains。
**restrict_xpaths:**使用xpath表达式,和allow共同作用过滤链接。

6.3、使用crawlspider

**创建项目**
scrapy startproject  project_name
**创建模版**
scrapy genspider -t crawl spider_name yuming

运行

scrapy crawl spider_name

7、scrapy中间件

下载中间件,代理和IP

在这里插入图片描述

8、scrapy对接selenium

为了获取js渲染后的数据,我们在中间件上配置

class AreaMiddleware(object):


    def process_request(self,request,spider):
        self.driver = webdriver.PhantomJS()

        self.driver.get(request.url)
        html = self.driver.page_source  #js加载之后的源码
        self.driver.quit()
        return  scrapy.http.HtmlResponse(url=request.url, body=html)

设置里面下载中间件里面如下设置

# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
  #将这里改为这样,这样我们就不仅过下载器,直接调用selenium模拟下载
    'area_spider.middlewares.AreaSpiderMiddleware': 543,
}

猜你喜欢

转载自blog.csdn.net/masicro/article/details/89190740
今日推荐