Python爬蟲成長之路:抓取證券之星的股票數據

来源:http://www.cnblogs.com/sjzh/archive/2016/09/24/5899716.html
-Advertisement-
Play Games

獲取數據是數據分析中必不可少的一部分,而網路爬蟲是是獲取數據的一個重要渠道之一。鑒於此,我拾起了Python這把利器,開啟了網路爬蟲之路。 本篇使用的版本為python3.5,意在抓取證券之星上當天所有A股數據。程式主要分為三個部分:網頁源碼的獲取、所需內容的提取、所得結果的整理。 一、網頁源碼的獲 ...


      獲取數據是數據分析中必不可少的一部分,而網路爬蟲是是獲取數據的一個重要渠道之一。鑒於此,我拾起了Python這把利器,開啟了網路爬蟲之路。

      本篇使用的版本為python3.5,意在抓取證券之星上當天所有A股數據。程式主要分為三個部分:網頁源碼的獲取、所需內容的提取、所得結果的整理。

一、網頁源碼的獲取

      很多人喜歡用python爬蟲的原因之一就是它容易上手。只需以下幾行代碼既可抓取大部分網頁的源碼。

import urllib.request
url='http://quote.stockstar.com/stock/ranklist_a_3_1_1.html'  #目標網址
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64)"}  #偽裝瀏覽器請求報頭
request=urllib.request.Request(url=url,headers=headers)  #請求伺服器
response=urllib.request.urlopen(request)  #伺服器應答
content=response.read().decode('gbk')   #以一定的編碼方式查看源碼
print(content)  #列印頁面源碼 

      雖說抓一頁的源碼容易,不過在一個網站內大量抓取網頁源碼卻經常遭到伺服器攔截,頓時感覺世界充滿了惡意。於是我開始研習突破反爬蟲限制的功法。

      1.偽裝流浪器報頭

      很多伺服器通過瀏覽器發給它的報頭來確認是否是人類用戶,所以我們可以通過模仿瀏覽器的行為構造請求報頭給伺服器發送請求。伺服器會識別其中的一些參數來識別你是否是人類用戶,很多網站都會識別User-Agent這個參數,所以請求頭最好帶上。有一些警覺性比較高的網站可能還會通過其他參數識別,比如通過Accept-Language來辨別你是否是人類用戶,一些有防盜鏈功能的網站還得帶上referer這個參數等等。

      2.隨機生成UA

      證券之星只需帶User-Agent這個參數就可以抓取頁面信息了,不過連續抓取幾頁就被伺服器阻止了。於是我決定每次抓取數據時模擬不同的瀏覽器發送請求,而伺服器通過User-Agent來識別不同瀏覽器,所以每次爬取頁面可以通過隨機生成不同的UA構造報頭去請求伺服器,

      3.減慢爬取速度

      雖然模擬了不同瀏覽器爬取數據,但發現有的時間段可以爬取上百頁的數據,有時候卻只能爬取十來頁,看來伺服器還會根據你的訪問的頻率來識別你是人類用戶還是網路爬蟲。所以我每抓取一頁都讓它隨機休息幾秒,加入此句代碼後,每個時間段都能爬取大量股票數據了。

      4.使用代理IP

      天有不測風雲,程式在公司時順利測試成功,回寢室後發現又只能抓取幾頁就被伺服器阻止了。驚慌失措的我趕緊詢問度娘,獲知伺服器可以識別你的IP,並記錄此IP訪問的次數,可以使用高匿的代理IP,併在抓取的過程中不斷的更換,讓伺服器無法找出誰是真凶。此功還未修成,欲知後事如何,請聽下回分解。

      5.其他突破反爬蟲限制的方法

      很多伺服器在接受瀏覽器請求時會發送一個cookie文件給瀏覽器,然後通過cookie來跟蹤你的訪問過程,為了不讓伺服器識別出你是爬蟲,建議最好帶上cookie一起去爬取數據;如果遇上要模擬登陸的網站,為了不讓自己的賬號被拉黑,可以申請大量的賬號,然後再爬入,此處涉及模擬登陸、驗證碼識別等知識,暫時不再深究...總之,對於網站主人來說,有些爬蟲確實是令人討厭的,所以會想出很多方法限制爬蟲的進入,所以我們在強行進入之後也得註意些禮儀,別把人家的網站給拖垮了。

二、所需內容的提取

      獲取網頁源碼後,我們就可以從中提取我們所需要的數據了。從源碼中獲取所需信息的方法有很多,使用正則表達式就是比較經典的方法之一。我們先來看所採集網頁源碼的部分內容。

      為了減少干擾,我先用正則表達式從整個頁面源碼中匹配出以上的主體部分,然後從主體部分中匹配出每隻股票的信息。代碼如下。

pattern=re.compile('<tbody[\s\S]*</tbody>')  
body=re.findall(pattern,str(content))  #匹配<tbody和</tbody>之間的所有代碼
pattern=re.compile('>(.*?)<')
stock_page=re.findall(pattern,body[0])  #匹配>和<之間的所有信息

       其中compile方法為編譯匹配模式,findall方法用此匹配模式去匹配出所需信息,並以列表的方式返回。正則表達式的語法還挺多的,下麵我只羅列所用到符號的含義。

語法 說明
. 匹配任意除換行符“\n”外的字元
* 匹配前一個字元0次或無限次
匹配前一個字元0次或一次
\s 空白字元:[<空格>\t\r\n\f\v]
\S 非空白字元:[^\s]
[...] 字元集,對應的位置可以是字元集中任意字元
(...) 被括起來的表達式將作為分組,裡面一般為我們所需提取的內容

      正則表達式的語法挺多的,也許有大牛隻要一句正則表達式就可提取我想提取的內容。在提取股票主體部分代碼時發現有人用xpath表達式提取顯得更簡潔一些,看來頁面解析也有很長的一段路要走。

三、所得結果的整理

      通過非貪婪模式(.*?)匹配>和<之間的所有數據,會匹配出一些空白字元出來,所以我們採用如下代碼把空白字元移除。

stock_last=stock_total[:] #stock_total:匹配出的股票數據
for data in stock_total:  #stock_last:整理後的股票數據
    if data=='':
        stock_last.remove('')

      最後,我們可以列印幾列數據看下效果,代碼如下

print('代碼','\t','簡稱','   ','\t','最新價','\t','漲跌幅','\t','漲跌額','\t','5分鐘漲幅')
for i in range(0,len(stock_last),13):        #網頁總共有13列數據
    print(stock_last[i],'\t',stock_last[i+1],' ','\t',stock_last[i+2],'  ','\t',stock_last[i+3],'  ','\t',stock_last[i+4],'  ','\t',stock_last[i+5])

      列印的部分結果如下

      抓取證券之星上當天所有A股數據的最終程式如下

import urllib
import urllib.request
import re
import random
import time
#抓取所需內容
user_agent = ["Mozilla/5.0 (Windows NT 10.0; WOW64)", 'Mozilla/5.0 (Windows NT 6.3; WOW64)',
              'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
              'Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko',
              'Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36',
              'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; rv:11.0) like Gecko)',
              'Mozilla/5.0 (Windows; U; Windows NT 5.2) Gecko/2008070208 Firefox/3.0.1',
              'Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070309 Firefox/2.0.0.3',
              'Mozilla/5.0 (Windows; U; Windows NT 5.1) Gecko/20070803 Firefox/1.5.0.12',
              'Opera/9.27 (Windows NT 5.2; U; zh-cn)',
              'Mozilla/5.0 (Macintosh; PPC Mac OS X; U; en) Opera 8.0',
              'Opera/8.0 (Macintosh; PPC Mac OS X; U; en)',
              'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.12) Gecko/20080219 Firefox/2.0.0.12 Navigator/9.0.0.6',
              'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Win64; x64; Trident/4.0)',
              'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)',
              'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C; .NET4.0E)',
              'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Maxthon/4.0.6.2000 Chrome/26.0.1410.43 Safari/537.1 ',
              'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C; .NET4.0E; QQBrowser/7.3.9825.400)',
              'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0 ',
              'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.92 Safari/537.1 LBBROWSER',
              'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; BIDUBrowser 2.x)',
              'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/3.0 Safari/536.11']
stock_total=[]   #stock_total:所有頁面的股票數據   stock_page:某頁的股票數據
for page in range(1,8):
    url='http://quote.stockstar.com/stock/ranklist_a_3_1_'+str(page)+'.html'
    request=urllib.request.Request(url=url,headers={"User-Agent":random.choice(user_agent)})#隨機從user_agent列表中抽取一個元素
    try:       
        response=urllib.request.urlopen(request)
    except urllib.error.HTTPError as e:            #異常檢測
        print('page=',page,'',e.code)
    except urllib.error.URLError as e:
        print('page=',page,'',e.reason)
    content=response.read().decode('gbk')       #讀取網頁內容
    print('get page',page)                  #列印成功獲取的頁碼
    pattern=re.compile('<tbody[\s\S]*</tbody>') 
    body=re.findall(pattern,str(content))
    pattern=re.compile('>(.*?)<')
    stock_page=re.findall(pattern,body[0])      #正則匹配
    stock_total.extend(stock_page)
    time.sleep(random.randrange(1,4))        #每抓一頁隨機休眠幾秒,數值可根據實際情況改動
#刪除空白字元
stock_last=stock_total[:]  #stock_last為最終所要得到的股票數據
for data in stock_total:
    if data=='':
        stock_last.remove('')
#列印部分結果
print('代碼','\t','簡稱','   ','\t','最新價','\t','漲跌幅','\t','漲跌額','\t','5分鐘漲幅')
for i in range(0,len(stock_last),13):  #原網頁有13列數據,所以步長為13
    print(stock_last[i],'\t',stock_last[i+1],' ','\t',stock_last[i+2],'  ','\t',stock_last[i+3],'  ','\t',stock_last[i+4],'  ','\t',stock_last[i+5])
python爬蟲實例

 

 

 

 

 

 

 

 

 

 

     

     


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 佈局:有2個屬性: Anchor:鎖定位置Dock:填充位置一般Dock是與容器控制項配合使用 容器控制項:Panel:就是一個區域,類似於DIV,可以獨立佈局,還可以讓其它控制項及容器在它的內部再次佈局 FlowLayoutPanel:流式佈局容器,內容會預設從左向右排列,如果寬度不夠了,那麼自動換行 ...
  • The alias cmd list your current aliases. For example : alias Use alias to shorten a long cmd in current shell session: alias [name=['command']] Use un... ...
  • 學習過Spring框架的人一定都會聽過Spring的IoC(控制反轉) 、DI(依賴註入)這兩個概念,對於初學Spring的人來說,總覺得IoC 、DI這兩個概念是模糊不清的,是很難理解的,今天和大家分享網上的一些技術大牛們對Spring框架的IOC的理解以及談談我對Spring Ioc的理解。 一 ...
  • 2、下載地址:https://github.com/MSOpenTech/redis/releases 3、最新的安裝包: 4、點擊msi文件開始安裝。 5、勾選同意,下一步。 6、使用預設的安裝地址地址,並且將redis安裝路徑添加到系統環境變數。 7、修改埠號為“46379”,添加防火牆例外。 ...
  • import java.util.*;import java.math.*;public class CaculatorLnN { public static void main(String[] args) { // TODO 自動生成的方法存根 int N; System.out.println ...
  • 網上目前還找不到完整的mac下golang環境配置支持,本人配置成功,現在整理分享出來。 mac最好裝下xcode,好像有依賴關係安裝Homebrew打開終端視窗, 粘貼腳本執行/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent. ...
  • 1、考慮用靜態工廠方法代替構造器 類的一個實例,通常使用類的公有的構造方法獲取。也可以為類提供一個公有的靜態工廠方法(不是設計模式中的工廠模式)來返回類的一個實例。例如: 使用靜態工廠方法代替構造器的優勢: 靜態工廠方法有名稱,更易讀。靜態工廠方法能夠使用方法名稱進行自註釋,來描述被返回的對象。例如 ...
  • restful服務中一個重要的特性就是一種資源可以有多種表現形式,在springmvc中可以使用ContentNegotiatingViewResolver這個視圖解析器來實現這種方式。 描述資源的三種形式 一、使用擴展名 http://localhost:8080/test/user.xml 以x ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...