• 第70天: Python Scrapy 爬虫框架及搭建


    by 戴景波

    Scrapy 框架实现爬虫的基本原理

    Scrapy 就是封装好的框架,你可以专心编写爬虫的核心逻辑,无需自己编写与爬虫逻辑无关的代码,套用这个框架就可以实现以上功能——爬取到想要的数据。

    Scrapy是一个Python实现的轻量级爬虫框架,它借助Twisted实现异步抓取。

    Scrapy 是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。

    本文档将通过介绍Scrapy背后的概念使您对其工作原理有所了解,如果暂时理解不深也没关系,后边会结合实例具体介绍。

    Python 爬虫基本流程

    A 发起请求———B 解析内容———C 获取响应内容———D 保存数据

    A 通过 HTTP 向目标站点发起请求,即发送一个 Request ,请求可以包含额外的 headers 等信息,等待服务器响应。

    B 得到的内容可能是 HTML ,可以用正则表达式、网页解析库进行解析。可能是 Json ,可以直接转为 Json 对象解析,可能是二进制数据,可以做保存或者进一步的处理。

    C 如果服务器能正常响应,会得到一个 Response , Response 的内容便是所要获取的页面内容,类型可能有 HTML , Json 字符串,二进制数据(如图片视频)等类型。

    D 保存形式多样,可以存为文本,也可以保存至数据库,或者保存特定格式的文件。

    搭建自己本机环境如下:Windows7 64bit———Python3.7———Pycharm64

    安装 Python———安装 Pycharm———安装 Scrapy———新建爬虫项目

    简单解释:将 Python 比作 Java ,那么 Pycharm 就相当于 eclipse , Pycharm 就是 Python 语言的运行环境 IDE 工具。

    安装 Python

    在 Python 的官网 www.python.org 中找到最新版本的 Python 安装包,点击进行下载,请注意,当你的电脑是32位的机器,请选择32位的安装包,如果是64位的,请选择64位的安装包;

    我自己机器是 win7 64bit 所以我下载的是 python-3.7.4.amd64.exe,其中的 add python 3.7 to PATH 一定要勾选。

    另外安装 python 路径不要有中文和空格,避免以后麻烦。后边就点击下一步即可。

    如果忘记勾选则需要手动添加环境变量:(需要添加两个: c:python3.7.0;c:python3.7.0Scripts)

    右键计算机——点击属性——点击高级系统设置——高级——环境变量——用户变量——PATH 添加自己安装 python 的路径。

    安装 Pycharm

    本篇对于环境的搭建只是起到抛砖引玉的作用,建议大家以下边做参考。

    https://www.runoob.com/w3cnote/pycharm-windows-install.html

    安装 Scrapy

    由于安装 Scrapy 不是本系列重点,所以仅展示 Windows 系统上安装 Scrapy 的步骤。注意:一定按顺序安装。 Cmd 进入 dos 窗口:

    C:UsersAdministrator>python
    Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    C:UsersAdministrator>python -m pip -V
    pip 19.0.3 from c:python3.7.0libsite-packagespip (python 3.7)  
    1.python -m pip install --upgrade pip
    2.python -m pip install Twisted-18.9.0-cp37-cp37m-win_amd64.whl
    3.python -m pip install pypiwin32
    4.python -m pip install scrapy
    5.python -m pip install requests
    

    如果中途安装遇到问题请及时 Google 查阅资料,查阅就是积累的过程。

    Scrapy 创建新项目:

    Pycharm 中用 alt+F12 切换到命令行,在命令行输入:

    (venv2) E:>scrapy startproject peilv
    

    就会生成 Scrapy 项目,项目名称是 peilv ,结构如下:主要改写2个文件:“items、settings”,新增2个文件:“爬虫主程序”、itemcsvexporter。

    peilv
    scrapy.cfg                     #创建项目时自动生成,项目的配置文件
    peilv/
        __init__.py                #创建项目时自动生成,无需任何改动
        items.py                   #创建项目时自动生成,定义爬取的字段    
        pipelines.py               #创建项目时自动生成,如存入文件,无需任何改动    
        settings.py                #创建项目时自动生成,将爬取字段按顺序输出    
        middlewares.py             #创建项目时自动生成,无需任何改动    
        spiders/   
            __init__.py            #创建项目时自动生成,无需任何改动	
    	itemcsvexporter.py     #需自己编写,代码固定	
            爬虫主程序.py           #需自己编写,爬虫的主程序
    

    items.py:

    ## -*- coding: utf-8 -*-
    import scrapy
    class PeilvItem(scrapy.Item):
        # define the fields for your item here like:
        cc  = scrapy.Field()#changci
        li =  scrapy.Field()#libo
        b5  = scrapy.Field()#bet365
    

    以上是定义您想抓取的数据,在Scrapy中, 这是通过 Scrapy Items 来完成的。通过scrapy.Field()方法创建需要存储的字段,比如cc存储比赛的场次信息,li存储立博的赔率信息,等等。

    关于这个items.py,你只要考虑它就是一个存储数据的容器,可以考虑成一个结构体,你所有需要提取的信息都在这里面存着。

    这里我们需要存储3个变量,cc,li,b5,所以我在里面加入三个变量,就这么简单。

    pipelines.py:

    一般来说,如果你要操作数据库什么的,需要在这里处理items,你可以把items写入数据库,但是今天我们用不到数据库,scrapy自带了一个很好的功能就是Feed exports,它支持多种格式的自动输出。

    所以我们直接用这个就好了,pipelines维持不变。

    settings.py:

    ## -*- coding: utf-8 -*-
    FEED_EXPORT_ENCODING = "gb18030" #解决导出的 Excel 文件中文乱码问题
    ...
    FEED_EXPORTERS = {
        'csv': 'peilv.spiders.itemcsvexporter.itemcsvexporter',
    }   
    FIELDS_TO_EXPORT = [
        'cc',#比赛场次
        'li',#立博的赔率
        'b5',#bet365的赔率
       ]
    ...
    

    FEED_EXPORT_ENCODING用gb18030常量来解决中文乱码问题,FEED_EXPORTERS表明了输出文件的格式,FIELDS_TO_EXPORT给定了输出字段的顺序。

    itemcsvexporter.py:

    from scrapy.conf import settings
    from scrapy.exporters import CsvItemExporter
    #指定输出到 csv 文件中字段的顺序,结合 setting.py
    class itemcsvexporter(CsvItemExporter):
        def __init__(self, *args, **kwargs):
    ...
    

    这里需要注意的是有的版本不支持from scrapy.contrib.exporter import CsvItemExporter类,所以用from scrapy.exporters import CsvItemExporter替换即可。
    通常结合setting中的字段顺序,规定最终CSV文件中的列排序规则。

    爬虫主程序.py:(下一篇详细介绍)

    ## -*- coding: utf-8 -*-
    ls_url = 'https://live.leisu.com/wanchang?date='#ls历史https://live.leisu.com/wanchang?date=20190606
    class LiveJiangSpider(scrapy.Spider):
        name = 'FBP'
        allowed_domains = ['leisu.com']
        def start_requests(self):
                d1='20190606' #历史的比赛
                request = scrapy.http.FormRequest(ls_url + d1,callback=self.parseLs, meta={'d1': d1}) #历史的比赛
                # request = scrapy.http.FormRequest(wl_url + d1,callback=self.parseWl, meta={'d1': d1})#未来的比赛
                yield request
        def parseLs(self,response):
            d2=response.meta['d1']
            sel=response.xpath
            racelist=[e5.split("'") for e5 in sel('//li[@data-status="8"]/@data-id').extract()]
            for raceid in racelist:#raceid=['2674547'];raceid[0]=2674547
                item = PeilvItem()
                sel_div=sel('//li[@data-id='+str(raceid[0])+']/div[@class="find-table layout-grid-tbody hide"]/div[@class="clearfix-row"]')
                if str(sel_div.xpath('span[@class="lab-lottery"]/span[@class="text-jc"]/text()').extract()) == "[]":
                    item['cc']=""
                else:
                    item['cc']=str(d2) + str(sel_div.xpath('span[@class="lab-lottery"]/span[@class="text-jc"]/text()').extract()[0])
                if "周" in item['cc']:#取竞彩-周一001等
                    plurl='https://live.leisu.com/3in1-'+raceid[0]
                    request = scrapy.http.FormRequest(plurl,callback=self.parse,meta={'item':item})
                    yield request #并非return,yield压队列,parse函数将会被当做一个生成器使用。scrapy会逐一获取parse方法中生成的结果,并没有直接执行parse,循环完成后,再执行parse
        def parse(self, response):
            print('--------------into parse----------------------')
            item = response.meta['item']
            pv=response.xpath
            pl_str = '/td[@class="bd-left"]/div[@class="begin float-left w-bar-100 bd-bottom p-b-8 color-999 m-b-8"]/span[@class="float-left col-3"]/text()'
            if str(pv('//*[@data-id="5"]'+pl_str).extract())=="[]":
                item['li'] =  ''
            else:
                item['li']=pv('//*[@data-id="5"]' + pl_str).extract()[0]
            if str(pv('//*[@data-id="2"]'+pl_str).extract())=="[]":
                item['b5'] =  ''
            else:
                item['b5']=pv('//*[@data-id="2"]' + pl_str).extract()[0]
            yield item#程序在取得各个页面的items前,会先处理完之前所有的request队列里的请求,然后再提取items
    

    爬虫主程序实现了爬取网页数据的具体逻辑,在下一讲会结合一个具体事例详细介绍。

    改写完程序后,最终执行命令:
    Pycharm 用 alt+F12 切换到命令行在项目 peilv 路径上执行:

    (venv2) E:>cd peilvpeilv 
    (venv2) E:peilvpeilv>scrapy crawl FBP -o BaseData.csv
    

    其中 FBP 是在“爬虫主程序.py”定义的——name = 'FBP',“-o BaseData.csv” 是将爬取的数据输出到 csv 文件中。

    总结

    以上首先创建一个工程和Spider模板,然后编写Spider,编写Item Pipeline,借助了Scrapy中的三个类——Request类、Response类和Item类。

    同时我们以一个实战项目为依托,将建立 Scrapy 项目的过程从零开始,深入浅出,让读者能够实践爬虫的整个过程。

    代码地址

    示例代码:Python-100-days-day070

    关注公众号:python技术,回复"python"一起学习交流

  • 相关阅读:
    CF225E Unsolvable
    CF1100E Andrew and Taxi
    oracle数据库导入导出方法
    ORACLE无法删除当前连接用户
     为什么上传文件的表单里要加个属性enctype----摘录
    ecplise 使用快捷键
    spring工作机制及为什么要用?
    阐述struts2的执行流程。
    Hibernate工作原理及为什么要用?
    Mybatis 如何自动生成bean dao xml 配置文件 generatorconfig.xml (main()方法自动生成更快捷)
  • 原文地址:https://www.cnblogs.com/ityouknow/p/12993355.html
Copyright © 2020-2023  润新知