2012-07-02 25 views
5

Tôi đang di chuyển một số trình phân tích cú pháp từ BeautifulSoup3 sang BeautifulSoup4 và tôi nghĩ rằng sẽ nhanh hơn khi xem xét nhanh hơn lxml và đó là trình phân tích cú pháp tôi đang sử dụng với BS4, tại đây là kết quả hồ sơ:Beautifulsoup4 với lxml vs Beautifulsoup3

Đối 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) 
... 

Đối với BS4 sử dụng 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) 
... 

tại sao BS4 đang kêu gọi 4 tim es nhiều chức năng hơn? tại sao nó sử dụng HTMLParser ở tất cả nếu tôi đặt nó để sử dụng lxml?

Những điều đáng chú ý nhất mà tôi đã thay đổi từ BS3 để BS4 đã này:

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]] 

mọi thứ khác chỉ là một số thay đổi tên (như findParent -> find_parent)

EDIT:

của tôi môi trường:

python 2.7.3 
beautifulsoup4==4.1.0 
lxml==2.3.4 

EDIT 2:

Đây là một mẫu mã nhỏ để thử nó ra:

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() 
+2

Chúng tôi không thể tạo lại kết quả của bạn nếu bạn không cung cấp cho chúng tôi URL mẫu để làm việc với sự kiện hiển thị vấn đề này. (Ngoài ra, bạn đã xác định liệu lxml.html có hiển thị vấn đề này hay chỉ BS4?) –

+0

chỉ BS4, chưa thử điều này với lxml một mình. Hãy để tôi tạo một ví dụ dễ dàng thực sự nhanh chóng để các bạn có thể tái sản xuất nó – Hassek

+0

ok chỉ cần thêm một ví dụ nhỏ để mọi người có thể dùng thử – Hassek

Trả lời

1

Tôi tin rằng vấn đề chính là một lỗi trong Beautiful Soup 4. Tôi đã filed it và sửa chữa sẽ được phát hành trong phiên bản tiếp theo. Cảm ơn bạn đã tìm thấy điều này.

Điều đó nói rằng, tôi không biết tại sao hồ sơ của bạn đề cập đến lớp HTMLParser ở tất cả, với điều kiện bạn đang sử dụng lxml.

+0

yep và trong bài kiểm tra wikipedia, nó cũng không hiển thị. Cảm ơn bạn đã chỉ nó là một lỗi, tôi hy vọng điều này sẽ được khắc phục sớm! – Hassek

Các vấn đề liên quan