[Python crawler]爬蟲教學-Part1

  • 4285
  • 0
  • 2019-05-08

基於大數據議題越來越火熱,而數據取得變得非常重要,如果使用企業提供資料就不用煩惱這問題,

但像我預測各大運動賽事賽果,網路上都可以取得,而且是非常詳細之數據(重點是幫公司省錢阿) 。

因此這系列文章會介紹大家如果使用python來爬取網站,也會直接拿實例作示範。

 

開始前,先灌輸給大家一些爬網的觀念

  • 當有禮貌的爬蟲家, 不要傳送密集大量的請求以免造成伺服器壓力過大。
  • 如上述,當我對此網站有大量需求,本身會設定time.sleep間隔。
  • 只抓取網站需求資料,而並非為了方便全部抓取,要的是深度而非廣度。
  • 你所寫得爬蟲程式碼,並非能一直作業,一旦網站調整網頁結構,就需要調整。

#事前準備

  • python2.7
  • package:BeautifulSoup
  • 爬取網站:http://www.basketball-reference.com/boxscores/201611230BRK.html
  • 爬取內容:如下圖

#程式碼

import cx_Oracle
import requests
from bs4 import BeautifulSoup

NBA_url='http://www.basketball-reference.com/boxscores/201611230BRK.html'
res=requests.get(NBA_url)
soup=BeautifulSoup(res.text)
#print soup

#step1
Bos_Basic=soup.findAll('div',{'id':'all_box_bos_basic'})[0].findAll('tbody')
print Bos_Basic

Step1解說:

1.res=requests.get(NBA_url)

  • 選取你要爬取網頁,透過HTTP協定中的get方法送出一個請求(Request)到遠端的伺服器(Server),伺服器接受請求後,就會回應(Response)並回傳網頁內容(原始碼)的檔案回來

2.soup=BeautifulSoup(res.text)

  • 我們將內容(原始碼)套入BeautifulSoup方法,已利於我們做Regular expression來判斷與過濾
  • 你可以print出來看看裡面的架構,他就是網頁所有的內容(這邊我先注解掉了)

3.這網頁的表格這麼多,我只要爬取我想要的表格,就必須要知道這表格的原始碼在哪一段,如下圖1

4.從圖1得知id=all_box_bos_basic,圖2得知整個資料都放在tbody架構裡,利用findAll方法,我們把這些資料抓出來,一樣可以pinrt出來看一下內容(這邊就不展示了)

#step2
NBA_data=[]
Play_stat_row=Bos_Basic[0].findAll('tr')
for i in range(0,len(Play_stat_row)):
    if i==5:
        pass
    else:
        print Play_stat_row[i].text

Step2解說:

1.上一步驟你抓出來的只事表格架構原始碼,那接下來就是把你想要的數據資料給抓出來了

2.Play_stat_row這邊我需要知道這張表的ROW的長度(也就是幾列,從上圖看會比較清楚)

3.用for迴圈把整個資料給印出來,這邊有設條件限制是因為表中間那一行沒數字的我不要

Output:

Avery Bradley33:441022.45517.14312.5001671502322
Isaiah Thomas31:49821.38159.556221.0000115012123
Al Horford30:24712.58334.750001458122217
Jae Crowder22:17611.54537.42901.0001451000215
Amir Johnson18:5012.5000000279100122
Marcus Smart30:39210.20004.00000268821124
Terry Rozier22:4134.75001.00000156120126
Kelly Olynyk19:1139.33325.400221.0001121201410
Jonas Jerebko16:30441.000111.000111.0001010101210
Tyler Zeller7:5212.5000000134002012
Jaylen Brown4:2801.0000000123000210
James Young1:35000000000000000
​#step3
NBA_Team_data=[]
for i in range(0,len(Play_stat_row)):
    NBA_Player_data=[]
    NBA_Player_Stat=Bos_Basic[0].findAll('tr')[i].findAll('td')
    NBA_Play_name=Bos_Basic[0].findAll('tr')[i].findAll('th')
    for j in range(0,len(Play_stat_col)):
        if i==5:
            pass
        else:       
            NBA_Player_data.append(NBA_Player_Stat[j].text)
    NBA_Player_data.insert(0,NBA_Play_name[0].text)
    NBA_Team_data.extend([NBA_Player_data])
print NBA_Team_data

​

 Step3:

1.上一步驟Output結果有沒有發現數字全部都擠在一塊,那是因為你一次取一列整個列出來,並未將每一列再切割成每一欄位

2.從下圖3紅色框部分,我們把tr展開來,可以看到td框架,這就是我們要的欄位 ,並進行動作=>NBA_Player_Stat=Bos_Basic[0].findAll('tr')[i].findAll('td')

3.我們發現球員名稱是在th框架,進行動作=>NBA_Play_name=Bos_Basic[0].findAll('tr')[i].findAll('th')

Output:

[[u'Avery Bradley', u'33:44', u'10', u'22', u'.455', u'1', u'7', u'.143', u'1', u'2', u'.500', u'1', u'6', u'7', u'1', u'5', u'0', u'2', u'3', u'22'], 
[u'Isaiah Thomas', u'31:49', u'8', u'21', u'.381', u'5', u'9', u'.556', u'2', u'2', u'1.000', u'0', u'1', u'1', u'5', u'0', u'1', u'2', u'1', u'23'], 
[u'Al Horford', u'30:24', u'7', u'12', u'.583', u'3', u'4', u'.750', u'0', u'0', u'', u'1', u'4', u'5', u'8', u'1', u'2', u'2', u'2', u'17'], 
[u'Jae Crowder', u'22:17', u'6', u'11', u'.545', u'3', u'7', u'.429', u'0', u'1', u'.000', u'1', u'4', u'5', u'1', u'0', u'0', u'0', u'2', u'15'], 
[u'Amir Johnson', u'18:50', u'1', u'2', u'.500', u'0', u'0', u'', u'0', u'0', u'', u'2', u'7', u'9', u'1', u'0', u'0', u'1', u'2', u'2'], 
[u'Marcus Smart', u'30:39', u'2', u'10', u'.200', u'0', u'4', u'.000', u'0', u'0', u'', u'2', u'6', u'8', u'8', u'2', u'1', u'1', u'2', u'4'], 
[u'Terry Rozier', u'22:41', u'3', u'4', u'.750', u'0', u'1', u'.000', u'0', u'0', u'', u'1', u'5', u'6', u'1', u'2', u'0', u'1', u'2', u'6'], 
[u'Kelly Olynyk', u'19:11', u'3', u'9', u'.333', u'2', u'5', u'.400', u'2', u'2', u'1.000', u'1', u'1', u'2', u'1', u'2', u'0', u'1', u'4', u'10'], 
[u'Jonas Jerebko', u'16:30', u'4', u'4', u'1.000', u'1', u'1', u'1.000', u'1', u'1', u'1.000', u'1', u'0', u'1', u'0', u'1', u'0', u'1', u'2', u'10'], 
[u'Tyler Zeller', u'7:52', u'1', u'2', u'.500', u'0', u'0', u'', u'0', u'0', u'', u'1', u'3', u'4', u'0', u'0', u'2', u'0', u'1', u'2'], 
[u'Jaylen Brown', u'4:28', u'0', u'1', u'.000', u'0', u'0', u'', u'0', u'0', u'', u'1', u'2', u'3', u'0', u'0', u'0', u'2', u'1', u'0'], 
[u'James Young', u'1:35', u'0', u'0', u'', u'0', u'0', u'', u'0', u'0', u'', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'0', u'0']]

自己是希望用簡單的範例,讓大家了解爬蟲的運作原理,part1部分就到這邊,

之後會分享在不同情況下使用不同爬蟲方法,我都會以我爬過網站做分享,

大多都是運動資料,有問題都可以互相交流,謝謝。