python爬蟲之Scrapy爬取股票信息的示例

python爬蟲之Scrapy的使用步驟

  • 首先講講教程的例子,還是以百度股票爲例子進行講解
Scrapy的使用步驟
  • 建立工程和Spider模版
  • 編寫Spider
  • 編寫ITEM Pipelines
前請回顧
  • 首先回顧一下爬取股票數據的相關的知識點和思路
    • 基本思路:從東方財富網獲取所有股票的代碼,然後在組成新的百度網網頁,跳轉到對應的列表中爬取對應的信息
    • 先看看,東方財富的網頁,篩選的正則表達式:r’[zh|sh]\d{6}’

在這裏插入圖片描述

  • 再看看單個股票網頁的網址,只需要在對應的網頁加上對應的股票編碼就可以獲得
    在這裏插入圖片描述

  • 最後再看看但個網頁的股票的具體的價格信息,分別在對應的dd和tt標籤中,名稱在屬性爲“bets—name”的屬性中

在這裏插入圖片描述

具體編寫
第一步、建立工程和Spider模版
  • 在控制檯輸入如下指令
  • 創建對應的scrapy工程: scrapy startproject BaiduStocks
    在這裏插入圖片描述
  • 切換到創建的工程目錄下:cd BaiduStocks
    在這裏插入圖片描述
  • 創建相關的爬蟲:scrapy genspider stocks baidu.com

在這裏插入圖片描述

第二步、編寫對應的Spider工具
  • 配置stocks.py文件,確定你需要爬取的具體的信息
  • 修改對返回頁面的處理
  • 修改對新增的URL爬取請求的處理

首先打開如下位置的文件
在這裏插入圖片描述
分析:
根據功能請求,總共爬取兩類網站,所以最基本的得寫針對兩類網站的爬取代碼

  • 部分一:爬取東方財富網的所有股票的信息地址
    • css().extract()是返回對應的所有的標籤內部的值,關於css用法,詳見 https://www.jianshu.com/p/278a4ca6d0c1 覺得還不錯
    • yield生成器,生成的是request對象,專門給downloader進行處理
    • callback指明對應的返回response對象,處理的函數
def parse(self, response):
    for href in response.css('a::attr(href)').extract():
        # 提取其中所有的a標籤,並獲取其中href連接
        try:
            stock = re.findall(r'[s][hz]\d{6}',href)[0]
            # 通過正則表達式,獲得相關的股票的代碼
            url = 'https://gupiao.baidu.com/stock/' + stock + '.html'
            # 生成百度股票的html網頁
            yield scrapy.Request(url,callback=self.parse_stock)
            # 根據生成的網頁在生成相關的request對象,以供downloader進行下載
            # callback是指定相應的函數類型
        except:
            continue
  • 部分二:爬取百度股票網的單個網頁的具體的信息
    • 指明當前函數的生成對象,非requests就是item,指明字典類默認就是給ITEM pipeline進行處理了
    • stockInfo = response.css(’.stock-bets’),找到對應的具有stock-bets的屬性的標籤,返回的是selector對象
    • name = stockInfo.css(’.bet-name’).extract()[0],借用上面的selector對象,然後返回所有的具有bet-name屬性的標籤的值組成的列表
    • keyList= stockInfo.css(‘dt’).extract()
      valueList = stockInfo.css(‘dd’).extract(),就分別返回的是dt和dd標籤的值組成的列表
    • 字典的update函數有些忘記:在這裏插入圖片描述

代碼如下:

# 定義指定的處理的信息
def parse_stock(self,response):
    infoDict = {}
    # 返回的信息是交給itempipeline進行處理的,所以用字典的信息進行存儲
    stockInfo = response.css('.stock-bets')
    name = stockInfo.css('.bet-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]
        try:
            val = re.findall(r'\d+\.?.*</dd>',valueList[i])[0]
        except:
            val = '--'
        infoDict[key] = val

    # 一個字典條目,增加一個股票名稱
    infoDict['股票名稱'] = re.findall('\s.*\(',name)[0].split()[0] + re.findall('\>.*\<',name)[0]

    yield infoDict
    # 將生成的item給itemPipeLine進行處理
總的代碼
import scrapy
import re


class StocksSpider(scrapy.Spider):
    name = 'stocks'
    start_urls = ['http://quote.eastmoney.com/stocklist.html']
    # 是先從東方財富網獲得每個股票的代碼,然後生成和百度股票相關的url連接

    def parse(self, response):
        for href in response.css('a::attr(href)').extract():
            # 提取其中所有的a標籤,並獲取其中href連接
            try:
                stock = re.findall(r'[s][hz]\d{6}',href)[0]
                # 通過正則表達式,獲得相關的股票的代碼
                url = 'https://gupiao.baidu.com/stock/' + stock + '.html'
                # 生成百度股票的html網頁
                yield scrapy.Request(url,callback=self.parse_stock)
                # 根據生成的網頁在生成相關的request對象,以供downloader進行下載
                # callback是指定相應的函數類型
            except:
                continue


    # 定義指定的處理的信息
    def parse_stock(self,response):
        infoDict = {}
        # 返回的信息是交給itempipeline進行處理的,所以用字典的信息進行存儲
        stockInfo = response.css('.stock-bets')
        name = stockInfo.css('.bet-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]
            try:
                val = re.findall(r'\d+\.?.*</dd>',valueList[i])[0]
            except:
                val = '--'
            infoDict[key] = val

        # 更新股票的名稱
        infoDict.update({
            '股票名稱':re.findall('\s.*\(',name)[0].split()[0] + \
            re.findall('\>.*\<',name)[0]
        })
        yield infoDict
        # 將生成的item給itemPipeLine進行處理
第三步、編寫ITEM pipelines
  • 配置匹配pipelines.py文件
  • 定義對爬取項的處理類
  • 在settings中配置相關的ITEM_PIPELINES選項,確保scrapy可以自動找到對應的item處理類

代碼如下:

  • 主要有三個方法,傳入相關的爬蟲時,自動打開對應的寫入的文件,結束爬蟲時,自動關閉文件,以及對文件的具體寫入
  • 分別是open_spider,close_spider和process_item
# -*- 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


# 下面的每一個類都是對一個item類進行處理的過程
class BaidustocksPipeline:
    def process_item(self, item, spider):
        return item

# 定義一個專門用來處理的infoDict的方法
class BaidustocksInfoPipeline(object):
    def open_spider(self,spider):
        self.f = open('BaiduStocksInfo.txt','w')

    def close_spider(self,spider):
        self.f.close()

    # 最核心的,對每一個item的處理方法
    def process_item(self,item,spider):
        try:
            line = str(dict(item)) + '\n'
            self.f.write(line)
        except:
            pass
        return item
        # 如果需要別的函數也可以操作對應的item,就需要返回item對象

這一步千萬別忘記,要給系統看的說明書中加上你寫的pipeline類

在這裏插入圖片描述
在這裏插入圖片描述

總結
  • 雖然很想繼續做下去,學下去,但是,真的很煩,作業好多,又要開始複習了
  • 這個教程應該沒有將scrapy框架作爲重點,我應該再繼續學習對應的框架內容,好在以後的內容中用於實戰
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章