1. 程式人生 > >BeautifulSoup爬蟲之儲存CSV檔案

BeautifulSoup爬蟲之儲存CSV檔案

爬蟲儲存資料到CSV檔案

一.閒話

一般我們寫爬蟲時都會儲存為簡單的text檔案,但是當我們爬取的資料量很大我們想方便統計或者想存長時間儲存 這個時候我們怎麼辦?我們可以儲存資訊為CSV格式 或者直接儲存到資料庫中。python提供了這樣的包給我們!接下來我們以“中彩網往期雙色球資訊”為例給大家演示下如何儲存資訊CSV格式。

二.幹活
依然是爬蟲三部曲:分析網頁獲取目標網址 ,爬取資訊,儲存資訊。
1.分析網頁:
中彩網的網址為:”http://www.zhcw.com/ssq/kaijiangshuju/index.shtml?type=0/” 雙色球往期回顧頁面如下:
這裡寫圖片描述
通過分析發現點選下一頁位址列網址沒有變化資料是動態載入的,如果爬取這一頁只能獲取一頁的資料,顯然這個地址不是最終的地址。我們接著分析網頁原始碼找到我們需要的網址:”

http://kaijiang.zhcw.com/zhcw/html/ssq/list_1.html
依舊是分析網址我們得出他的分頁規律,為我們以後拼接頁數做準備。
2.程式碼
1)日誌檔案

#! -*- encoding:utf-8 -*-

"""
亂碼問題 解決方式一:#! -*- encoding:utf-8 -*-\
            方式二:u'哈哈哈'  字串以unicode格式儲存

"""
import logging
import getpass
import sys

class MyLog(object):
    #構造方法
    def __init__
(self):
self.user=getpass.getuser() self.logger=logging.getLogger(self.user) self.logger.setLevel( logging.DEBUG ) #日誌的級別 critical error warn info debug #定義日誌檔案 self.logFile=sys.argv[0][0:-3]+'.log' # 從命令列引數中取出第一個引數,並取從0開始到 倒數第三個字元 拼接成檔名 self.formatter=logging.Formatter('%(asctime) -12s %(levelname) -8s %(name) -10s %(message)-12s\r\n'
) #日誌輸出的格式 #日誌輸出到檔案 logging有三個內建的Handler, self.logHand=logging.FileHandler(self.logFile, encoding='utf8') self.logHand.setFormatter( self.formatter ) #設定 格式 self.logHand.setLevel( logging.DEBUG ) #設定 級別 #日誌輸出 到螢幕,這是標準輸出流 self.logHandSt=logging.StreamHandler() self.logHandSt.setFormatter( self.formatter ) self.logHand.setLevel( logging.DEBUG ) #將兩個Handler加入到 logger中 self.logger.addHandler( self.logHand ) self.logger.addHandler( self.logHandSt ) #重新定義logger中的日誌輸出的級別的方法 def debug(self,msg): self.logger.debug(msg) def info(self,msg): self.logger.info(msg) def warn(self,msg): self.logger.warn(msg) def error(self,msg): self.logger.error(msg) def critical(self,msg): self.logger.critical(msg) if __name__=='__main__': mylog=MyLog() mylog.debug(u'debug測試') mylog.info(u'info測試') mylog.warn(u'warn測試') mylog.error(u'error測試') mylog.critical(u'critical測試')

2)爬蟲程式碼:

"""
   目標地址:  http://kaijiang.zhcw.com/zhcw/html/ssq/list_60.html
"""

from MyLog import MyLog
import string
from urllib.parse import quote
from urllib import error
import urllib.request
from bs4 import BeautifulSoup
import codecs
import re
from save2excel import SaveBallDate



#爬取出來的資料封裝
class DoubleColorBallItem(object):
    date=None
    order = None 
    red1 = None  
    red2 = None   
    red3 = None  
    red4 = None  
    red5 = None  
    red6 = None  
    blue=None
    money = None  
    firstPrize = None  
    province=None
    secondPrize = None

class GetDoubleColorBallNumber( object ):
    def __init__(self):
        self.urls=[]
        self.log=MyLog()
        #根據pageSum拼裝要爬取的地址
        self.getUrls()
        #開始爬取
        self.items=self.spider(   self.urls )
        #存
        self.pipelines(  self.items )
        #存入excel
        SaveBallDate( self.items)

    def getResponseContent(self,url):
        try:
            url=quote(   url, safe=string.printable )
            response=urllib.request.urlopen(   url )
        except error.URLError as e:
            self.log.error( u'python爬取 %s 出錯了' %url)
            print( e )
        else:
            self.log.info( u'python爬取 %s 成功' %url   )
            return response.read() 

    """
        1. 先獲取頁面上的總頁數
        2.  拼裝 訪問 地址
    """
    def  getUrls(self):
        url=r'http://kaijiang.zhcw.com/zhcw/html/ssq/list_1.html'   #從第一頁中取總頁數
        htmlContent=self.getResponseContent(  url )
        soup=BeautifulSoup( htmlContent,'lxml')
        pTag=soup.find_all(    re.compile('p')      )[-1]
        pages=pTag.strong.getText().strip()
        for i in range( 1, int(pages)-107):
            url=r'http://kaijiang.zhcw.com/zhcw/html/ssq/list_'+ str(i)+ '.html'
            self.urls.append( url )
            self.log.info(  u'新增url %s 到 urls列表中待爬取' %url )



    def spider(  self, urls ):
        items=[]
        for url in urls:
            htmlContent=self.getResponseContent(url)
            soup=BeautifulSoup( htmlContent,'lxml')
            tags=soup.find_all('tr',attrs={})
            for tag in tags:
                if tag.find('em'):
                    item=DoubleColorBallItem()
                    tagTd=tag.find_all('td')
                    item.date=tagTd[0].get_text().strip()
                    item.order=tagTd[1].get_text().strip()
                    tagEms=tagTd[2].find_all('em')
                    item.red1=tagEms[0].get_text().strip()
                    item.red2=tagEms[1].get_text().strip()
                    item.red3=tagEms[2].get_text().strip()
                    item.red4=tagEms[3].get_text().strip()
                    item.red5=tagEms[4].get_text().strip()
                    item.red6=tagEms[5].get_text().strip()
                    item.blue=tagEms[6].get_text().strip()
                    item.money=tagTd[3].find('strong').get_text().strip()
                    item.firstPrize=tagTd[4].find('strong').get_text().strip()
                    item.province=tagTd[4].get_text().strip()
                    item.secondPrize=tagTd[5].find('strong').get_text().strip()
                    items.append( item )
                    self.log.info( u'爬取時間為 %s 的資料成功' %(item.date))       
        return items



    def pipelines(  self, items  ):
        fileName=u'雙色球中獎資訊.txt'
        with codecs.open( fileName,'w','utf8') as fp:
            for item in items:
                fp.write('%s %s \t %s %s %s %s %s %s %s \t %s %s %s %s \n' %(item.date,item.order,item.red1,item.red2,item.red3,item.red4,item.red5,item.red6,item.blue,item.money,item.firstPrize,item.province,item.secondPrize)) 
                self.log.info(   u'期數為 %s 的雙色球資訊儲存成功' %(item.order) )

if __name__=='__main__':
     gbn=GetDoubleColorBallNumber()

3)今天的重點—->儲存為CSV檔案
python 提供了xlrd,xlwt兩個模組給我們讀寫CSV檔案具體的用法請檢視他的api(未安裝記得安裝:pip install xlwt)我這裡只講實戰 嘻嘻!

#! -*- encoding:utf-8 -*-
import xlrd
import xlwt
import os
import sys

class SaveBallDate(object):
    def __init__(self,items):
        self.items=items
        self.run(self.items)

    def run(self,items):
        fileName='hello.csv'
        #建立工作簿
        book=xlwt.Workbook(encoding='utf8')
        sheet=book.add_sheet('ball',cell_overwrite_ok=True)

        #寫入
        sheet.write(0,0,u'開獎日期')
        sheet.write(0,1, u'期號')
        sheet.write(0,2, u'紅球1')
        sheet.write(0,3, u'紅球2')
        sheet.write(0,4, u'紅球3')
        sheet.write(0,5, u'紅球4')
        sheet.write(0,6, u'紅球5')
        sheet.write(0,7, u'紅球6')
        sheet.write(0,8, u'藍球')
        sheet.write(0,9, u'銷售金額')
        sheet.write(0,10, u'一等獎')
        sheet.write(0,11, u'中獎省份')
        sheet.write(0,12, u'二等獎')

        i=1
        while i<len(items):
            item=items[i-1]
            sheet.write(i,0,item.date)
            sheet.write(i, 1, item.order)
            sheet.write(i, 2, item.red1)
            sheet.write(i, 3, item.red2)
            sheet.write(i, 4, item.red3)
            sheet.write(i, 5, item.red4)
            sheet.write(i, 6, item.red5)
            sheet.write(i, 7, item.red6)
            sheet.write(i, 8, item.blue)
            sheet.write(i, 9, item.money)
            sheet.write(i, 10, item.firstPrize)
            sheet.write(i, 11, item.province)
            sheet.write(i, 12, item.secondPrize)
            i+=1
        book.save(fileName)

結果:
這裡寫圖片描述

記得匯入from save2excel import SaveBallDate以及在init函式新增儲存CSV的函式
這裡寫圖片描述

下一次我們講解如何將爬取的資料儲存到mysq資料庫當中!!!