2015-01-06 16 views
15

Tôi đang làm việc trên dự án cào web và đã gặp sự cố với tốc độ. Để cố gắng khắc phục, tôi muốn sử dụng lxml thay vì html.parser làm trình phân tích cú pháp của BeautifulSoup. Tôi đã có thể thực hiện điều này:Đặt lxml làm trình phân tích cú pháp BeautifulSoup mặc định

soup = bs4.BeautifulSoup(html, 'lxml') 

nhưng tôi không muốn phải liên tục nhập 'lxml' mỗi lần tôi gọi BeautifulSoup. Có cách nào tôi có thể đặt trình phân tích cú pháp nào sẽ sử dụng một lần ở đầu chương trình của tôi không?

+1

'lxml' * được * mặc định trong 'bs4', giả sử bạn đã' lxml' cài đặt. Vì vậy, trừ khi bạn tình cờ làm việc với BeautifulSoup3 ... – roippi

+0

Tôi đang sử dụng bs4, nhưng tôi không biết cách kiểm tra trình phân tích cú pháp nào tôi hiện đang sử dụng. Cảm ơn bạn! –

Trả lời

12

Theo trang Specifying the parser to use tài liệu:

Đối số đầu tiên để các nhà xây dựng BeautifulSoup là một chuỗi hoặc một mở filehandle-đánh dấu bạn muốn phân tích cú pháp. Đối số thứ hai là cách bạn muốn đánh dấu phân tích cú pháp.

Nếu bạn không chỉ định bất cứ điều gì, bạn sẽ nhận được trình phân tích cú pháp HTML tốt nhất được cài đặt . Beautiful Soup xếp hạng trình phân tích cú pháp của lxml là tốt nhất, sau đó là html5lib’s, sau đó là trình phân tích cú pháp tích hợp của Python.

Nói cách khác, chỉ cần cài đặt lxml trong cùng môi trường python làm cho trình phân tích cú pháp mặc định.

Mặc dù lưu ý rằng việc nêu rõ phân tích cú pháp được coi là phương pháp thực hành tốt nhất. Có differences between parsers có thể dẫn đến các lỗi tinh vi khó gỡ lỗi nếu bạn cho phép BeautifulSoup tự chọn trình phân tích cú pháp tốt nhất. Bạn cũng phải nhớ rằng bạn cần cài đặt lxml. Và, nếu bạn không cài đặt nó, bạn thậm chí sẽ không nhận thấy nó - BeautifulSoup sẽ chỉ nhận được trình phân tích cú pháp sẵn có tiếp theo mà không phải ném bất kỳ lỗi nào.

Nếu bạn vẫn không muốn chỉ định trình phân tích cú pháp một cách rõ ràng, ít nhất hãy ghi chú cho tương lai hoặc người khác sử dụng mã bạn đã viết trong tài liệu README/tài liệu của dự án và liệt kê lxml trong yêu cầu dự án của bạn cùng với beautifulsoup4.

Bên cạnh đó: "Explicit is better than implicit."

+0

Lưu ý, với bs4 phiên bản 4.5.1, khi xác định trình phân tích cú pháp 'lxml' và không cài đặt nó bs4 ** thì ** lỗi: bs4.FeatureNotFound: Không thể tìm thấy trình tạo hình bằng các tính năng bạn yêu cầu: lxml. Bạn có cần phải cài đặt một thư viện phân tích cú pháp không? – glexey

4

Rõ ràng có một cái nhìn tại accepted answer đầu tiên. Điều này khá tốt và đối với tính kỹ thuật này:

nhưng tôi không muốn phải liên tục nhập 'lxml' mỗi khi tôi gọi BeautifulSoup. Có cách nào tôi có thể đặt trình phân tích cú pháp nào sử dụng một lần ở số phần đầu của chương trình của tôi không?

Nếu tôi hiểu câu hỏi của bạn một cách chính xác, tôi có thể nghĩ đến hai phương pháp giúp bạn tiết kiệm một số phím: - Xác định hàm bao, hoặc - Tạo chức năng một phần.

# V1 - define a wrapper function - most straight-forward. 
import bs4 

def bs_parse(html): 
    return bs4.BeautifulSoup(html, 'lxml') 
# ... 
html = ... 
bs_parse(html) 

Hoặc nếu bạn cảm thấy thích khoe ...

import bs4 
from functools import partial 
bs_parse = partial(bs4.BeautifulSoup, features='lxml') 
# ... 
html = ... 
bs_parse(html) 
+0

Bạn có thể thêm giải thích về cách 'partial' hoạt động không? Có bất kỳ lợi thế để sử dụng nó trên một chức năng wrapper? – r3robertson

+1

@ r3robertson Có tài liệu hướng dẫn tốt cho các chức năng một phần tại đây: https://docs.python.org/2/library/functools.html#functools.partial Có vẻ như tôi là một phần chậm hơn và phức tạp hơn dưới mui xe so với một trình bao bọc, nhưng một khi nó đã được triển khai, nó khá dễ sử dụng. Một phần chức năng được sạch sẽ cho một thiếu một từ tốt hơn từ quan điểm toán học của xem. Các ngôn ngữ khác có điều này và nó được coi là một sử dụng tốt của lập trình chức năng của một số, nhưng bạn phải trả một mức giá về tốc độ và nhập khẩu thêm. Tôi vẫn sử dụng các chức năng một phần vì chúng rất vui. – Leonid

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