簡體   English   中英

如何使用Python抓取動態生成的URL頁面?

[英]How do I scrape pages with dynamically generated URLs using Python?

我試圖刮掉http://www.dailyfinance.com/quote/NYSE/international-business-machines/IBM/financial-ratios ,但傳統的網址字符串構建技術不起作用,因為“全公司名稱-is-inserted-in-path“字符串。 並且事先並不知道確切的“完整公司名稱”。 只有公司的標志,“IBM”才知道。

從本質上講,我刮擦的方式是循環遍歷公司符號數組並在將url字符串發送到urllib2.urlopen(url)之前構建它。 但在這種情況下,這是不可能做到的。

例如,CSCO字符串是

http://www.dailyfinance.com/quote/NASDAQ/cisco-systems-inc/CSCO/financial-ratios

另一個例子url字符串是AAPL:

http://www.dailyfinance.com/quote/NASDAQ/apple/AAPL/financial-ratios

因此,為了獲取URL,我必須在主頁的輸入框中搜索符號:

http://www.dailyfinance.com/

我注意到當我輸入“CSCO”並在Firefox Web開發人員網絡選項卡中的( http://www.dailyfinance.com/quote/NASDAQ/apple/AAPL/financial-ratios)檢查搜索輸入時,我注意到獲取請求正在發送給

http://j.foolcdn.com/tmf/predictivesearch?callback=_predictiveSearch_csco&term=csco&domain=dailyfinance.com

並且引用者實際上給出了我想要捕獲的路徑

Host: j.foolcdn.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:28.0) Gecko/20100101 Firefox/28.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://www.dailyfinance.com/quote/NASDAQ/cisco-systems-inc/CSCO/financial-ratios?source=itxwebtxt0000007
Connection: keep-alive

很抱歉很長的解釋。 所以問題是如何在Referer中提取網址? 如果那是不可能的,我應該如何處理這個問題? 還有另外一種方法嗎?

我非常感謝你的幫助。

我喜歡這個問題。 因此,我會給出一個非常徹底的答案。 為此,我將使用我最喜歡的Requests庫和BeautifulSoup4。 如果您真的想使用它,請移植到Mechanize由您決定。 請求將為您節省大量的麻煩。


首先,您可能正在尋找POST請求。 但是,如果搜索功能立即您帶到您正在查找的頁面,則通常不需要POST請求。 所以讓我們檢查它,好嗎?

當我登陸基本網址http://www.dailyfinance.com/ ,我可以通過Firebug或Chrome的檢查工具進行簡單的檢查,當我在搜索欄上放入CSCO或AAPL並啟用“跳轉”時,有一個301 Moved Permanently狀態代碼。 這是什么意思?

在此輸入圖像描述

簡單來說,我被轉移到了某個地方。 此GET請求的URL如下:

http://www.dailyfinance.com/quote/jump?exchange-input=&ticker-input=CSCO

現在,我們通過使用簡單的URL操作來測試它是否適用於AAPL。

import requests as rq

apl_tick = "AAPL"
url = "http://www.dailyfinance.com/quote/jump?exchange-input=&ticker-input="
r = rq.get(url + apl_tick)
print r.url

以上結果如下:

http://www.dailyfinance.com/quote/nasdaq/apple/aapl
[Finished in 2.3s]

查看響應的URL如何更改? 讓我們通過在下面的代碼中附加以下代碼來查找/financial-ratios頁面,從而進一步采用URL操作:

new_url = r.url + "/financial-ratios"
p = rq.get(new_url)
print p.url

運行時,這給出了以下結果:

http://www.dailyfinance.com/quote/nasdaq/apple/aapl
http://www.dailyfinance.com/quote/nasdaq/apple/aapl/financial-ratios
[Finished in 6.0s]

現在我們走在正確的軌道上。 我現在將嘗試使用BeautifulSoup解析數據。 我的完整代碼如下:

from bs4 import BeautifulSoup as bsoup
import requests as rq

apl_tick = "AAPL"
url = "http://www.dailyfinance.com/quote/jump?exchange-input=&ticker-input="
r = rq.get(url + apl_tick)
new_url = r.url + "/financial-ratios"
p = rq.get(new_url)

soup = bsoup(p.content)
div = soup.find("div", id="clear").table
rows = table.find_all("tr")
for row in rows:
    print row

然后我嘗試運行此代碼,只是遇到以下回溯的錯誤:

  File "C:\Users\nanashi\Desktop\test.py", line 13, in <module>
    div = soup.find("div", id="clear").table
AttributeError: 'NoneType' object has no attribute 'table'

值得注意的是'NoneType' object... 這意味着我們的目標div不存在! Egads,但為什么我會看到以下內容?!

在此輸入圖像描述

只能有一個解釋:表是動態加載的! 大鼠。 讓我們看看我們是否可以找到該表的另一個來源。 我研究頁面,看到底部有滾動條。 這可能意味着表被加載到一個框架內,或者直接從另一個源加載並放入頁面中的div

我刷新頁面並再次觀看GET請求。 賓果,我發現了一些似乎有點前途的東西:

在此輸入圖像描述

第三方源URL,看起來,它很容易使用股票代碼進行操作! 讓我們嘗試將其加載到新標簽中。 這是我們得到的:

在此輸入圖像描述

哇! 我們現在擁有非常確切的數據來源。 最后一個障礙是當我們嘗試使用這個字符串拉出CSCO數據時它會起作用(記得我們去了CSCO - > AAPL,現在再次回到CSCO,所以你不會感到困惑)。 讓我們徹底清理字符串並放棄www.dailyfinance.com的角色。 我們的新網址如下:

http://www.motleyfool.idmanagedsolutions.com/stocks/financial_ratios.idms?SYMBOL_US=AAPL

讓我們在最后的刮刀中嘗試使用它!

from bs4 import BeautifulSoup as bsoup
import requests as rq

csco_tick = "CSCO"
url = "http://www.motleyfool.idmanagedsolutions.com/stocks/financial_ratios.idms?SYMBOL_US="
new_url = url + csco_tick

r = rq.get(new_url)
soup = bsoup(r.content)

table = soup.find("div", id="clear").table
rows = table.find_all("tr")
for row in rows:
    print row.get_text()

我們對CSCO財務比率數據的原始結果如下:

Company
Industry


Valuation Ratios


P/E Ratio (TTM)
15.40
14.80


P/E High - Last 5 Yrs 
24.00
28.90


P/E Low - Last 5 Yrs
8.40
12.10


Beta
1.37
1.50


Price to Sales (TTM)
2.51
2.59


Price to Book (MRQ)
2.14
2.17


Price to Tangible Book (MRQ)
4.25
3.83


Price to Cash Flow (TTM)
11.40
11.60


Price to Free Cash Flow (TTM)
28.20
60.20


Dividends


Dividend Yield (%)
3.30
2.50


Dividend Yield - 5 Yr Avg (%)
N.A.
1.20


Dividend 5 Yr Growth Rate (%)
N.A.
144.07


Payout Ratio (TTM)
45.00
32.00


Sales (MRQ) vs Qtr 1 Yr Ago (%)
-7.80
-3.70


Sales (TTM) vs TTM 1 Yr Ago (%)
5.50
5.60


Growth Rates (%)


Sales - 5 Yr Growth Rate (%)
5.51
5.12


EPS (MRQ) vs Qtr 1 Yr Ago (%)
-54.50
-51.90


EPS (TTM) vs TTM 1 Yr Ago (%)
-54.50
-51.90


EPS - 5 Yr Growth Rate (%)
8.91
9.04


Capital Spending - 5 Yr Growth Rate (%)
20.30
20.94


Financial Strength


Quick Ratio (MRQ)
2.40
2.70


Current Ratio (MRQ)
2.60
2.90


LT Debt to Equity (MRQ)
0.22
0.20


Total Debt to Equity (MRQ)
0.31
0.25


Interest Coverage (TTM)
18.90
19.10


Profitability Ratios (%)


Gross Margin (TTM)
63.20
62.50


Gross Margin - 5 Yr Avg
66.30
64.00


EBITD Margin (TTM)
26.20
25.00


EBITD - 5 Yr Avg
28.82
0.00


Pre-Tax Margin (TTM)
21.10
20.00


Pre-Tax Margin - 5 Yr Avg
21.60
18.80


Management Effectiveness (%)


Net Profit Margin (TTM)
17.10
17.65


Net Profit Margin - 5 Yr Avg
17.90
15.40


Return on Assets (TTM)
8.30
8.90


Return on Assets - 5 Yr Avg
8.90
8.00


Return on Investment (TTM)
11.90
12.30


Return on Investment - 5 Yr Avg
12.50
10.90


Efficiency


Revenue/Employee (TTM)
637,890.00
556,027.00


Net Income/Employee (TTM)
108,902.00
98,118.00


Receivable Turnover (TTM)
5.70
5.80


Inventory Turnover (TTM)
11.30
9.70


Asset Turnover (TTM)
0.50
0.50

[Finished in 2.0s]

清理數據取決於您。


從這次刮擦中學到的一個好教訓並不是所有數據都只包含在一個頁面中。 很高興看到它來自另一個靜態網站。 如果它是通過JavaScript或AJAX調用等生成的,我們的方法可能會遇到一些困難。

希望你從中學到了一些東西。 如果這有幫助並祝你好運,請告訴我們。

不回答您的具體問題,但解決您的問題。

http://www.dailyfinance.com/quotes/{Company Symbol}/{Stock Exchange}

例子:

http://www.dailyfinance.com/quotes/AAPL/NAS

http://www.dailyfinance.com/quotes/IBM/NYSE

http://www.dailyfinance.com/quotes/CSCO/NAS

要進入財務比率頁面,您可以使用以下內容:

import urllib2

def financial_ratio_url(symbol, stock_exchange):
    starturl  = 'http://www.dailyfinance.com/quotes/'
    starturl += '/'.join([symbol, stock_exchange])
    req = urllib2.Request(starturl)
    res = urllib2.urlopen(starturl)
    return '/'.join([res.geturl(),'financial-ratios'])

例:

financial_ratio_url('AAPL', 'NAS')
'http://www.dailyfinance.com/quote/nasdaq/apple/aapl/financial-ratios'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM