运用scrapy爬虫框架爬取fgowiki上的礼装图片

     分类: Python,个人笔记,编程开发 发布时间: 2018-11-05 18:02 1,213人浏览

一、scrapy框架的安装使用

1、安装基础环境

一般的python包可以直接使用pip安装

安装lxml

pip install lxml

如果没有任何报错,则证明安装成功。

如果出现报错,比如提示缺少libxml2库等信息,可以采用wheel方式安装。

直接到这里下载对应的whl文件,找到本地安装Python版本和系统对应的lxml版本,将其下载到本地。

然后利用pip安装即可,命令如下:

pip install lxml‑4.2.5‑cp35‑cp35m‑win_amd64.whl

安装pyOpenSSL
官方网站点击 Download files,下载whl文件,同样使用pip安装

安装Twisted
直接到这里下载对应的whl文件,找到本地安装Python版本和系统对应的lxml版本下载,同样使用pip安装

安装PyWin32
官方网站下载对应版本的安装包即可,

2、安装scrapy

有了依赖库之后,安装scrapy本体非常简单,使用以下命令安装即可

pip install Scrapy

如果需要对js进行渲染的话,还需要使用scrapy-splash与docker。
其中scrapy-splash直接pip install scrapy_splash就行。
docker需要docker pull scrapinghub/splash ,并开启8050端口docker run -p 8050:8050 scrapinghub/splash
详情可以参考Scrapy学习篇(十三)之scrapy-splash
不需要js渲染的话就不用折腾docker了。

二、scrapy框架构成

Scrapy使用Twisted作为框架,采用异步事件驱动,具体架构图如下:
运用scrapy爬虫框架爬取fgowiki上的礼装图片插图

Scrapy数据流是由执行的核心引擎(engine)控制,流程是这样的:

  1. 爬虫引擎获得初始请求开始抓取。
  2. 爬虫引擎开始请求调度程序,并准备对下一次的请求进行抓取。
  3. 爬虫调度器返回下一个请求给爬虫引擎。
  4. 引擎请求发送到下载器,通过下载中间件下载网络数据。
  5. 一旦下载器完成页面下载,将下载结果返回给爬虫引擎。
  6. 引擎将下载器的响应通过中间件返回给爬虫进行处理。
  7. 爬虫处理响应,并通过中间件返回处理后的items,以及新的请求给引擎。
  8. 引擎发送处理后的items到项目管道,然后把处理结果返回给调度器,调度器计划处理下一个请求抓取。
  9. 重复该过程(继续步骤1),直到爬取完所有的url请求。

爬虫引擎(Engine)
爬虫引擎负责控制各个组件之间的数据流,当某些操作触发事件后都是通过engine来处理。

调度器(Scheduler)
调度接收来engine的请求并将请求放入队列中,并通过事件返回给engine。

下载器(Downloader)
通过engine请求下载网络数据并将结果响应给engine。

爬虫模块(Spider)
Spider发出请求,并处理engine返回给它下载器响应数据,以items和规则内的数据请求(urls)返回给engine。

管道项目(item pipeline)
负责处理engine返回spider解析后的数据,并且将数据持久化,例如将数据存入数据库或者文件。

下载中间件(Downloader middlewares)
下载中间件是engine和下载器交互组件,以钩子(插件)的形式存在,可以代替接收请求、处理数据的下载以及将结果响应给engine。

spider中间件(Spider middlewares)
spider中间件是engine和spider之间的交互组件,以钩子(插件)的形式存在,可以代替处理response以及返回给engine items及新的请求集。

三、scrapy入门

如果可以的话配合使用virtualenv,可以单独配置爬虫环境,具体使用方法应该会另外说明(咕咕)。
在virtualenv环境中,进入想要创建的目录中,输入:

scrapy startproject tutorial

例如:
运用scrapy爬虫框架爬取fgowiki上的礼装图片插图1
scrapy会自动创建一个tutorial文件夹(可改名),文件夹内目录如下:

    scrapy.cfg         #scrapy基础配置
    tutorial/
        __init__.py
        items.py            #负责数据模型的建立,类似于实体类
        middlewares.py      #自己定义的中间件
        pipelines.py        #负责对spider返回数据的处理
        settings.py         #爬虫项目主要配置文件
        spiders/            #自定义的文件夹,里面填写自己写的爬虫文件
            __init__.py
            ...

四、爬取礼装的关键代码

具体可参见该项目的Github:scrapy-FGOwiki-spider

在spiders文件夹内可以自定义自己的爬虫文件,py文件名随意,但需要在class里面使用name属性定义自己的爬虫名字。至于类的名字可以自由定义,反正也不直接使用它。

其中这个爬虫类需要有几个重要的属性:
– start_urls 用于设定爬虫开始爬取的初始URL
– allowed_domains 设定爬虫可以爬取的范围,一般是某一个域名
– headers 爬虫的请求头,作用和模拟登录中发起请求的header是一样的
– headers 爬虫的请求头,作用和模拟登录中发起请求的header是一样的
– parse(self, response) 爬虫爬取到网站信息之后返回处理的函数,提取出我们需要的信息并把它置于item中,下一步交由对应的处理函数或者pineline处理。

# -*- coding: utf-8 -*-
import scrapy
import re
from ..items import TutorialItem #..代表上一级
from scrapy_splash import SplashRequest

class DmozSpider(scrapy.Spider):
    #定义爬虫名
    name = "fgo-wiki-demo"
     #搜索的域名范围,也就是爬虫的约束区域,规定爬虫只爬取这个域名下的网页
    allowed_domains = [""]
    #用for构造url
    start_urls = []
    for i in range(901):
        start_urls.append('https://fgowiki.com/guide/equipdetail/%s'%i)
    print(start_urls)
    # 设置爬虫的请求头,防止爬取失败
    headers = {
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 '
                      '(KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36',
    }
    # 定义主页面爬取规则,有其他链接则继续深挖
    #rules = (Rule(LinkExtractor(allow=('.+?\.html')), follow=True),

    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(url
                                ,self.parse
                                ,args={'wait':'0.5'}
                                )
        pass

#该函数名不能改变,因为Scrapy源码中默认callback函数的函数名就是parse
    def parse(self, response):
        item = TutorialItem()
        image_style = response.xpath('//li[@class="swiper-slide eq Card"]/@style').extract() #返回一个list,但这个list里只有一条
        item['image_urls'] = re.search(r'http.*?jpg',image_style[0]).group()
        item['name'] = response.xpath('//div[@class="textsmall NAME_CN"]//text()').extract_first()
        item['author'] = response.xpath('//div[@class="textsmall ILLUST"]//text()').extract_first()
        yield item
        print("返回item成功")

在爬虫中引用的item需要在items.py中定义:

import scrapy

class TutorialItem(scrapy.Item):
    image_urls=scrapy.Field()
    name = scrapy.Field()
    author = scrapy.Field()

如果需要下载文件的话,则需要在pipelines.py中定义处理函数。这个函数比较自由发挥,能实现自己需要的功能即可。

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

import scrapy
from scrapy.pipelines.images import ImagesPipeline

class TutorialPipeline(ImagesPipeline):

    def get_media_requests(self, item, info):
        print("获取URL")
        yield scrapy.Request(item['image_urls'], meta={'item': item, 'index': item['image_urls']})
    def file_path(self, request, response=None, info=None):
        item = request.meta['item']  # 通过上面的meta传递过来item
        image_name = "礼装-" + item['name'] + "." + request.url.split('/')[-1].split('.')[-1]
        down_file_name = u'/{0}/{1}'.format(item['author'], image_name)
        return down_file_name

在项目下使用scrapy crawl 爬虫名即可运行爬虫


参考链接:
崔庆才的个人博客
scrapy中文文档
Scrapy修改下载图片名字


上一篇文章:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注