5.3 案例:用Scrapy抓取股票行情

---恢复内容开始---

本案例将使用Scrapy框架,抓取某证券网站A股行情,如下图所示。抓取过程分为以下五步:

第一步,创建Scrapy爬虫项目;

第二步,定义一个item容器;

第三步,定义settings文件进行基本爬虫设置;

第四步,编写爬虫逻辑;

第五步,代码调试。

1、创建Scrapy爬虫项目

调出CMD,输入如下代码并按【Enter】键,创建Scrapy爬虫项目。

scrapy startproject stockstar

其中scrapy startproject 是固定命令,stockstar是笔者设置的工程名字。

运行上述代码的目的是创建相应的项目文件,如下所示。

放置spider代码的目录文件     spiders(用于编写爬虫)
项目中的item文件            items.py(用于保存所抓取的数据的容器,其存储方式类似于Python的字典)。
项目的中间件                middlewares.py(提供一种简便的机制,通过允许插入兹定于代码来拓展Scrapy的功能)。
项目的pipelines文件         pipelines.py(核心处理器)。
项目的设置文件              settings.py
项目的配置文件              scrapy.cfg

项目结构如图所示。

创建scrapy项目以后,在settings文件中有这样的一条默认开启的语句。

ROBOTSTXT_OBEY = True

robots.txt是遵循Robot协议的一个文件,在Scrapy启动后,首先会访问网站的robots.txt文件,然后决定该网站的爬取范围。有时我们需要将此配置项设置为False。在settings.py文件中,修改文件属性的方法如下。

ROBOTSTXT_OBEY = False

右击E:\stockstar\stockstar文件夹,在弹出的快捷菜单中选择“Mark Directory as”命令->选择“Sources Root”命令,这样可以使得导入包的语法更加简洁,如图所示。

2、定义一个item容器

item是存储爬取数据的容器,其使用方法和Python字典类似。它提供了额外的保护机制以避免拼写错误导致的未定义字段错误。

首先需要对所要抓取的网页数据进行分析,定义所爬取记录的数据结构。在相应的items.py中建立相应的字段,详细代码如下。

import scrapy
from scrapy.loader import ItemLoader
from scrapy.loader.processors import TakeFirst

class StockstarItemLoader(ItemLoader):
    #自定义itemloader,用于存储爬虫所抓取的字段内容de
    default_output_processor = TakeFirst()

class StockstarItem(scrapy.Item): #建立相应的字段
    # define the fields for your item here like:
    # name = scrapy.Field()
    code = scrapy.Field()     #股票代码
    abbr = scrapy.Field()     #股票简称
    last_trade = scrapy.Field()  #最新价
    chg_ratio = scrapy.Field()   #涨跌幅
    chg_amt = scrapy.Field()    #涨跌额
    chg_ratio_5min = scrapy.Field()  #5分钟涨幅
    volumn = scrapy.Field()      #成交量
    turn_over = scrapy.Field()    #成交额

3、定义settings文件进行基本爬虫设置

在相应的settings.py文件中定义可显示中文的JSON Lines Exporter,并设置爬取间隔为0.25秒,详细代码如下。

from scrapy.exporters import JsonLinesItemExporter
#默认显示的中文是阅读性较差的Unicode字符
#需要定义子类显示出原来的字符集(将父类的ensure_ascii属性设置为False即可)
class CustomJsonLinesItemExporter(JsonLinesItemExporter):
    def __init__(self,file,**kwargs):
        super(CustomJsonLinesItemExporter,self).__init__(file,ensure_ascii=False,**kwargs)
        # 启用新定义的Exporter类
        FEED_EXPORTERS = {
            'json':'stockstar.settings.CustomJsonLinesItemExporter',
        }

# Configure a delay for requests for the same website (default: 0)
# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 0.25

4、编写爬虫逻辑

在编写爬虫逻辑之前,需要在stockstar/spider子文件下创建.py文件,用于定于爬虫的范围,也就是初始URL。接下来定义一个名为parse的函数,用于解析服务器返回的内容。

首先在CMD中输入代码,并生成spider代码,如下所示。

cd stockstar
scrapy genspider stock quote.stockstar.com

 

此时spider文件夹下面会创建后缀名为stock.py的文件,该文件会生成start_url,即爬虫的起始地址,并且创建名为parse的自定义函数,之后的爬虫逻辑将在parse函数中书写。文件详情如图所示,代码详情如图所示。

        

随后在spiders/stock.py文件下,定义爬虫逻辑,详细代码如下。

 

import scrapy
from stockstar.items import StockstarItem,StockstarItemLoader

class StockSpider(scrapy.Spider):
    name = 'stock'                                 #定义爬虫名称
    allowed_domains = ['quote.stockstar.com']    #定义爬虫域
    start_urls = ['http://quote.stockstar.com/stock/ranklist_a_3_1_1.html']
    #定义开始爬虫链接
    def parse(self,response):    #撰写爬虫逻辑
        page = int(response.url.split("_")[-1].split(".")[0])  #抓取页码
        item_nodes = response.css('#datalist tr')
        for item_node in item_nodes:
            #根据item文件中所定义的字段内容,进行字段内容的抓取
            item_loader = StockstarItemLoader(item=StockstarItem(),selector= item_node)
            item_loader.add_css("code","td:nth-child(1) a::text")
            item_loader.add_css("abbr", "td:nth-child(2) a::text")
            item_loader.add_css("last_trade", "td:nth-child(3) span::text")
            item_loader.add_css("chg_ratio", "td:nth-child(4) span::text")
            item_loader.add_css("chg_amt", "td:nth-child(5) span::text")
            item_loader.add_css("chg_ratio_5min", "td:nth-child(6) span::text")
            item_loader.add_css("volumn", "td:nth-child(7) ::text")
            item_loader.add_css("turn_over", "td:nth-child(8) ::text")
            stock_item = item_loader.load_item()
            yield stock_item
        if item_nodes:
            next_page = page + 1
            next_url = response.url.replace("{0}.html".format(page),"{0}.html".format(next_page))
            yield scrapy.Request(url=next_url,callback=self.parse)

5、代码调试

为了调试方便,在E:\stockstar下新建一个main.py,调试代码如下。

from scrapy.cmdline import execute
execute(["scrapy","crawl","stock","-o","items.json"])

其等价于在E:\stockstar下执行命令“scrapy crawl stock -o items.json”,将爬取的数据导出到items.json文件。

E:\stockstar>scrapy crawl stock -o items.json

在代码里可设置断点(如在spiders/stock.py内),然后单击"Run”选项按钮->在弹出的菜单中选择“Debug 'main'”命令,进行调试,如下图所示。

最后在PyCharm中运行Run'main',运行界面如图所示。

 

报错了,貌似是有一个名为“pywin32”的库找不到。

pywin32库也不能通过pycharm进行安装,也不能通过pip3直接安装,只能通过下载whl文件进行安装,与安装twisted库过程一样。

安装完pywin32库后,需要对其进行文件的配置,打开python环境,导入pywin32会出错,如下图所示。

解决上面问题的方法如下:

1、在本机中找到pywin32库,如下图所示,复制其文件。

2、然后把复制的文件复制到C:\Windows\System32

在回到pycharm中,run”stock.py",可以正常运行,运行的结果如下所示。

 

posted @ 2019-07-01 17:48  taoziya  阅读(1012)  评论(1)    收藏  举报