Python爬蟲日記二:爬取天天基金網(wǎng)

一、前言

這次的實(shí)驗(yàn)的任務(wù)是要爬取天天基金網(wǎng)的6000多個(gè)基金,并把爬取的數(shù)據(jù)存放到Mongodb數(shù)據(jù)庫中,數(shù)據(jù)以供下次分析使用。而此次 需要采集的數(shù)據(jù)來自兩個(gè)頁面

  • 頁面1:從該頁面爬取 所有基金代碼、基金名稱、基金URL

    頁面1

  • 頁面2:從上個(gè)頁面獲取的基金URL地址爬取對(duì)應(yīng)基金的近1個(gè)月、近3個(gè)月、近6個(gè)月、近1年、近3年、成立來的變動(dòng)百分比。

    圖片.png

二、運(yùn)行環(huán)境

  • Python3
  • requests
  • MongoDb
  • bs4
  • pymongo
  • re

由于python2的字符編碼問題確實(shí)讓人蛋疼,所以今后的試驗(yàn)項(xiàng)目全部改成python3開發(fā),下面會(huì)詳細(xì)介紹蛋疼的原因。

關(guān)于python2和python3字符編碼的問題可以參考以下鏈接:
關(guān)于Python2.X與Python3.X的編碼問題
Python2和Python3之間關(guān)于字符串編碼處理的差別

三、實(shí)例分析

頁面一分析

  1. 天天基金網(wǎng)這個(gè)頁面所有從0至7開頭的基金代碼分別放在'class="num_box"對(duì)應(yīng)的8個(gè)div中,其中每個(gè)li對(duì)應(yīng)的就是基金所有信息,最后我們用正則表達(dá)式就可以取到我們需要的基金名稱、基金代碼和URL地址。
    圖片.png

取所有l(wèi)i基金信息用BeautifulSoup的select方法:
select('.num_right > li')

  1. 用循環(huán)方法取每個(gè)基金信息,并配合正則表達(dá)式,就可以得到我們需要的基金名稱、基金代碼和url地址。
for tag in tags:
 content=tag.a.text  #取第一個(gè)<a>的文本數(shù)據(jù)
 code=re.findall(r'\d+',content)[0]?。d+從文本數(shù)據(jù)里取數(shù)字,位數(shù)至少大于等于1位,正則表達(dá)式取得的結(jié)果用列表,所以后面用[0]取出數(shù)據(jù)
 name=content.split(')')[1]   #用中文')'分割取第二個(gè)值得到基金名稱
  1. 七個(gè).num中的最后一個(gè)<li>里面的內(nèi)容為空值,需要在此做判斷,否則會(huì)提示:not of index
if tag.a is None:
    contine?。H绻麨榭罩?,跳過
else:
    
  1. 兩個(gè)頁面分別用了兩種編碼方式,第一個(gè)頁面是gb2312,第二個(gè)頁面是utf-8,所以分別定義了2個(gè)不同編碼函數(shù),供兩個(gè)頁面調(diào)用


    圖片.png
html=requests.get(url,headers=header).content.decode('gbk')
#gbk編碼擴(kuò)展了gb2312,還支持中文繁體
html=requests.get(url,headers=header).content.decode('utf-8')

頁面二分析

  1. 從頁面1傳給頁面2的url地址,url格式如:http://fund.eastmoney.com/000001.html 可以分析得出需要的數(shù)據(jù)放在dd 標(biāo)簽里。
    圖片.png

先用BeautifulSoup的select方法搜索到。
再用find_all方法獲取dd標(biāo)簽里的第二個(gè)span標(biāo)簽。

tags=soup.select('dd')
m1=(tags[1].find_all('span')[1].string)
y1=(tags[2].find_all('span')[1].string)
m3=(tags[4].find_all('span')[1].string)
y3=(tags[5].find_all('span')[1].string)
m6=(tags[7].find_all('span')[1].string)
rece=(tags[8].find_all('span')[1].string)
detail={'代碼':code,'名稱':name,'近1月':m1,'近3月':m3,'近6月':m6,'近1年':y1,'近3年':y3,'成立來':rece}
  1. 但當(dāng)用以上方法獲取信息到基金代碼000009時(shí),又提示錯(cuò)誤“IndexError: list index out of range”,經(jīng)分析從頁面1獲取的url地址在頁面2生成的頁面有2種布局方式。
    于是再寫一個(gè)函數(shù)獲取第二種布局方式
tags=soup.find_all(class_='ui-font-middle ui-color-red ui-num')
m1=tags[3].string
y1=tags[4].string
m3=tags[5].string
y3=tags[6].string
m6=tags[7].string
rece=tags[8].string
detail={'代碼':code,'名稱':name,'近1月':m1,'近3月':m3,'近6月':m6,'近1年':y1,'近3年':y3,'成立來':rece}

在第一個(gè)方法里加入try...except... 捕捉錯(cuò)誤,當(dāng)遇到錯(cuò)誤時(shí)運(yùn)行第二個(gè)函數(shù)

  1. 把requests和BeautifulSoup單獨(dú)寫成一個(gè)模塊,以便給其他函數(shù)共用。
from bs4 import BeautifulSoup
import requests,random
def geturl_gbk(url):
    html=requests.get(url,headers=header).content.decode('gbk')
    soup=BeautifulSoup(html,'lxml')
    return soup
def geturl_utf8(url):
    html=requests.get(url,headers=header).content.decode('utf-8')
    soup=BeautifulSoup(html,'lxml')
    return soup 

導(dǎo)入MongoDb數(shù)據(jù)庫

import pymongo
clients=pymongo.MongoClient('127.0.0.1')
#建立鏈接
db=clients['hexun']
#指定數(shù)據(jù)庫
col1=db['fund']
#返回?cái)?shù)據(jù)集合1
col2=db['detail']
#返回?cái)?shù)據(jù)集合2

四、實(shí)戰(zhàn)代碼

代碼貼圖:

getstart模塊


getstart.png

eastmoney1.png
eastmoney2.png

完整代碼在github:

On GitHub : Click Here-> 爬取天天基金網(wǎng)代碼

五、MongoDb數(shù)據(jù)截圖

mongodb1.png
mongodb2.png

六、總結(jié)

  1. requests.content和requests.text的方法.content返回的是二進(jìn)制內(nèi)容要用decode指定編碼;text根據(jù)網(wǎng)頁編碼響應(yīng)內(nèi)容來猜測編碼,但此處依舊要指定編碼.
    requests.content方法:
html=requests.get(url).content.decode('gbk')
print (html)

request.text方法

html=requests.get(url)
html.encoding='gbk'
print (html.text)
  1. 此網(wǎng)站會(huì)判斷爬蟲,斷開連接,如下提示:

("Connection broken: ConnectionResetError(104, 'Connection reset by peer')", ConnectionResetError(104, 'Connection reset by peer'))

所以加上了隨機(jī)代理

proxies=['http://118.178.124.33:3128',
'http://139.129.166.68:3128',
'http://61.163.39.70:9999',
'http://61.143.228.162']

html=requests.get(url,headers=header,proxies={'http':random.choice(proxies)}).content.decode('gbk')
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • # Python 資源大全中文版 我想很多程序員應(yīng)該記得 GitHub 上有一個(gè) Awesome - XXX 系列...
    aimaile閱讀 26,835評(píng)論 6 427
  • 環(huán)境管理管理Python版本和環(huán)境的工具。p–非常簡單的交互式python版本管理工具。pyenv–簡單的Pyth...
    MrHamster閱讀 3,955評(píng)論 1 61
  • 出一道題,你從這張圖看到了什么?如果你已經(jīng)有了答案,理清自己的解題思路,就看看我的解答吧。 你看到的部分,就證明你...
    十七碎碎念閱讀 1,011評(píng)論 0 2
  • 我最喜歡冬天我家那里下的鵝毛大雪,鞋踩在雪上“咯吱”“咯吱”地響,陽光灑下來,亮晶晶的有些耀眼,河面光滑的像一面...
    醉兒閱讀 198評(píng)論 0 0

友情鏈接更多精彩內(nèi)容