Python 网络爬虫笔记11 – Scrapy 实战
Python 网络爬虫系列笔记是笔者在学习嵩天老师的《Python网络爬虫与信息提取》课程及笔者实践网络爬虫的笔记。
课程链接:Python网络爬虫与信息提取
参考文档:
Requests 官方文档(英文)
Requests 官方文档(中文)
Beautiful Soup 官方文档
re 官方文档
Scrapy 官方文档(英文)
Scrapy 官方文档(中文)
股票数据 Scrapy 爬虫
介绍:
爬取中国股市的股票信息, 从东方财富网获取股票列表,根据股票列表逐个到百度股票获取个股信息根据股票列表逐个到百度股票获取个股信息,将结果存储到文件将结果存储到文件东方财富网:/stocklist.html百度股票:/stock/单个股票:/stock/sz002439.html
步骤:
建立工程和 Spider 模板
# cmd 依次输入以下命令scrapy startproject scrapy_stockscd scrapy_stocksscrapy genspider stocks
编写Spider,处理链接爬取和页面解析
配置stocks.py文件修改对返回页面的处理修改对新增URL爬取请求的处理
编写ITEM Pipelines,处理信息存储
配置pipelines.py文件定义对爬取项(Scraped Item)的处理类配置ITEM_PIPELINES选项
# 在settings.py文件中配置ITEM_PIPELINES选项,改为自己写的类名ITEM_PIPELINES = {'scrapy_stocks.pipelines.ScrapyStocksPipeline': 300,}
运行爬虫
# cmd输入以下命令scrapy crawl stocks
配置优化
修改 settings.py文件的相应项
stocks.py 文件:
# -*- coding: utf-8 -*-import scrapyimport reclass StocksSpider(scrapy.Spider):name = "stocks"start_urls = ['/stocklist.html']def parse(self, response):"""解析 Response 对象,产生额外的爬取请求"""for href in response.css('a::attr(href)').extract():try:stock = re.findall(r's[hz]\d{6}', href)[0]url = '/stock/' + stock + '.html'yield scrapy.Request(url, callback=self.parse_stock)except:continuedef parse_stock(self, response):"""解析 Response 对象"""info_dict = {}stock_info = response.css('.stock-bets')name = stock_info.css('.bets-name').extract()[0]key_list = stock_info.css('dt').extract()value_list = stock_info.css('dd').extract()for i in range(len(key_list)):key = re.findall(r'>.*</dt>', key_list[i])[0][1:-5]try:val = re.findall(r'\d+\.?.*</dd>', value_list[i])[0][0:-5]except:val = '--'info_dict[key] = valinfo_dict.update({'股票名称': re.findall('\s.*\(', name)[0].split()[0] + re.findall('\>.*\<', name)[0][1:-1]})yield info_dict
pipelines.py 文件:
class BaiduStocksPipeline(object):"""直接返回解析结果"""def process_item(self, item, spider):return itemclass BaiduStocksInfoPipeline(object):"""保存解析结果到文件"""def open_spider(self, spider):self.f = open('BaiduStockInfo.txt', 'w')def close_spider(self, spider):self.f.close()def process_item(self, item, spider):try:line = str(dict(item)) + '\n'self.f.write(line)except:passreturn item
settings.py 文件:
ITEM_PIPELINES = {'scrapy_stocks.pipelines.BaiduStocksInfoPipeline': 300,}