小白學 Python 爬蟲(25):爬取股票信息

小白學 Python 爬蟲(25):爬取股票信息

人生苦短,我用 Python


如果我的文章對您有幫助,請關注支持下作者的公眾號:極客挖掘機,您的關注,是對小編堅持原創的最大鼓勵:)

前文傳送門:

小白學 Python 爬蟲(1):開篇

小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝

小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門

小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門

小白學 Python 爬蟲(5):前置準備(四)數據庫基礎

小白學 Python 爬蟲(6):前置準備(五)爬蟲框架的安裝

小白學 Python 爬蟲(7):HTTP 基礎

小白學 Python 爬蟲(8):網頁基礎

小白學 Python 爬蟲(9):爬蟲基礎

小白學 Python 爬蟲(10):Session 和 Cookies

小白學 Python 爬蟲(11):urllib 基礎使用(一)

小白學 Python 爬蟲(12):urllib 基礎使用(二)

小白學 Python 爬蟲(13):urllib 基礎使用(三)

小白學 Python 爬蟲(14):urllib 基礎使用(四)

小白學 Python 爬蟲(15):urllib 基礎使用(五)

小白學 Python 爬蟲(16):urllib 實戰之爬取妹子圖

小白學 Python 爬蟲(17):Requests 基礎使用

小白學 Python 爬蟲(18):Requests 進階操作

小白學 Python 爬蟲(19):Xpath 基操

小白學 Python 爬蟲(20):Xpath 進階

小白學 Python 爬蟲(21):解析庫 Beautiful Soup(上)

小白學 Python 爬蟲(22):解析庫 Beautiful Soup(下)

小白學 Python 爬蟲(23):解析庫 pyquery 入門

小白學 Python 爬蟲(24):2019 豆瓣電影排行

引言

上一篇的實戰寫到最後沒有用到頁面元素解析,感覺有點小遺憾,不過最後的電影列表還是挺香的,真的推薦一看。

小白學 Python 爬蟲(25):爬取股票信息

本次選題是先寫好代碼再寫的文章,絕對可以用到頁面元素解析,並且還需要對網站的數據加載有一定的分析,才能得到最終的數據,並且小編找的這兩個數據源無 ip 訪問限制,質量有保證,絕對是小白練手的絕佳之選。

鄭重聲明: 本文僅用於學習等目的。

分析

首先要爬取股票數據,肯定要先知道有哪些股票吧,這裡小編找到了一個網站,這個網站上有股票的編碼列表:https://hq.gucheng.com/gpdmylb.html 。

小白學 Python 爬蟲(25):爬取股票信息

打開 Chrome 的開發者模式,將股票代碼一個一個選出來吧。具體過程小編就不貼了,各位同學自行實現。

我們可以將所有的股票代碼存放在一個列表中,剩下的就是找一個網站,循環的去將每一隻股票的數據取出來咯。

這個網站小編已經找好了,是同花順,鏈接: http://stockpage.10jqka.com.cn/000001/ 。

小白學 Python 爬蟲(25):爬取股票信息

想必各位聰明的同學已經發現了,這個鏈接中的 000001 就是股票代碼。

我們接下來只需要拼接這個鏈接,就能源源不斷的獲取到我們想要的數據。

實戰

首先,還是先介紹一下本次實戰用到的請求庫和解析庫為: Requests 和 pyquery 。數據存儲最後還是落地在 Mysql 。

獲取股票代碼列表

第一步當然是先構建股票代碼列表咯,我們先定義一個方法:

<code>

def

get_stock_list

(stockListURL)

:

r =requests.get(stockListURL, headers = headers) doc = PyQuery(r.text) list = []

for

i

in

doc(

'.stockTable a'

).items():

try

: href = i.attr.href list.append(re.findall(

r"\d{6}"

, href)[

0

])

except

:

continue

list = [item.lower()

for

item

in

list]

return

list /<code>

將上面的鏈接當做參數傳入,大家可以自己運行下看下結果,小編這裡就不貼結果了,有點長。。。

獲取詳情數據

詳情的數據看起來好像是在頁面上的,但是,實際上並不在,實際最終獲取數據的地方並不是頁面,而是一個數據接口。

<code>http://qd.10jqka.com.cn/quote.php?cate=real&

type

=stock&callback=showStockDate&

return

=json&code=000001 /<code>

至於是怎麼找出來,小編這次就不說,還是希望各位想學爬蟲的同學能自己動動手,去尋找一下,多找幾次,自然就摸到門路了。

現在數據接口有了,我們先看下返回的數據吧:

<code>

showStockDate

({

"info"

:{

"000001"

:{

"name"

:

"\u5e73\u5b89\u94f6\u884c"

}},

"data"

:{

"000001"

:{

"10"

:

"16.13"

,

"8"

:

"16.14"

,

"9"

:

"15.87"

,

"13"

:

"78795234.00"

,

"19"

:

"1262802470.00"

,

"7"

:

"16.12"

,

"15"

:

"40225508.00"

,

"14"

:

"37528826.00"

,

"69"

:

"17.73"

,

"70"

:

"14.51"

,

"12"

:

"5"

,

"17"

:

"945400.00"

,

"264648"

:

"0.010"

,

"199112"

:

"0.062"

,

"1968584"

:

"0.406"

,

"2034120"

:

"9.939"

,

"1378761"

:

"16.026"

,

"526792"

:

"1.675"

,

"395720"

:

"-948073.000"

,

"461256"

:

"-39.763"

,

"3475914"

:

"313014790000.000"

,

"1771976"

:

"1.100"

,

"6"

:

"16.12"

,

"11"

:

""

}}}) /<code>

很明顯,這個結果並不是標準的 json 數據,但這個是 JSONP 返回的標準格式的數據,這裡我們先處理下頭尾,將它變成一個標準的 json 數據,再對照這頁面的數據進行解析,最後將分析好的值寫入數據庫中。

<code>

def

getStockInfo

(list, stockInfoURL)

:

count =

0

for

stock

in

list:

try

: url = stockInfoURL + stock r = requests.get(url, headers=headers) dict1 = json.loads(r.text[

14

: int(len(r.text)) -

1

]) print(dict1) insert_data = {

"code"

: stock,

"name"

: dict1[

'info'

][stock][

'name'

],

"jinkai"

: dict1[

'data'

][stock][

'7'

],

"chengjiaoliang"

: dict1[

'data'

][stock][

'13'

],

"zhenfu"

: dict1[

'data'

][stock][

'526792'

],

"zuigao"

: dict1[

'data'

][stock][

'8'

],

"chengjiaoe"

: dict1[

'data'

][stock][

'19'

],

"huanshou"

: dict1[

'data'

][stock][

'1968584'

],

"zuidi"

: dict1[

'data'

][stock][

'9'

],

"zuoshou"

: dict1[

'data'

][stock][

'6'

],

"liutongshizhi"

: dict1[

'data'

][stock][

'3475914'

] } cursor.execute(sql_insert, insert_data) conn.commit() print(stock,

':寫入完成'

)

except

: print(

'寫入異常'

)

continue

/<code>

這裡我們加入異常處理,因為本次爬取的數據有些多,很有可能由於某些原因拋出異常,我們當然不希望有異常的時候中斷數據抓取,所以這裡添加異常處理繼續抓取數據。

完整代碼

我們將代碼稍作封裝,完成本次的實戰。

<code>

import

requests

import

re

import

json

from

pyquery

import

PyQuery

import

pymysql

def

connect

()

:

conn = pymysql.connect(host=

'localhost'

, port=

3306

, user=

'root'

, password=

'password'

, database=

'test'

, charset=

'utf8mb4'

) cursor = conn.cursor()

return

{

"conn"

: conn,

"cursor"

: cursor} connection = connect() conn, cursor = connection[

'conn'

], connection[

'cursor'

] sql_insert =

"insert into stock(code, name, jinkai, chengjiaoliang, zhenfu, zuigao, chengjiaoe, huanshou, zuidi, zuoshou, liutongshizhi, create_date) values (%(code)s, %(name)s, %(jinkai)s, %(chengjiaoliang)s, %(zhenfu)s, %(zuigao)s, %(chengjiaoe)s, %(huanshou)s, %(zuidi)s, %(zuoshou)s, %(liutongshizhi)s, now())"

headers = {

'User-Agent'

:

'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'

}

def

get_stock_list

(stockListURL)

:

r =requests.get(stockListURL, headers = headers) doc = PyQuery(r.text) list = []

for

i

in

doc(

'.stockTable a'

).items():

try

: href = i.attr.href list.append(re.findall(

r"\d{6}"

, href)[

0

])

except

:

continue

list = [item.lower()

for

item

in

list]

return

list

def

getStockInfo

(list, stockInfoURL)

:

count =

0

for

stock

in

list:

try

: url = stockInfoURL + stock r = requests.get(url, headers=headers) dict1 = json.loads(r.text[

14

: int(len(r.text)) -

1

]) print(dict1) insert_data = {

"code"

: stock,

"name"

: dict1[

'info'

][stock][

'name'

],

"jinkai"

: dict1[

'data'

][stock][

'7'

],

"chengjiaoliang"

: dict1[

'data'

][stock][

'13'

],

"zhenfu"

: dict1[

'data'

][stock][

'526792'

],

"zuigao"

: dict1[

'data'

][stock][

'8'

],

"chengjiaoe"

: dict1[

'data'

][stock][

'19'

],

"huanshou"

: dict1[

'data'

][stock][

'1968584'

],

"zuidi"

: dict1[

'data'

][stock][

'9'

],

"zuoshou"

: dict1[

'data'

][stock][

'6'

],

"liutongshizhi"

: dict1[

'data'

][stock][

'3475914'

] } cursor.execute(sql_insert, insert_data) conn.commit() print(stock,

':寫入完成'

)

except

: print(

'寫入異常'

)

continue

def

main

()

:

stock_list_url =

'https://hq.gucheng.com/gpdmylb.html'

stock_info_url =

'http://qd.10jqka.com.cn/quote.php?cate=real&type=stock&callback=showStockDate&return=json&code='

list = get_stock_list(stock_list_url) getStockInfo(list, stock_info_url)

if

__name__ ==

'__main__'

: main() /<code>

成果

最終小編耗時 15 分鐘左右,成功抓取數據 4600+ 條,結果就不展示了。

示例代碼

本系列的所有代碼小編都會放在代碼管理倉庫 Github 和 Gitee 上,方便大家取用。

示例代碼-Github

示例代碼-Gitee


分享到:


相關文章: