Migliorare BeautifulSoup Perf
-
11-10-2019 - |
Domanda
Ho il seguente set di codice parsing informazioni deliziosa. Esso stampa i dati da una pagina Delicious nel seguente formato
Bookmark | Numero di persone
Bookmark | Numero di persone ecc ...
Ho usato per usare il seguente metodo per trovare queste informazioni.
def extract (soup):
links = soup.findAll('a',rel='nofollow')
for link in links:
print >> outfile, link['href']
hits = soup.findAll('span', attrs={'class': 'delNavCount'})
for hit in hits:
print >> outfile, hit.contents
#File to export data to
outfile = open("output.txt", "w")
#Browser Agent
br = Browser()
br.set_handle_robots(False)
br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]
url= "http://www.delicious.com/asd"
page = br.open(url)
html = page.read()
soup = BeautifulSoup(html)
extract(soup)
Ma il problema era che alcuni segnalibri non ha ancora hanno un certo numero di persone, così ho deciso di analizzarlo in modo diverso che vorrei ottenere i dati contemporaneamente e stampare i segnalibri e il numero di persone lato a fianco.
EDIT: preso da 15 - 5 secondi con questa versione aggiornata, eventuali ulteriori suggerimenti
def extract (soup):
bookmarkset = soup.findAll('div', 'data')
for bookmark in bookmarkset:
link = bookmark.find('a',)
vote = bookmark.find('span', 'delNavCount')
try:
print >> outfile, link['href'], " | " ,vote.contents
except:
print >> outfile, "[u'0']"
#print bookmarkset
#File to export data to
outfile = open("output.txt", "w")
#Browser Agent
br = Browser()
br.set_handle_robots(False)
br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')]
url= "http://www.delicious.com/asd"
page = br.open(url)
html = page.read()
soup = BeautifulSoup(html)
extract(soup)
Le prestazioni su questo è terribile, però, prende 17 secondi per analizzare la prima pagina, e circa 15 secondi in seguito su una macchina abbastanza decente. E 'notevolmente ridotta, quando si passa dal primo bit di codice al secondo bit. C'è qualcosa che posso fare per imporve perf qui?
Soluzione
Non capisco il motivo per cui si stanno assegnando a vote
- due volte. Il primo incarico è inutile e davvero molto pesante, in quanto deve analizzare l'intero documento - ad ogni iterazione. Perché?
vote = BeautifulSoup(html)
vote = bookmark.findAll('span', attrs={'class': 'delNavCount'})
Altri suggerimenti
Se siete preoccupati per le prestazioni si potrebbe avere uno sguardo a qualcosa che parla con la deliziosa API, piuttosto che screen-scraping, vale a dire pydelicious . Ad esempio:
>>> import pydelicious
>>> pydelicious.get_userposts('asd')
[{'extended': '', 'description': u'Ksplice - System administration and software blog', 'tags': u'sysadm, blog, interesting', 'url': u'http://blog.ksplice.com/', 'user': u'asd'
BeautifulSoup fa molto di più di quello che ti serve in questo caso. Se davvero si vuole alzare la velocità, poi vorrei suggerire un approccio più fondamentale di urllib + un semplice parser riga per riga.
L'analisi di una pagina la dimensione dell'esempio "asd" dovrebbe prendere ben meno di un secondo su una macchina moderna.