股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

时间:2024-05-19 10:48:44

Scrapy

中文名:抓取

一个功能强大、快速、优秀的第三方库

它是软件结构与功能组件的结合,可以帮助用户快速实现爬虫。

Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。

Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、sitemap爬虫等,最新版本又提供了web2.0爬虫的支持。

框架安装

使用管理员权限启动command控制台

\>pip install scrapy

测试安装

输入指令查看所有scrpy命令

\>scrapy -h

出现以下界面则可视为安装成功

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

我们还可以通过指令查看帮助信息:

\>scrapy --help

命令提示符输出如下:

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

Scrapy框架常用命令:

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

我们本次实验只用到了startprojectgenspidercrawl命令

Scrapy“5+2”框架结构

5个主体部分:

  已有的功能实现:

                 Engine 控制模块间的数据流、根据条件触发事件

                 Schedule 对所有爬取请求进行调度

                 Downloader 根据请求下载网页

  需要配置实现:

                 Spiders 解析返回的响应、产生爬取项与新的爬取请求 

                 Item Pipelines 清理、检验和查重爬取项中的数据与数据存储

2个中间键(可配置)

                SpiderMiddleware 修改、丢弃、新增请求或爬取项 

                 Downloader Middleware 修改、丢弃、新增请求或响应

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

1.  SpidersEngine发送网页信息爬取请求     

2.  SchedulerEngine接收爬取请求并进行调度

3,4.  EngineScheduler获得下一个网页信息爬取请求,通过中间键发送给Downloader

5,6.  Downloader连接互联网爬取网页内容,形成响应(爬取内容)通过中间键与Engine发送给Spiders

7.  Spiders处理获得的响应(爬取内容),形成爬取项与新的网页信息爬取请求发送给Engine

8.  Engine将爬取项发送给Item Pipelines,将新的爬取请求发送给Scheduler进行调度,形成循环为数据处理与再次启动爬虫进行爬取提供数据。

功能概述:

·      技术:Scrapy
·      目标:获取上交所和深交所的股票名称与交易信息
·      输出:txt文档

获取股票列表:

·      东方财富网:http://quote.eastmoney.com/stocklist.html

获取个股信息:

·      股市通:https://gupiao.baidu.com/stock/sz002338.html

过程概述:

1.   编写spider爬虫处理链接的爬取和网页解析

2.   编写pipeline处理解析后的股票数据并存储

具体流程

·      相关安装

使用管理员权限启动command控制台

\>pip install requests

\>pip install scrapy

====================================

接下来的工程我刚开始运行失败,后通过以下四步才得以运行

(视个人情况而定)

#先卸载scrapy框架

1. pip uninstall scrapy  

#再卸载twisted框架

2. pip uninstall twisted 

重新安装scrapy以及16.6.0版本的twisted

 #先安装twisted框架

3. pip install twisted==16.6.0  

#再安装scrapy--no-deps指不安装依赖的twisted

4. pip  install scrapy--no-deps 

如仍不能运行可能需要安装pywin32模块

\>pip install pywin32

·      建立工程和Spider模板

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

1. 转到目标目录

\>d:
\>cd pycodes

:目录位置不限定)

2. 生成BaiduStocks项目

\>scrapy startproject BaiduStocks

3. 修改当前目录

\>cd BaiduStocks

4. 生成stocks爬虫

\>scrapy genspider stocks baidu.com

·      编写spider

配置stocks.py

修改对返回页面与新增的URL爬取请求的处理,使其解析返回的信息

  1. import scrapy  
  2. import re  # 引入正则表达式库  
  3.   
  4.   
  5. class StocksSpider(scrapy.Spider):  
  6.     name = "stocks"  
  7.     # 设置初始链接为股票列表页面链接  
  8.     start_urls = ['http://quote.eastmoney.com/stocklist.html']  
  9.   
  10.   
  11.     def parse(self, response):  # 获取页面中股票代码并生成对应股票页面链接  
  12.         # for循环提取页面中所有<a>标签中的链接  
  13.         for href in response.css('a::attr(href)').extract():  
  14.             # 使用try...except忽略错误信息  
  15.             try:  
  16.                 # 通过正则表达式获取股票代码  
  17.                 stock = re.findall(r"[s][hz]\d{6}", href)[0]  
  18.                 # 生成对应股票代码的页面链接  
  19.                 url = 'https://gupiao.baidu.com/stock/' + stock + '.html'  
  20.                 # 使用yield将函数定义为生成器将新请求重新提交给scrapy  
  21.                 yield scrapy.Request(url, callback=self.parse_stock)  
  22.             except:  
  23.                 continue  
  24.   
  25.   
  26.     def parse_stock(self, response):  # 从对应股票代码的页面提取信息  
  27.         infoDict = {}  # 生成空字典  
  28.         stockInfo = response.css('.stock-bets')  # 找到属性为"stock-bets"的区域  
  29.         # 在区域中检索"bets-name"属性提取股票名称  
  30.         name = stockInfo.css('.bets-name').extract()[0]  
  31.         # 提取股票中的其他信息存储为键值对  
  32.         keyList = stockInfo.css('dt').extract()  
  33.         valueList = stockInfo.css('dd').extract()  
  34.         for i in range(len(keyList)):  # 将提取到的股票信息保存在字典中  
  35.             key = re.findall(r'>.*</dt>', keyList[i])[0][1:-5]  
  36.             try:  
  37.                 val = re.findall(r'\d+\.?.*</dd>', valueList[i])[0][0:-5]  
  38.             except:  
  39.                 val = '--'  
  40.             infoDict[key] = val  
  41.   
  42.         # 保存对应股票代码的股票页面中的股票名称和相关信息  
  43.         infoDict.update(  
  44.             {'股票名称': re.findall('\s.*\(', name)[0].split()[0] + \  
  45.                      re.findall('\>.*\<', name)[0][1:-1]})  
  46.         # 使用yield将函数定义为生成器传递信息给后续处理的pipeline模块  
  47.         yield infoDict  


·      编写Pipelines

配置pipelines.py

定义对爬取项的处理类

  1. # -*- coding: utf-8 -*-  
  2.   
  3. # Define your item pipelines here  
  4. #  
  5. # Don't forget to add your pipeline to the ITEM_PIPELINES setting  
  6. # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html  
  7.   
  8.   
  9. class BaidustocksPipeline(object):  
  10.     def process_item(self, item, spider):  
  11.         return item  
  12.   
  13.   
  14. class BaidustocksInfoPipeline(object):  # 尝试定义新类  
  15.     def open_spider(self, spider):  # 爬虫调用时,对应启动的方法  
  16.         self.f = open('BaiduStockInfo.txt''w')  # 打开文件  
  17.   
  18.     def close_spider(self, spider):  # 爬虫关闭时,对应启动的方法  
  19.         self.f.close()  # 关闭文件  
  20.   
  21.     def process_item(self, item, spider):  # 对item项的处理方法  
  22.         try:  
  23.             line = str(dict(item)) + '\n'  
  24.             self.f.write(line)  # 把每一个股票的字典信息写入文件中  
  25.         except:  
  26.             pass  
  27.         return item  # 让其他函数也可以处理当前item  

 

·      配置ITEM_PIPELINES选项

settings.py找到以下代码块

  1. # ITEM_PIPELINES = {  
  2. #    'BaiduStocks.pipelines.BaidustocksPipeline': 300,  
  3. # }  

将指向的pipelines修改为刚才定义的处理类BaidustocksInfoPipeline

  1. ITEM_PIPELINES = {  
  2.     'BaiduStocks.pipelines.BaidustocksInfoPipeline'300,  
  3. }  
·      运行爬虫

使用管理员权限启动command控制台

修改当前路径:

\>d:

\>cd pycodes

\>cd BaiduStocks

运行爬虫

\>scrapy crawl stocks

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

运行结束会在BaiduStocks文件夹生成BaiduStockInfo.txt

内容如下

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

我们还可以采用Beautiful Soup库与Requests库通过requests-bs4-re技术路线制作股票数据爬虫

Beautiful soup

BeautifulSoup是Python的一个库,最主要的功能就是从网页爬取我们需要的数据。BeautifulSoup将html解析为对象进行处理,全部页面转变为字典或者数组,相对于正则表达式的方式,可以大大简化处理过程。

BeautifulSoup默认支持Python的标准HTML解析库,但是它也支持一些第三方的解析库:

解析库

使用方法

优势

劣势

Python标准库

BeautifulSoup(html,’html.parser’)

Python内置标准库;执行速度快

容错能力较差

lxml HTML解析库

BeautifulSoup(html,’lxml’)

速度快;容错能力强

需要安装,需要C语言库

lxml XML解析库

BeautifulSoup(html,[‘lxml’,’xml’])

速度快;容错能力强;支持XML格式

需要C语言库

htm5lib解析库

BeautifulSoup(html,’htm5llib’)

以浏览器方式解析,最好的容错性

速度慢

 

Requests

目前公认的爬取网页最好的第三方库

简单,简洁,甚至只用一行代码就可以从网页上获得相关资源

Requests库的七个主要方法:

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

具体实现

安装相关库,使用管理员权限启动command控制台

\>pip install beautifulsoup4

\>pip install requests

测试安装Requests

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

出现以下界面则可视为成功安装Requests

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

测试安装Beautiful Soup

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

出现以下界面即可视为安装成功Beautiflu Soup

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

·      代码实现

  1. import requests  
  2. from bs4 import BeautifulSoup  
  3. import traceback  # 引用traceback库方便调试  
  4. import re  
  5.   
  6.   
  7. # 获得url对应的页面,第二个参数为编码方式  
  8. def getHTMLText(url, code="utf-8"):  
  9.     try:  # 使用try...except规避错误信息  
  10.         r = requests.get(url)  # 通过get函数获取url信息  
  11.         r.raise_for_status()  # 产生异常信息  
  12.         r.encoding = code  # 直接修改编码方式提高效率  
  13.         return r.text  # 将信息返回给程序的其他部分  
  14.     except:  
  15.         return ""  # 出现错误则返回空字符串  
  16.   
  17.   
  18. def getStockList(lst, stockURL):  
  19.     # 获得股票的信息列表,第一个参数为列表类型,第二个为获得信息的url  
  20.     html = getHTMLText(stockURL, "GB2312")  # 获得股票列表页面  
  21.     # 使用beautifulsoup解析页面  
  22.     soup = BeautifulSoup(html, 'html.parser')  
  23.     a = soup.find_all('a')  # 找到页面中所有<a>标签  
  24.     for i in a:  
  25.         try:  # 使用try...except规避错误信息  
  26.             href = i.attrs['href']  # 找到<a>标签中所有href属性  
  27.             # 分析源代码通过正则表达式获得每只股票代码并存储到lst  
  28.             lst.append(re.findall(r"[s][hz]\d{6}", href)[0])  
  29.         except:  
  30.             continue  
  31.   
  32.   
  33. # 第一参数为保存信息的列表,第二为获取信息的url,第三为存储信息的文件路径  
  34. def getStockInfo(lst, stockURL, fpath):  # 获得每一只股票的信息并存储  
  35.     count = 0  
  36.     for stock in lst:  # 获取每一只股票代码  
  37.         url = stockURL + stock + ".html"  # 构造具体股票页面url  
  38.         html = getHTMLText(url)  # 获取具体股票页面信息  
  39.         try:  # 使用try...except规避错误信息  
  40.             if html == "":  # 判断是否为空页面  
  41.                 continue  
  42.             infoDict = {}  # 生成空字典  
  43.             # 构建解析网页的类型  
  44.             soup = BeautifulSoup(html, 'html.parser')  
  45.             # 找到属性为"stock-bets"的区域  
  46.             stockInfo = soup.find('div', attrs={'class''stock-bets'})  
  47.             # 在区域中检索"bets-name"属性提取股票名称  
  48.             name = stockInfo.find_all(attrs={'class''bets-name'})[0]  
  49.             # 将提取到的股票名称保存在字典中  
  50.             infoDict.update({'股票名称': name.text.split()[0]})  
  51.             # 提取股票中的其他信息并存储为键值对形式  
  52.             keyList = stockInfo.find_all('dt')  
  53.             valueList = stockInfo.find_all('dd')  
  54.             for i in range(len(keyList)):  # 将股票其他信息存入字典  
  55.                 key = keyList[i].text  
  56.                 val = valueList[i].text  
  57.                 infoDict[key] = val  
  58.             # 将信息保存到制定目录文件  
  59.             with open(fpath, 'a', encoding='utf-8') as f:  
  60.                 f.write(str(infoDict) + '\n')  
  61.                 count = count + 1  
  62.                 # 显示当前爬取进度百分比提高用户体验  
  63.                 print("\r当前进度: {:.2f}%".format(count * 100 / len(lst)), end="")  
  64.         except:  
  65.             count = count + 1  
  66.             print("\r当前进度: {:.2f}%".format(count * 100 / len(lst)), end="")  
  67.             continue  
  68.   
  69.   
  70. def main():  
  71.     # 获取股票列表的url  
  72.     stock_list_url = 'http://quote.eastmoney.com/stocklist.html'  
  73.     # 获取每一只股票具体信息的初始url  
  74.     stock_info_url = 'https://gupiao.baidu.com/stock/'  
  75.     # 输出文件的保存路径  
  76.     output_file = 'D:/BaiduStockInfo.txt'  
  77.     slist = []  # 股票信息变量  
  78.     getStockList(slist, stock_list_url)  # 获得股票列表  
  79.     getStockInfo(slist, stock_info_url, output_file)  # 获取相关股票信息并存储  
  80.   
  81.   
  82. # 执行主函数  
  83. main()  

 

在这里我们尝试使用PyCharm运行这个程序

PyCharm是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制。此外,该IDE提供了一些高级功能,以用于支持Django框架下的专业Web开发。

首先我们需要新建工程

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

输入工程名点确定

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

在工程中点击右键新建python文件

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

输入python文件名,点击保存

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

导入bs4库与requests库

1.点击File->settings 

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

2.选择Project Interpreter,点击右边绿色的加号添加包 

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

3.输入你想添加的包名,点击Install Package

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

4.可以在Pycharm保存项目的目录下查看已经安装的包,路径D:\PycharmProjects\untitled\venv\Lib\site-packages(大致路径)

5.配置完成后,输入程序代码,点击上方的Run即可运行程序

股票数据爬虫(Scrapy框架与requests-bs4-re技术路线)

BeautifulSoup库与Requests框架通过requests-bs4-re技术路线实现的爬虫执行速度相对较慢。

总结

      通过本次Python实验,我学习到了第三方库的安装与使用,深化了对PyCharm及IDLE的使用,对Scrapy框架、BeautifulSoup库与Requests框架以及requests-bs4-re技术路线有了进一步的认识,对正则表达式的编写和Python的程序结构也有了更深入的了解,增加了Python的编程经验。