实例应用:
建立工程和spider模板:
执行以下步骤命令:
代码最终写完后如下:
文件1:
stocks.py
# -*- coding: utf-8 -*-
import scrapy
import re
class StocksSpider(scrapy.Spider):
name = 'stocks'
start_urls = ['https://www.banban.cn/gupiao/list_sh.html']
def parse(self, response):
for href in response.css('a::attr(href)').extract(): # 提取这个页面中的a标签的链接
try :
stock = re.findall(r"[s][hz]\d{6}]",href)[0]
url = 'https://gupiao.baidu.com/stock/' + stock + '.html'
# 用yield 把parse方法变成一个生成器
yield scrapy.Request(url,callback=self.parse_stock) # callback给出了处理这个url对应响应的处理函数
except:
continue
# 提取单个股票信息 返回信息 给item pipeline 处理信息,作为item 接收字典类型。
def parse_stock():
# 对每个页面 生成一个空字典
infoDict={}
# 使用CSS Selector 提取其中的信息,找到属性的区域
stockInfo =response.css('.stock-bets')
name = stockInfo.css('.bets-name').extract()[0] # 股票的名字
#对股票其他信息进行提取
keyList = stockInfo.css('dt').extract()
valueList = stockInfo.css('dd').extract()
# 将信息保存在字典中
for i in range(len(keyList)):
key = re.findall(r'>.*</dt>',keyList[i])[0][1:-5]
try:
val = re.findall(r'\d+\.?.*</dd>',valueList[i])[0][0:-5]
except:
val = '--'
infoDict[key]=val
#将股票的名称进行更新 一个infoDict保存了一个股票名称和相关信息
infoDict.update(
{'股票名称':re.findall('\s.*\(',name)[0].split()[0] + \
re.findall('\>.*\<',name)[0][1:-1]}
)
# 将上面的信息给到后续处理的 item pipe line 模块儿,方法是将此方法parse_stock定义生成器
yield infoDict
文件2:
pipelines.py
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
class BstocksPipeline(object):
def process_item(self, item, spider):
return item
# 注意:如何让scrapy框架找到我们这个类呢??需要修改配置文件D:\pythontest\scrapy\pycodes\BStocks\BStocks\settings.py(配置ITEM_PIPELINES)
# 定义一个新的类 此文件中每一个类都是对一个item处理的一个过程
# 定义一个新的类是为了尝试一下定义新类的方法,并通过配置文件,让框架找到我们新定义的这个类
# 并且用这个类来处理Spider提出的提取的item相关信息
class BstocksInfoPipeline(object):
#每个pipeline中对应3个方法
# 爬虫被调用时对应的pipeline 启动的方法
def open_spider(self,spider):
self.f = open('BStockInfo.txt','w')
#一个爬虫关闭和结束时对应的方法
def close_spider(self,spider):
self.f.close()
#对于每一个item项进行处理时调用的方法 pipe中最主体的部分
#在打开爬虫 时我们 希望它建立一个文件,关闭爬虫时我们 希望这个文件被关闭,而处理item时我们希望把每一个股票的信息写到这个文件中
# 那么在process item中,我们需要将获得的股票字典信息写入一个文件,语句如下
def process_item(self,item,spider):
try:
line = str(dict(item)) + '\n'
self.f.write(line)
except:
pass
return item
#如果还希望其他函数还继续处理这个item,那我们这里就返回
文件3:
执行爬取命令:
在D:\pythontest\scrapy\pycodes\BStocks 目录下执行:scrapy crawl stocks
优化:
目的是提高爬取速度
scrapy提供了四个与性能相关的配置: