Analisi dei dati html nella lista python per la manipolazione

Sto cercando di leggere in siti Web html ed estrarre i loro dati. Ad esempio, mi piacerebbe leggere l’EPS (utile per azione) negli ultimi 5 anni di società. Fondamentalmente, posso leggerlo e posso usare BeautifulSoup o html2text per creare un enorme blocco di testo. Poi voglio cercare il file – ho usato re.search – ma non riesco a farlo funzionare correttamente. Ecco la riga a cui sto tentando di accedere:

EPS (base) \ n13.4620.6226.6930.1732.81 \ n \ n

Quindi mi piacerebbe creare un elenco chiamato EPS = [13.46, 20.62, 26.69, 30.17, 32.81].

Grazie per qualsiasi aiuto.

from stripogram import html2text from urllib import urlopen import re from BeautifulSoup import BeautifulSoup ticker_symbol = 'goog' url = 'http://www.marketwatch.com/investing/stock/' full_url = url + ticker_symbol + '/financials' #build url text_soup = BeautifulSoup(urlopen(full_url).read()) #read in text_parts = text_soup.findAll(text=True) text = ''.join(text_parts) eps = re.search("EPS\s+(\d+)", text) if eps is not None: print eps.group(1) 

Non è una buona pratica usare regex per analizzare l’html. Usa il parser BeautifulSoup : trova la cella con la class rowTitle e il testo EPS (Basic) al suo interno, quindi itera sui fratelli successivi con class valueCell :

 from urllib import urlopen from BeautifulSoup import BeautifulSoup url = 'http://www.marketwatch.com/investing/stock/goog/financials' text_soup = BeautifulSoup(urlopen(url).read()) #read in titles = text_soup.findAll('td', {'class': 'rowTitle'}) for title in titles: if 'EPS (Basic)' in title.text: print [td.text for td in title.findNextSiblings(attrs={'class': 'valueCell'}) if td.text] 

stampe:

 ['13.46', '20.62', '26.69', '30.17', '32.81'] 

Spero possa aiutare.

Avrei un approccio molto diverso. Usiamo LXML per raschiare pagine html

Uno dei motivi per cui siamo passati è stato perché BS non veniva mantenuto per un po ‘- o dovrei dire aggiornato.

Nel mio test ho eseguito quanto segue

 import requests from lxml import html from collections import OrderedDict page_as_string = requests.get('http://www.marketwatch.com/investing/stock/goog/financials').content tree = html.fromstring(page_as_string) 

Ora ho guardato la pagina e vedo che i dati sono divisi in due tabelle. Dal momento che vuoi EPS, ho notato che è nella seconda tabella. Potremmo scrivere del codice per sistemarlo a livello programmatico, ma lo lascerò per te.

 tables = [ e for e in tree.iter() if e.tag == 'table'] eps_table = tables[-1] 

ora ho notato che la prima riga ha le intestazioni delle colonne, quindi voglio separare tutte le righe

 table_rows = [ e for e in eps_table.iter() if e.tag == 'tr'] 

ora consente di ottenere le intestazioni delle colonne:

 column_headings =[ e.text_content() for e in table_rows[0].iter() if e.tag == 'th'] 

Finalmente possiamo mappare le intestazioni delle colonne alle etichette delle righe e ai valori delle celle

 my_results = [] for row in table_rows[1:]: cell_content = [ e.text_content() for e in row.iter() if e.tag == 'td'] temp_dict = OrderedDict() for numb, cell in enumerate(cell_content): if numb == 0: temp_dict['row_label'] = cell.strip() else: dict_key = column_headings[numb] temp_dict[dict_key] = cell my_results.append(temp_dict) 

ora per accedere ai risultati

 for row_dict in my_results: if row_dict['row_label'] == 'EPS (Basic)': for key in row_dict: print key, ':', row_dict[key] row_label : EPS (Basic) 2008 : 13.46 2009 : 20.62 2010 : 26.69 2011 : 30.17 2012 : 32.81 5-year trend : 

Ora c’è ancora molto da fare, ad esempio non ho provato per l’ortogonalità (il numero di celle in ogni riga è uguale).

Finalmente sono un novizio e ho il sospetto che altri consiglieranno metodi più diretti per ottenere questi elementi (xPath o cssselect) ma questo funziona e ti porta tutto dal tavolo in un modo ben strutturato.

Dovrei aggiungere che ogni riga della tabella è disponibile, sono nell’ordine di riga originale. Il primo elemento (che è un dizionario) nell’elenco my_results ha i dati della prima riga, il secondo ha i dati dalla seconda riga, ecc.

Quando ho bisogno di una nuova build di lxml, visito una pagina gestita da un bravo ragazzo di UC-IRVINE

Spero che aiuti

 from bs4 import BeautifulSoup import urllib2 import lxml import pandas as pd url = 'http://markets.ft.com/research/Markets/Tearsheets/Financials?s=CLLN:LSE&subview=BalanceSheet' soup = BeautifulSoup(urllib2.urlopen(url).read()) table = soup.find('table', {'data-ajax-content' : 'true'}) data = [] for row in table.findAll('tr'): cells = row.findAll('td') cols = [ele.text.strip() for ele in cells] data.append([ele for ele in cols if ele]) df = pd.DataFrame(data) print df dictframe = df.to_dict() print dictframe 

Il codice sopra ti darà un DataFrame dalla pagina web e poi lo userà per creare un dizionario python.