Python項目實戰:福布斯系列之數據採集

1 數據採集概述

開始一個數據分析項目,首先須要作的就是get到原始數據,得到原始數據的方法有多種途徑。好比:html

  1. 獲取數據集(dataset)文件
  2. 使用爬蟲採集數據
  3. 直接得到excel、csv及其餘數據文件
  4. 其餘途徑…

本次福布斯系列數據分析項目實戰,數據採集方面,主要數據來源於使用爬蟲進行數據採集,同時也輔助其餘數據進行對比。python

本文主要是介紹使用爬蟲進行數據採集的思路和步驟。c++

本次採集的福布斯全球上市企業2000強排行榜數據,涉及年份從2007年到2017年,跨越10多年。微信

本次採集的目標網站,是多個網頁,但多個網頁的分佈結構都有所不一樣,雖然思路和步驟都差很少,但須要分開來編寫,分別採集。markdown

2 數據採集步驟

數據採集大致分爲幾步:app

  1. 目標主網頁內容的Download
  2. 主網頁上數據的採集
  3. 主網頁上其餘分發頁面網站連接的採集
  4. 各分發網頁數據的download與採集
  5. 將採集的數據保存

涉及到的python庫包括,requests、BeautifulSoup以及csv。 下面以採集某年的數據爲案例,來描述下數據採集的步驟。函數

import requests
from bs4 import BeautifulSoup
import csv

2.1 數據Download模塊

主要是基於 requests,代碼以下:網站

def download(url):
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'}
    response = requests.get(url,headers=headers)
    # print(response.status_code)
    return response.text

這個模塊會在主網頁數據下載,以及各個分頁面數據下載時使用,是一個比較通用的模塊。ui

2.2 主網頁上數據的採集

主網頁的頁面結構,主要分爲兩個部分,一類是包含其餘頁面數據的網頁連接,一類是主網頁上的公司數據列表,以表格形式在網頁上顯示。lua

用BeautifulSoup能夠把這些數據解析出來。 代碼模塊以下:

  • 解析主網頁上的公司數據列表信息
def get_content_first_page(html, year):
    ''' 獲取排名在1-100的公司列表,且包含表頭 '''
    soup = BeautifulSoup(html, 'lxml')
    body = soup.body
    body_content = body.find('div', {'id': 'bodyContent'})
    tables = body_content.find_all('table', {'class': 'XXXXtable'})

    # tables一共有3個,最後一個纔是咱們想要的
    trs = tables[-1].find_all('tr')

    # 獲取表頭名稱
    # trs[1], 這裏跟其餘年份不同
    row_title = [item.text.strip() for item in trs[1].find_all('th')]
    row_title.insert(0, '年份')

    rank_list = []
    rank_list.append(row_title)
    for i, tr in enumerate(trs):
        if i == 0 or i == 1:
            continue
        tds = tr.find_all('td')

        # 獲取公司排名及列表
        row = [ item.text.strip() for item in tds]
        row.insert(0, year)
        rank_list.append(row)
    return rank_list
  • 解析主網頁上其餘頁面的網頁連接
def get_page_urls(html):
    ''' 獲取排名在101-2000的公司的網頁連接 '''
    soup = BeautifulSoup(html, 'lxml')
    body = soup.body
    body_content = body.find('div', {'id': 'bodyContent'})
    label_div = body_content.find('div', {'align':'center'})
    label_a = label_div.find('p').find('b').find_all('a')

    page_urls = ['basic_url' + item.get('href') for item in label_a]
    return page_urls

2.3 各個分發頁面上的數據採集

步驟也是 網頁頁面下載 和表格類數據爬取。 代碼內容跟主網頁頁面相似,只是細節上有些差別,這裏就不做贅述了。

2.4 數據存儲

採集的數據,最後保存到csv文件中。模塊代碼以下:

def save_data_to_csv_file(data, file_name):
    ''' 保存數據到csv文件中 '''
    with open(file_name, 'a', errors='ignore', newline='') as f:
        f_csv = csv.writer(f)
        f_csv.writerows(data)

2.5 數據採集主函數

def get_forbes_global_year_2007(year=2007):
    url = 'url'
    html = download(url)
    # print(html)

    data_first_page = get_content_first_page(html, year)
    # print(data_first_page)
    save_data_to_csv_file(data_first_page, 'forbes_'+str(year)+'.csv')

    page_urls = get_page_urls(html)
    # print(page_urls)

    for url in page_urls:
        html = download(url)
        data_other_page = get_content_other_page(html, year)
        # print(data_other_page)
        print('saving data ...', url)
        save_data_to_csv_file(data_other_page, 'forbes_'+str(year)+'.csv')

if __name__ == '__main__':

    # get data from Forbes Global 2000 in Year 2009
    get_forbes_global_year_2007()

3 總結

本文只介紹了數據採集的思路與各個模塊,並無提供目標網頁的連接, 一方面因爲原始網頁的數據信息比較雜亂,採集的時候須要寫多個採集程序,另一方面,因爲咱們的重點在於後續的數據分析部分,但願不要着重於數據爬取。

在後續的分析過程當中,咱們會來查看數據的結構、數據完整性及相關信息,歡迎關注微信公衆號(ID:PyDataRoad)。

本期推薦閱讀:

相關文章
相關標籤/搜索