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",可以正常运行,运行的结果如下所示。

浙公网安备 33010602011771号