关键字: Scrapy
CSS选择器
爬虫
前言
今天我们编写一个用 Scrapy
框架来爬取百度股票的代码,之前写过一篇爬取百度股票的文章,代码的逻辑和这篇文章的逻辑是一样的,用到的解析器不同罢了。
Scrapy爬虫框架
Scrapy 爬虫框架是由 7+2
的结构构成: 引擎(Scrapy Engine) 、调度器(Schedule) 、下载器(Downloader) 、爬虫(Spider) 、项目通道(Item Pipeline) 和 下载中间器(Downloader Middlewares) 、爬虫中间器(Spider Middlewares) 。
Scrapy 中的数据流(Data flow)由执行引擎控制,如下所示:
- 引擎 从 Spider 中获得需要爬取初始的
Requests
。 - 引擎 在 调度器 中调度
Requests
并询问下一个需要爬取的Requests
。 - 调度器 向 引擎 返回下一个要爬取的
Requests
。 - 引擎 通过 下载中间器 把这个
Requests
传递给 下载器 。 - 一旦页面下载完毕,下载器 生成一个
Response
(包含那个页面),并通过 下载中间件 把它传递给引擎。 - 引擎 从 下载器 中接收
Response
,通过 爬虫中间件 的处理传递给 Spider 。 - Spider 处理完
Response
后,通过 爬虫中间件 向 引擎 返回生成的items
和新的Requests
(如果有的话)。 - 引擎 把
items
传递给 Item Pipelines ,并把处理过的Requests
传递给 调度器 ,询问新的requests
。 - 程序从步骤 1 开始重复,直到 调度器 中不再有更多的请求为止。
更多 Scrapy 信息参考官方文档:
创建Scrapy项目
在电脑配置好 Scrapy 后,
在 D盘 创建名为 pycodes
的文件夹。
打开 cmd
命令窗口,进入 D盘 根目录后键入:
cd d:\pycodes
进入目录。scrapy startproject BaiduStocks
创建名为 BaiduStocks 的目录。cd BaiduStocks
进入项目目录。scrapy genspider stocks baidu.com
创建一个名为 stocks 的.py
文件,爬虫的初始 URL 为baidu.com
。- 在 BaiduStocks 文件夹下找到
stocks.py
文件后用 IDE 打开,下面我们来编写代码。
stocks.py
import scrapy
import re
class stocksSpider(scrapy.Spider):
name = 'stocks'
start_urls = ['http://quote.eastmoney.com/stocklist.html']
def parse(self, response):
for href in response.css('a::attr(href)').extract():
try:
stock = re.findall('[s][zh]\d{6}', href)[0]
url = 'http://gupiao.baidu.com/stock/' + stock + '.html'
yield scrapy.Request(url, callback=self.parse_stock)
except:
continue
def parse_stock(self, response):
infoDict = {}
stockInfo = response.css('.stock-bets') #只搜索'.stock-bets'标签下的'dt'和'dd'标签
stockname = stockInfo.css('.bets-name').extract()
keyList = stockInfo.css('dt').extract()
valueList = stockInfo.css('dd').extract()
for i in range(len(keyList)):
key = re.findall('<dt.*?>(.*?)</dt>', keyList)[0]
try:
value = re.findall('<dd.*?>(.*?)</dd>', valueList)[0]
except:
value = '--'
infoDict[key] = value
infoDict.update({'股票名称': re.findall('<a.*?">(.*?)(<span.*?)', stockname)})
yield infoDict
- parse 函数用到关键字
yield
,由于 parse 函数生成的股票 URL 超过 4500 个,如果以列表形式传递给 parse_stocks ,给内存造成的负担会更大。 - 在文件夹 BaiduStocks 下找到
pipelines.py
,用 IDE 打开。
pipelines.py
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
class BaidustocksPipeline(object):
def open_item(self, spider):
self.f = open('baiduStockInfo.txt', 'w')
def close_item(self, spider):
self.f.close()
def process_item(self, item, spider):
try:
line = str(dict(item)) + '\n'
self.f.write(line)
except:
pass
return item
类 BaiduStocksPipeline
有三个函数: open_item
、close_item
、process_item
。
至此,代码编写完成,运行程序,结果会保存在一个名为 baiduStockInfo
的 txt 文件中。