iT邦幫忙

DAY 21
3

用python擷取網頁上的開放資訊(數據資料),分析及畫出圖表系列 第 22

Scrapy(三):學XPATH的好工具:Scrapy Shell及將爬得的資料寫回SQLITE3

1。下XPATH指令, 馬上看到過濾後的結果,即時的效果,提高效率。

2。用框架,或不用框架,隨著想抓的資料愈來愈多,這時原來沒有規畫過的問題,就浮現了。
用了框架後,發現很多程式的連接,框架在底層都做掉了,使用者只須按規定,把程式碼放到指定的
位置,這是省力之處,也會讓USER覺得到處存有謎題。
在指令列下

在家裏提到:

timloo@timloo-home:~$ scrapy shell 'http://www.twse.com.tw/ch/trading/indices/MI_5MINS_HIST/MI_5MINS_HIST.php?myear=102&mmon=09'

其中特別注意當網址有**?myear=102&mmon=09時,要用單引號框起來,
遇到
&**時,會把後面的字截掉,這個bug找了筆者大半夜。
畢竟網上的範例,都是沒有單引號的範例。

再來就可以試XPATH了,

In [49]: tbls=hxs.select('//table[3]')

In [50]: for tr in tbls.select('.//tr'):
   ....:     print tr.extract()
   ....:     

可以分段試,hxs物件,就是一切好用的開始,

HtmlXPathSelector提到:
[s] hxs <HtmlXPathSelector xpath=None data=u'<title>TWSE \u81fa\u7063\u8b49\u5238\u4ea4\u6613\u6240 \ufe65\u4ea4\u6613\u8cc7\u8a0a \ufe65'>

hxs.select('//table[3]')
在select 裏下語法。
**//table[3]**是整個html檔裏,排在第三個的table.

select('.//tr'), 注意那個點,跟檔案目錄指令一樣,表示目前的位置,
目前在那裏呢?以這個範例,是在第三個的table。

可以一段定位,再一段定位,

In [52]: for tr in tbls.select('.//tr'):
   ....:     for td in tr.select('.//td/text()'):
   ....:         print td.extract()
   ....:         

同裏,找到某一列時,也可以對欄位定位,定出第一個,第二個,第三個,
tr.select('.//td[2]/text()'):

一個怪異的現象:

 def parse(self, response):        
        x = HtmlXPathSelector(response)

        t01 = Twse01Item()
        tbls = x.select('//table[3]')
        for tr in tbls.select('.//tr'):
            for td1 in  tr.select('.//td[1]/text()'):  #用for 寫
                print td1.extract()
                t1=td1.extract()[0]
                t01['ymd']=t1
            for td2 in  tr.select('.//td[2]/text()'): #用for 寫
                print td2.extract()
                t2=td2.extract()[0].strip().replace(',','')
                t01['openi']=t2
            td3 = tr.select('.//td[3]/text()')       #不用for 寫
            print td3.extract()
            td4 = tr.select('.//td[4]/text()')
            print td4.extract()
            td5 = tr.select('.//td[5]/text()')
            print td5.extract()
        #print dt
        #article['summary'] = x.select("//p/text()").extract()

        return dt
---------------------------------------
日期
開盤指數
[u'\u6700\u9ad8\u6307\u6578']    ##不用for 寫的輸出效果
[u'\u6700\u4f4e\u6307\u6578']
[u'\u6536\u76e4\u6307\u6578']
 102/09/02
 8,010.15
[u' 8,052.71']
[u' 7,993.13']
[u' 8,038.86']

再來是議題2,這真是痛苦的經驗,
Scrapy,有一個Item Pipeline的好用界面,
理想情況,在spider裏,用XPATH解析出的資料,由底層程式,送來這裏,就可以把data寫回
資料庫。
底層怎麼送的,一般USER並不清楚,
筆者也試了大半天,參考一些人的做法,總是試不出效果。

那很杜爛,就把寫SQLITE3的程式碼,放在spider裏,
雖然可以work, 那就把框架的精神破壞了,
又把不同任務的程式放在同一程式檔裏

    def parse(self, response):        
        x = HtmlXPathSelector(response)
        items = []
        i=0
        t01 = Twse01Item()
        tbls = x.select('//table[3]')
        for tr in tbls.select('.//tr'):
            i=i+1
            if i>1 :
                for td1 in  tr.select('.//td[1]/text()'):
                    print td1.extract()
                    t1=td1.extract()#[0]
                    t01['ymd']=t1.strip()
                for td2 in  tr.select('.//td[2]/text()'):
                    print td2.extract()
                    t2=td2num(td2.extract())#[0].strip().replace(',','')
                    t01['openi']=t2
                for td3 in  tr.select('.//td[3]/text()'):
                    print td3.extract()
                    t3=td2num(td3.extract())#[0].strip().replace(',','')
                    t01['highi']=t3
                for td4 in tr.select('.//td[4]/text()'):
                    print td4.extract()
                    t4=td2num(td4.extract())#[0].strip().replace(',','')
                    t01['lowi']=t4
                for td5 in tr.select('.//td[5]/text()'):
                    print td5.extract()
                    t5=td2num(td5.extract()) #[0].strip().replace(',','')
                    t01['closei']=t5
                print t01
                self.cur.execute("insert into index01  values  (?,?,?,?,? )", 
                         (t01['ymd'],t01['openi'],t01['highi'],t01['lowi'],t01['closei']))#不該放這裏,筆者真無奈

                items.append(t01)
                #return t01
        self.conn.commit() #不該放這裏,筆者真無奈
                

畢竟筆者己經卡得有點不耐煩了。所以先很醜的做一下。


上一篇
Scrapy(二):實作上的一些議題討論
系列文
用python擷取網頁上的開放資訊(數據資料),分析及畫出圖表22
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言