Mi piace questa domanda. E a causa di ciò, darò una risposta molto approfondita. Per questo, userò la mia libreria delle richieste preferite insieme a BeautifulSoup4. Effettuare il porting su Mechanize se vuoi davvero usarlo dipende da te. Le richieste ti faranno risparmiare un sacco di mal di testa.
Prima di tutto, probabilmente siete alla ricerca di una richiesta POST. Tuttavia, le richieste POST spesso non sono necessarie se una funzione di ricerca porta immediatamente alla pagina che stai cercando. Quindi controlliamolo, vero?
Quando atterro sulla URL di base, http://www.dailyfinance.com/
, posso fare un semplice controllo tramite Firebug o Chrome di strumento ispezionare che quando ho messo in CSCO o AAPL sulla barra di ricerca e consentire il "salto", c'è un codice di 301 Moved Permanently
di stato . Cosa significa questo?

In termini semplici, ero trasferiti da qualche parte. L'URL per questa richiesta GET è la seguente:
http://www.dailyfinance.com/quote/jump?exchange-input=&ticker-input=CSCO
Ora, ci prova se funziona con AAPL utilizzando un semplice manipolazione URL.
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
È possibile che questo dà il seguente risultato:
http://www.dailyfinance.com/quote/nasdaq/apple/aapl
[Finished in 2.3s]
vedere come l'URL della risposta è cambiato? Prendiamo la manipolazione URL un ulteriore passo avanti, cercando la pagina /financial-ratios
aggiungendo il seguente per il codice di cui sopra:
new_url = r.url + "/financial-ratios"
p = rq.get(new_url)
print p.url
Quando correva, questo dà è il seguente risultato:
http://www.dailyfinance.com/quote/nasdaq/apple/aapl
http://www.dailyfinance.com/quote/nasdaq/apple/aapl/financial-ratios
[Finished in 6.0s]
Ora noi' ri sulla strada giusta. Ora cercherò di analizzare i dati usando BeautifulSoup. Il mio codice completo è il seguente:
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
Ho poi provare a eseguire questo codice, solo per incontrare un errore con il seguente traceback:
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'
di nota è la linea di 'NoneType' object...
. Questo significa che il nostro obiettivo div
non esiste! Egads, ma perché sto vedendo quanto segue ?!

Non ci può essere una sola spiegazione: la tabella è caricata in modo dinamico! Ratti. Vediamo se riusciamo a trovare un'altra fonte per il tavolo. Studio la pagina e vedo che ci sono delle barre di scorrimento in basso. Ciò potrebbe significare che la tabella è stata caricata all'interno di un frame o è stata caricata direttamente da un'altra fonte interamente e inserita in un div
nella pagina.
Aggiorna la pagina e guardo di nuovo le richieste GET. Bingo, ho trovato qualcosa che sembra un po 'promettente:

un URL di riferimento di terze parti, e guarda, è facilmente manipolabile con il simbolo! Proviamo a caricarlo in una nuova scheda. Ecco cosa si ottiene:

WOW! Ora abbiamo la fonte esatta dei nostri dati. L'ultimo ostacolo è che funzionerà quando proveremo a estrarre i dati CSCO usando questa stringa (ricordate che siamo passati a CSCO -> AAPL e ora torniamo di nuovo a CSCO, quindi non siete confusi). Puliamo la stringa e abbandoniamo completamente il ruolo di www.dailyfinance.com
.Il nostro nuovo URL è il seguente:
http://www.motleyfool.idmanagedsolutions.com/stocks/financial_ratios.idms?SYMBOL_US=AAPL
Proviamo a utilizzarlo nel nostro raschietto finale!
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()
E i nostri risultati grezzi per i dati indici finanziari del CSCO è la seguente:
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]
eliminando i dati dipende da voi.
Una buona lezione da imparare da questo raschiare non è tutti i dati sono contenuti in una pagina sola. È piuttosto bello vederlo provenire da un altro sito statico. Se fosse stato prodotto tramite chiamate JavaScript o AJAX o simili, avremmo probabilmente qualche difficoltà con il nostro approccio.
Speriamo che tu abbia imparato qualcosa da questo. Facci sapere se questo aiuta e buona fortuna.
+1: * Molto * bella domanda, per me personalmente. – Manhattan
Ci sono aggiornamenti su questo? Hai visto come il Referente è gestito correttamente nella mia risposta? – Manhattan