自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

程序員三大美德之一:快速有效檢索網(wǎng)頁數(shù)據(jù)的“懶惰”程序員指南

大數(shù)據(jù) 數(shù)據(jù)分析
根據(jù)Perl編程語言的作者拉里·沃爾的說法,程序員具有三大美德:懶惰,不耐煩和傲慢。懶惰可以讓你全力以赴,降低總能耗,其他人會發(fā)現(xiàn)你編寫的省力程序很有用。

 根據(jù)Perl編程語言的作者拉里·沃爾的說法,程序員具有三大美德:懶惰,不耐煩和傲慢。懶惰可以讓你全力以赴,降低總能耗,其他人會發(fā)現(xiàn)你編寫的省力程序很有用。

[[336534]]

比爾蓋茨的觀點是:我選擇讓懶惰的人完成艱巨的任務,因為他可以找到完成任務的捷徑。

網(wǎng)頁抓取或許是一個相當簡單的編程問題:在文檔的源代碼中搜索唯一標識符,提取相關(guān)數(shù)據(jù),但我認為存在一個更“懶惰”的解決方案——更簡單,更快,可以生成更多數(shù)據(jù)。

雅虎財經(jīng)是財務數(shù)據(jù)做得最好的網(wǎng)站之一,這也讓它成為金融愛好者進行網(wǎng)頁抓取的主要目標。幾乎每天都有關(guān)于StackOverflow的問題,抓取數(shù)據(jù)的人參考了雅虎財經(jīng)的某種數(shù)據(jù)檢索(通常是通過網(wǎng)絡抓取)。

網(wǎng)頁抓取問題1

網(wǎng)頁抓取者嘗試查找Facebook當前的股票價格。代碼如下:

  1. import requests 
  2.         from bs4 importBeautifulSoup 
  3.              defparsePrice(): 
  4.           r = requests.get("https://finance.yahoo.com/quote/FB?p=FB"
  5.           soup =BeautifulSoup(r.text, "lxml"
  6.           price = soup.find( div , { class : My(6px) Pos(r)smartphone_Mt(6px) }).find( span ).text 
  7.           print(f the current price: {price} ) 

該代碼輸出如下:

  1. the current price: 216.08 

使用簡單的網(wǎng)頁抓取解決方案非常簡單,但這還不夠“懶惰”,讓我們看下一個。

網(wǎng)頁抓取問題2

網(wǎng)頁抓取者正在嘗試從統(tǒng)計標簽中查找有關(guān)股票的企業(yè)價值和空頭股票數(shù)量的數(shù)據(jù)。他的問題實際上是檢索可能存在或不存在的嵌套字典值,但是在檢索數(shù)據(jù)上,他似乎已經(jīng)找到了更好的解決方法。

  1. import requests, re, json, pprint 
  2.              p = re.compile(r root.App.main =(.*); ) 
  3.         tickers = [ AGL.AX ] 
  4.         results = {} 
  5.              with requests.Session() as s: 
  6.                  for ticker in tickers: 
  7.                 r = s.get( https://finance.yahoo.com/quote/{}/key-statistics?p={} .format(ticker,ticker)) 
  8.                 data = json.loads(p.findall(r.text)[0]) 
  9.                 key_stats = data[ context ][ dispatcher ][ stores ][ QuoteSummaryStore ] 
  10.                 print(key_stats) 
  11.                 res = { 
  12.                          Enterprise Value  : key_stats[ defaultKeyStatistics ][ enterpriseValue ][ fmt ] 
  13.                         , Shares_Short  : key_stats[ defaultKeyStatistics ][ sharesShort ].get( longFmt ,  N/A ) 
  14.                 } 
  15.                 results[ticker] = res 
  16.              print(results) 

看第3行:網(wǎng)頁抓取者能夠在javascript的變量內(nèi)找到他要查找的數(shù)據(jù):

  1. root.App.main = {.... }; 

在那里,只需訪問字典中適當?shù)那短祖I,即可輕松檢索數(shù)據(jù)。但是,確實還有更“懶惰”的辦法。

“懶惰”的解決方案1

  1. import requests 
  2.              r = requests.get("https://query2.finance.yahoo.com/v10/finance/quoteSummary/FB?modules=price"
  3.        data = r.json() 
  4.        print(data) 
  5.        print(f"the currentprice: {data[ quoteSummary ][ result ][0][ price ][ regularMarketPrice ][ raw ]}"

看看第三行的URL,輸出如下:

  1.      quoteSummary : { 
  2.          error : None, 
  3.          result : [{ 
  4.              price : { 
  5.                 averageDailyVolume10Day : {}, 
  6.                 averageDailyVolume3Month : {}, 
  7.                  circulatingSupply : {}, 
  8.                  currency :  USD , 
  9.                  currencySymbol :  $ , 
  10.                  exchange :  NMS , 
  11.                  exchangeDataDelayedBy :0, 
  12.                  exchangeName : NasdaqGS , 
  13.                  fromCurrency : None, 
  14.                  lastMarket : None, 
  15.                  longName :  Facebook,Inc. , 
  16.                  marketCap : { 
  17.                      fmt :  698.42B , 
  18.                      longFmt : 698,423,836,672.00 , 
  19.                      raw : 698423836672 
  20.                 }, 
  21.                  marketState :  REGULAR , 
  22.                  maxAge : 1, 
  23.                  openInterest : {}, 
  24.                  postMarketChange : {}, 
  25.                  postMarketPrice : {}, 
  26.                  preMarketChange : { 
  27.                      fmt :  -0.90 , 
  28.                      raw : -0.899994 
  29.                 }, 
  30.                  preMarketChangePercent :{ 
  31.                      fmt :  -0.37% , 
  32.                      raw : -0.00368096 
  33.                 }, 
  34.                  preMarketPrice : { 
  35.                      fmt :  243.60 , 
  36.                      raw : 243.6 
  37.                 }, 
  38.                  preMarketSource : FREE_REALTIME , 
  39.                  preMarketTime :1594387780, 
  40.                  priceHint : { 
  41.                      fmt :  2 , 
  42.                      longFmt :  2 , 
  43.                      raw : 2 
  44.                 }, 
  45.                  quoteSourceName : Nasdaq Real Time   
  46.                  Price , 
  47.                  quoteType :  EQUITY , 
  48.                  regularMarketChange : { 
  49.                      fmt :  0.30 , 
  50.                      raw : 0.30160522 
  51.                 }, 
  52.                 regularMarketChangePercent : { 
  53.                      fmt :  0.12% , 
  54.                      raw : 0.0012335592 
  55.                 }, 
  56.                  regularMarketDayHigh : { 
  57.                      fmt :  245.49 , 
  58.                      raw : 245.49 
  59.                 }, 
  60.                  regularMarketDayLow : { 
  61.                      fmt :  239.32 , 
  62.                      raw : 239.32 
  63.                 }, 
  64.                  regularMarketOpen : { 
  65.                      fmt :  243.68 , 
  66.                      raw : 243.685 
  67.                 }, 
  68.                 regularMarketPreviousClose : { 
  69.                      fmt :  244.50 , 
  70.                      raw : 244.5 
  71.                 }, 
  72.                  regularMarketPrice : { 
  73.                      fmt :  244.80 , 
  74.                      raw : 244.8016 
  75.                 }, 
  76.                  regularMarketSource : FREE_REALTIME , 
  77.                  regularMarketTime :1594410026, 
  78.                  regularMarketVolume : { 
  79.                      fmt :  19.46M , 
  80.                      longFmt :  19,456,621.00 , 
  81.                      raw : 19456621 
  82.                 }, 
  83.                  shortName :  Facebook,Inc. , 
  84.                  strikePrice : {}, 
  85.                  symbol :  FB , 
  86.                  toCurrency : None, 
  87.                  underlyingSymbol : None, 
  88.                  volume24Hr : {}, 
  89.                  volumeAllCurrencies : {} 
  90.             } 
  91.         }] 
  92.     } 
  93. }the current price: 241.63 

“懶惰”的解決方案2

  1. import requests 
  2.              r = requests.get("https://query2.finance.yahoo.com/v10/finance/quoteSummary/AGL.AX?modules=defaultKeyStatistics"
  3.       data = r.json() 
  4.       print(data) 
  5.       print({ 
  6.            AGL.AX : { 
  7.                Enterprise Value : data[ quoteSummary ][ result ][0][ defaultKeyStatistics ][ enterpriseValue ][ fmt ], 
  8.                Shares Short : data[ quoteSummary ][ result ][0][ defaultKeyStatistics ][ sharesShort ].get( longFmt ,  N/A ) 
  9.           } 
  10.       }) 

再次看一下第三行的URL,輸出如下:

  1.      quoteSummary : { 
  2.          result : [{ 
  3.              defaultKeyStatistics : { 
  4.                  maxAge : 1, 
  5.                  priceHint : { 
  6.                      raw : 2, 
  7.                      fmt :  2 , 
  8.                      longFmt :  2  
  9.                 }, 
  10.                  enterpriseValue : { 
  11.                      raw : 13677747200, 
  12.                      fmt :  13.68B , 
  13.                      longFmt : 13,677,747,200  
  14.                 }, 
  15.                  forwardPE : {}, 
  16.                  profitMargins : { 
  17.                      raw : 0.07095, 
  18.                      fmt :  7.10%  
  19.                 }, 
  20.                  floatShares : { 
  21.                      raw : 637754149, 
  22.                      fmt :  637.75M , 
  23.                      longFmt : 637,754,149  
  24.                 }, 
  25.                  sharesOutstanding : { 
  26.                      raw : 639003008, 
  27.                      fmt :  639M , 
  28.                      longFmt : 639,003,008  
  29.                 }, 
  30.                  sharesShort : {}, 
  31.                  sharesShortPriorMonth :{}, 
  32.                  sharesShortPreviousMonthDate :{}, 
  33.                  dateShortInterest : {}, 
  34.                  sharesPercentSharesOut : {}, 
  35.                  heldPercentInsiders : { 
  36.                      raw : 0.0025499999, 
  37.                      fmt :  0.25%  
  38.                 }, 
  39.                  heldPercentInstitutions : { 
  40.                      raw : 0.31033, 
  41.                      fmt :  31.03%  
  42.                 }, 
  43.                  shortRatio : {}, 
  44.                  shortPercentOfFloat :{}, 
  45.                  beta : { 
  46.                      raw : 0.365116, 
  47.                      fmt :  0.37  
  48.                 }, 
  49.                  morningStarOverallRating :{}, 
  50.                  morningStarRiskRating :{}, 
  51.                  category : None, 
  52.                  bookValue : { 
  53.                      raw : 12.551, 
  54.                      fmt :  12.55  
  55.                 }, 
  56.                  priceToBook : { 
  57.                      raw : 1.3457094, 
  58.                      fmt :  1.35  
  59.                 }, 
  60.                 annualReportExpenseRatio : {}, 
  61.                  ytdReturn : {}, 
  62.                  beta3Year : {}, 
  63.                  totalAssets : {}, 
  64.                  yield : {}, 
  65.                  fundFamily : None, 
  66.                  fundInceptionDate : {}, 
  67.                  legalType : None, 
  68.                  threeYearAverageReturn :{}, 
  69.                  fiveYearAverageReturn :{}, 
  70.                  priceToSalesTrailing12Months :{}, 
  71.                  lastFiscalYearEnd : { 
  72.                      raw : 1561852800, 
  73.                      fmt :  2019-06-30  
  74.                 }, 
  75.                  nextFiscalYearEnd : { 
  76.                      raw : 1625011200, 
  77.                      fmt :  2021-06-30  
  78.                 }, 
  79.                  mostRecentQuarter : { 
  80.                      raw : 1577750400, 
  81.                      fmt :  2019-12-31  
  82.                 }, 
  83.                 earningsQuarterlyGrowth : { 
  84.                      raw : 0.114, 
  85.                      fmt :  11.40%  
  86.                 }, 
  87.                  revenueQuarterlyGrowth :{}, 
  88.                  netIncomeToCommon : { 
  89.                      raw : 938000000, 
  90.                      fmt :  938M , 
  91.                      longFmt : 938,000,000  
  92.                 }, 
  93.                  trailingEps : { 
  94.                      raw : 1.434, 
  95.                      fmt :  1.43  
  96.                 }, 
  97.                  forwardEps : {}, 
  98.                  pegRatio : {}, 
  99.                  lastSplitFactor : None, 
  100.                  lastSplitDate : {}, 
  101.                  enterpriseToRevenue : { 
  102.                      raw : 1.035, 
  103.                      fmt :  1.03  
  104.                 }, 
  105.                  enterpriseToEbitda : { 
  106.                      raw : 6.701, 
  107.                      fmt :  6.70  
  108.                 }, 
  109.                  52WeekChange : { 
  110.                      raw : -0.17621362, 
  111.                      fmt :  -17.62%  
  112.                 }, 
  113.                  SandP52WeekChange : { 
  114.                      raw : 0.045882702, 
  115.                      fmt :  4.59%  
  116.                 }, 
  117.                  lastDividendValue : {}, 
  118.                  lastCapGain : {}, 
  119.                  annualHoldingsTurnover :{} 
  120.             } 
  121.        }], 
  122.          error : None 
  123.     } 
  124. }{ AGL.AX : { Enterprise Value :  13.73B ,  Shares Short :  N/A }} 

“懶惰”的解決方案只是簡單地將請求從使用前端URL更改為某種非官方的返回JSON數(shù)據(jù)的API端點。這個方案更簡單,可以導出更多數(shù)據(jù) ,那么它的速度呢?代碼如下:

  1. import timeit 
  2.      import requests 
  3.      from bs4 importBeautifulSoup 
  4.      import json 
  5.      import re 
  6.              repeat =5 
  7.      number =5 
  8.              defweb_scrape_1(): 
  9.          r = requests.get(f https://finance.yahoo.com/quote/FB?p=FB ) 
  10.          soup =BeautifulSoup(r.text, "lxml"
  11.          price = soup.find( div , { class : My(6px) Pos(r)smartphone_Mt(6px) }).find( span ).text 
  12.          returnf the current price: {price}  
  13.              deflazy_1(): 
  14.          r = requests.get( https://query2.finance.yahoo.com/v10/finance/quoteSummary/FB?modules=price ) 
  15.          data = r.json() 
  16.          returnf"the currentprice: {data[ quoteSummary ][ result ][0][ price ][ regularMarketPrice ][ raw ]}" 
  17.      
  18.          defweb_scrape_2(): 
  19.          p = re.compile(r root.App.main = (.*); ) 
  20.          ticker = AGL.AX  
  21.          results = {} 
  22.          with requests.Session() as s: 
  23.              r = s.get( https://finance.yahoo.com/quote/{}/key-statistics?p={} .format(ticker,ticker)) 
  24.              data = json.loads(p.findall(r.text)[0]) 
  25.              key_stats = data[ context ][ dispatcher ][ stores ][ QuoteSummaryStore ] 
  26.              res = { 
  27.                       Enterprise Value : key_stats[ defaultKeyStatistics ][ enterpriseValue ][ fmt ], 
  28.                       Shares Short : key_stats[ defaultKeyStatistics ][ sharesShort ].get( longFmt ,  N/A ) 
  29.              } 
  30.              results[ticker] = res 
  31.          return results 
  32.     
  33.          deflazy_2(): 
  34.          r = requests.get( https://query2.finance.yahoo.com/v10/finance/quoteSummary/AGL.AX?modules=defaultKeyStatistics ) 
  35.          data = r.json() 
  36.          return { 
  37.               AGL.AX : { 
  38.                   Enterprise Value : data[ quoteSummary ][ result ][0][ defaultKeyStatistics ][ enterpriseValue ][ fmt ], 
  39.                   Shares Short : data[ quoteSummary ][ result ][0][ defaultKeyStatistics ][ sharesShort ].get( longFmt ,  N/A ) 
  40.              } 
  41.          } 
  42.     
  43.          web_scraping_1_times = timeit.repeat( 
  44.           web_scrape_1() , 
  45.          setup= import requests; from bs4 import BeautifulSoup , 
  46.          globals=globals(), 
  47.          repeat=repeat, 
  48.          number=number) 
  49.      print(f web scraping #1min time is {min(web_scraping_1_times) / number} ) 
  50.              lazy_1_times = timeit.repeat( 
  51.           lazy_1() , 
  52.          setup= import requests , 
  53.          globals=globals(), 
  54.          repeat=repeat, 
  55.          number=number 
  56.      ) 
  57.      print(f lazy #1 min timeis {min(lazy_1_times) / number} ) 
  58.     
  59.          web_scraping_2_times = timeit.repeat( 
  60.           web_scrape_2() , 
  61.          setup= import requests, re, json , 
  62.          globals=globals(), 
  63.          repeat=repeat, 
  64.          number=number) 
  65.      print(f web scraping #2min time is {min(web_scraping_2_times) / number} ) 
  66.              lazy_2_times = timeit.repeat( 
  67.           lazy_2() , 
  68.          setup= import requests , 
  69.          globals=globals(), 
  70.          repeat=repeat, 
  71.          number=number 
  72.      ) 
  73.      print(f lazy #2 min timeis {min(lazy_2_times) / number} ) 
  1. web scraping #1 min time is 0.5678426799999997 
  2. lazy #1 min time is 0.11238783999999953 
  3. web scraping #2 min time is 0.3731000199999997 
  4. lazy #2 min time is 0.0864451399999993 

“懶惰”的替代方案比其網(wǎng)頁抓取同類產(chǎn)品快4到5倍!

“偷懶”的過程

思考一下上面遇到的兩個問題:原來的方案里,代碼加載到頁面后,我們嘗試檢索數(shù)據(jù)。“懶惰”的解決方案直接針對數(shù)據(jù)源,根本不理會前端頁面。當你嘗試從網(wǎng)站提取數(shù)據(jù)時,這是一個重要區(qū)別和一個很好的方法。

步驟1:檢查XHR請求

XHR(XMLHttpRequest)對象是可用于Web瀏覽器腳本語言(例如JavaScript)的API,它將HTTP或HTTPS請求發(fā)送到Web服務器,并將服務器響應數(shù)據(jù)加載回腳本中?;旧希琗HR允許客戶端從URL檢索數(shù)據(jù),不必刷新整個網(wǎng)頁。

筆者將使用Chrome進行以下演示,但是其他瀏覽器也具有類似的功能。

· 打開Chrome的開發(fā)者控制臺。要在Google Chrome中打開開發(fā)者控制臺,請打開瀏覽器窗口右上角的Chrome菜單,然后選擇更多工具>開發(fā)者工具。也可以使用快捷鍵Option + ?+ J(適用于ios系統(tǒng)),或Shift + CTRL + J(適用于Windows / Linux)。

  •  選擇“網(wǎng)絡”選項卡。

  • 然后通過“ XHR”篩選結(jié)果

應注意,盡管有些請求包含“ AAPL”,得到的結(jié)果將相似但不相同。從調(diào)查這些開始,單擊最左側(cè)列中包含字符“ AAPL”的鏈接之一。

  • 選擇其中一個鏈接后會看到一個附加窗口,其中提供了所選請求的詳細信息。第一個選項卡Headers,提供有關(guān)瀏覽器請求和服務器響應的詳細信息。你應該立即注意到“Headers”選項卡中的“URL請求”與上面的惰性解決方案中提供的URL請求非常相似。

如果選擇“預覽”選項卡,將看到從服務器返回的數(shù)據(jù)。

 

好極了!看來我們找到了獲取Apple OHLC數(shù)據(jù)的URL!

步驟2:搜尋

現(xiàn)在我們已經(jīng)發(fā)現(xiàn)了一些通過瀏覽器發(fā)出的XHR請求。搜索javascript文件,查看是否可以找到更多信息。筆者發(fā)現(xiàn)與XHR請求相關(guān)的URL共同點是“ query1”和“ query2”。在開發(fā)者控制臺的右上角,選擇三個垂直點,然后在下拉框中選擇“搜索”。

 

在搜索欄中搜索“ query2”:

選擇第一個選項。將會彈出一個附加選項卡,其中包含找到“ query2”的位置。應該在這里注意到類似的內(nèi)容:

網(wǎng)頁抓取解決方案2提取的數(shù)據(jù)變量與該變量相同??刂婆_應提供“優(yōu)質(zhì)打印”變量的選項。你可以選擇該選項,也可以將整行(上面的第11行)復制并粘貼到https://beautifier.io/。或者如果你使用vscode,下載美化擴展,它會做同樣的事情。

正確格式化后,將整個代碼粘貼到文本編輯器或類似的編輯器中,然后再次搜索“ query2”。搜索結(jié)果應該在 “ Service Plugin” 中。該部分包含雅虎財經(jīng)用于在其頁面中填充數(shù)據(jù)的URL。以下是該部分的內(nèi)容:

  1. "tachyon.quoteSummary": { 
  2. "path""/v10/finance/quoteSummary/{symbol}"
  3. "timeout":6000, 
  4. "query": ["lang""region","corsDomain""crumb""modules",    "formatted"], 
  5. "responseField":"quoteSummary"
  6. "get": {"formatted"true
  7. }, 

以上是“懶惰”的解決方案中使用的URL。

“懶惰”人類發(fā)展的階梯,適當偷懶,你會進入新世界。

本文轉(zhuǎn)載自微信公眾號「讀芯術(shù)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系讀芯術(shù)公眾號。

 

責任編輯:武曉燕 來源: 讀芯術(shù)
相關(guān)推薦

2020-02-22 21:51:43

程序員Microsoft SServerSQL

2014-06-05 09:23:47

程序員高效

2013-12-24 09:59:48

程序員管理

2018-04-23 11:00:06

程序員養(yǎng)生健康

2013-08-20 09:33:59

程序員

2014-09-11 09:25:15

程序員

2013-07-04 13:50:14

2015-07-28 17:58:22

程序員指南

2012-03-06 09:22:46

程序員

2011-05-13 14:34:02

程序員

2009-06-22 09:06:57

程序員技術(shù)升級

2018-07-25 09:49:59

2019-01-07 09:31:37

程序員測試人員代碼

2011-05-30 14:50:56

程序員

2009-05-21 15:58:12

程序員工作經(jīng)驗職場

2017-11-14 21:30:15

2012-11-22 14:00:26

程序員

2015-03-25 13:16:55

SQL Server數(shù)據(jù)庫安全開發(fā)人員

2012-02-01 09:30:54

HTML 5

2022-02-16 18:21:33

程序員跳槽架構(gòu)
點贊
收藏

51CTO技術(shù)棧公眾號