Mam migrację niektórych parserów z BeautifulSoup3 do BeautifulSoup4 i pomyślałem, że byłoby dobrym pomysłem, aby profilować, jak szybko by się to stało, biorąc pod uwagę, że lxml jest super szybki i jest to parser, którego używam z BS4, tutaj są to wyniki profilu:Beautifulsoup4 z lxml vs Beautifulsoup3
Dla BS3:
43208 function calls (42654 primitive calls) in 0.103 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 <string>:2(<module>)
18 0.000 0.000 0.000 0.000 <string>:8(__new__)
1 0.000 0.000 0.072 0.072 <string>:9(parser)
32 0.000 0.000 0.000 0.000 BeautifulSoup.py:1012(__init__)
1 0.000 0.000 0.000 0.000 BeautifulSoup.py:1018(buildTagMap)
...
Dla BS4 stosując lxml:
164440 function calls (163947 primitive calls) in 0.244 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.040 0.040 0.069 0.069 <string>:2(<module>)
18 0.000 0.000 0.000 0.000 <string>:8(__new__)
1 0.000 0.000 0.158 0.158 <string>:9(parser)
1 0.000 0.000 0.008 0.008 HTMLParser.py:1(<module>)
1 0.000 0.000 0.000 0.000 HTMLParser.py:54(HTMLParseError)
...
dlaczego BS4
dzwoni 4 tim es więcej funkcji? dlaczego w ogóle używa on HTMLParser
, jeśli ustawię go na lxml
?
najbardziej zauważalnych rzeczy zmieniłem od BS3 do BS4 były to:
BeautifulSoup(html, convertEntities=BeautifulSoup.HTML_ENTITIES) --->
BeautifulSoup(html, 'lxml')
[x.getText('**SEP**') for x in i.findChildren('font')[:2]] --->
[x.getText('**SEP**', strip=True) for x in i.findChildren('font')[:2]]
wszystko inne to tylko niektóre zmiany nazwy (jak findParent -> find_parent)
EDIT:
mój środowisko:
python 2.7.3
beautifulsoup4==4.1.0
lxml==2.3.4
EDYCJA 2:
Oto mała próbka kodu, aby ją wypróbować:
from cProfile import Profile
from BeautifulSoup import BeautifulSoup
from bs4 import BeautifulSoup as BS4
import urllib2
def parse(html):
soup = BS4(html, 'lxml')
hl = soup.find_all('span', {'class': 'mw-headline'})
return [x.get_text(strip=True) for x in hl]
def parse3(html):
soup = BeautifulSoup(html, convertEntities=BeautifulSoup.HTML_ENTITIES)
hl = soup.findAll('span', {'class': 'mw-headline'})
return [x.getText() for x in hl]
if __name__ == "__main__":
opener = urllib2.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
html = ''.join(opener.open('http://en.wikipedia.org/wiki/Price').readlines())
profiler = Profile()
print profiler.runcall(parse, html)
profiler.print_stats()
profiler2 = Profile()
print profiler2.runcall(parse3, html)
profiler2.print_stats()
Nie możemy odtworzyć wyników, jeśli nie podasz nam przykładowego adresu URL, z którym można by pracować. (Czy ustaliłeś, czy plik lxml.html przedstawia ten problem, czy tylko BS4?) –
tylko BS4, nie próbowałem tego z samym lxml. Pozwól mi stworzyć prosty przykład bardzo szybki, więc możesz go odtworzyć. – Hassek
ok wystarczy dodać mały przykład, aby każdy mógł go wypróbować – Hassek