本文轉載自:https://www.makcyun.top/web_scraping_withpython2.html
需要學習的地方:
(1)read_html的用法
作用:快速獲取在html中頁面中table格式的數據
(2)to_sql的用法
將獲得的DataFrame數據寫入數據表中
(3)使用urlencode構造所需的url參數
摘要: 我們平常在瀏覽網頁中會遇到一些表格型的數據信息,除了表格本身體現的內容以外,你可能想透過表格再更進一步地進行匯總、篩選、處理分析等操作從而得到更多有價值的信息,這時可用python爬蟲來實現。本文采用pandas庫中的read_html方法來快速准確地抓取表格數據。
本文知識點:
- Table型表格抓取
- DataFrame.read_html函數使用
- 爬蟲數據存儲到mysql數據庫
- Navicat數據庫的使用
1. table型表格
我們在網頁上會經常看到這樣一些表格,比如:
QS2018世界大學排名:
他們除了都是表格以外,還一個共同點就是當你點擊右鍵-定位時,可以看到他們都是table類型的表格形式。
從中可以看到table類型的表格網頁結構大致如下:
<table class="..." id="..."> |
先來簡單解釋一下上文出現的幾種標簽含義:
<table> : 定義表格 |
這樣的表格數據,就可以利用pandas模塊里的read_html函數方便快捷地抓取下來。下面我們就來操作一下。
2. 快速抓取
下面以中國上市公司信息這個網頁中的表格為例,感受一下read_html函數的強大之處。
import pandas as pd |
只需不到十行代碼,1分鍾左右就可以將全部178頁共3536家A股上市公司的信息干凈整齊地抓取下來。比采用正則表達式、xpath這類常規方法要省心省力地多。如果采取人工一頁頁地復制粘貼到excel中,就得操作到猴年馬月去了。
上述代碼除了能爬上市公司表格以外,其他幾個網頁的表格都可以爬,只需做簡單的修改即可。因此,可作為一個簡單通用的代碼模板。但是,為了讓代碼更健壯更通用一些,接下來,以爬取177頁的A股上市公司信息為目標,講解一下詳細的代碼實現步驟。
3. 詳細代碼實現
3.1. read_html函數
先來了解一下read_html函數的api:
pandas.read_html(io, match='.+', flavor=None, header=None, index_col=None, skiprows=None, attrs=None, parse_dates=False, tupleize_cols=None, thousands=', ', encoding=None, decimal='.', converters=None, na_values=None, keep_default_na=True, displayed_only=True) |
參考:
1 http://pandas.pydata.org/pandas-docs/stable/io.html#io-read-html
2 http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_html.html
3.2. 分析網頁url
首先,觀察一下中商情報網第1頁和第2頁的網址:
http://s.askci.com/stock/a/?reportTime=2017-12-31&pageNum=1#QueryCondition |
可以發現,只有pageNum的值隨着翻頁而變化,所以基本可以斷定pageNum=1代表第1頁,pageNum=10代表第10頁,以此類推。這樣比較容易用for循環構造爬取的網址。
試着把#QueryCondition刪除,看網頁是否同樣能夠打開,經嘗試發現網頁依然能正常打開,因此在構造url時,可以使用這樣的格式:
http://s.askci.com/stock/a/?reportTime=2017-12-31&pageNum=i
再注意一下其他參數:
a:表示A股,把a替換為h,表示港股;把a替換為xsb,則表示新三板。那么,在網址分頁for循環外部再加一個for循環,就可以爬取這三個股市的股票了。
3.3. 定義函數
將整個爬取分為網頁提取、內容解析、數據存儲等步驟,依次建立相應的函數。
# 網頁提取函數 |
上面兩個函數相比於快速抓取的方法代碼要多一些,如果需要抓的表格很少或只需要抓一次,那么推薦快速抓取法。如果頁數比較多,這種方法就更保險一些。解析函數用了BeautifulSoup和css選擇器,這種方法定位提取表格所在的id為#myTable04的table代碼段,更為准確。
3.4. 存儲到MySQL
接下來,我們可以將結果保存到本地csv文件,也可以保存到MySQL數據庫中。這里為了練習一下MySQL,因此選擇保存到MySQL中。
首先,需要先在數據庫建立存放數據的表格,這里命名為listed_company。代碼如下:
import pymysql |
上述代碼定義了generate_mysql()函數,用於在MySQL中wade數據庫下生成一個listed_company的表。表格包含15個列字段。根據每列字段的屬性,分別設置為INT整形(長度為30)、VARCHAR字符型(長度為30) 、DATETIME(0) 日期型等。
在Navicat中查看建立好之后的表格:
接下來就可以往這個表中寫入數據,代碼如下:
import pymysql |
以上就完成了單個頁面的表格爬取和存儲工作,接下來只要在main()函數進行for循環,就可以完成所有總共178頁表格的爬取和存儲,完整代碼如下:
import requests |
最終,A股所有3535家企業的信息已經爬取到mysql中,如下圖:
最后,需說明不是所有表格都可以用這種方法爬取,比如這個網站中的表格,表面是看起來是表格,但在html中不是前面的table格式,而是list列表格式。這種表格則不適用read_html爬取。得用其他的方法,比如selenium,以后再進行介紹。
本文完。