Đẹp Soup và trích xuất một div và nội dung của nó bằng ID


147
soup.find("tagName", { "id" : "articlebody" })

Tại sao điều này KHÔNG trả lại các <div id="articlebody"> ... </div>thẻ và công cụ ở giữa? Nó không trả lại gì cả. Và tôi biết thực tế nó tồn tại bởi vì tôi đang nhìn chằm chằm vào nó từ

soup.prettify()

soup.find("div", { "id" : "articlebody" }) cũng không hoạt động.

( EDIT: Tôi thấy rằng BeautifulSoup không phân tích chính xác trang của tôi, điều đó có nghĩa là trang tôi đang cố phân tích không được định dạng chính xác trong SGML hoặc bất cứ điều gì)


(Đối với EDIT của bạn, câu hỏi này vẫn có giá trị như một tài nguyên có thể sử dụng lại cho người khác, ngay cả khi trình phân tích cú pháp không hoạt động trên trang cụ thể của bạn)
smci

Câu trả lời:


202

Bạn nên đăng tài liệu mẫu của bạn, bởi vì mã hoạt động tốt:

>>> import BeautifulSoup
>>> soup = BeautifulSoup.BeautifulSoup('<html><body><div id="articlebody"> ... </div></body></html')
>>> soup.find("div", {"id": "articlebody"})
<div id="articlebody"> ... </div>

Tìm <div>s bên trong<div> s cũng hoạt động:

>>> soup = BeautifulSoup.BeautifulSoup('<html><body><div><div id="articlebody"> ... </div></div></body></html')
>>> soup.find("div", {"id": "articlebody"})
<div id="articlebody"> ... </div>

2
tài liệu ví dụ của tôi là rất lớn. Tôi đang theo dõi vấn đề - tôi nghĩ rằng điều này không hoạt động trên div của div. Tôi đã đếm được có bao nhiêu div trong tài liệu có in len (súp ('div')) dẫn đến 10, và tôi có thể R CLE RÀNG thấy nhiều hơn 10 div với con bọ lửa. Vì vậy, tôi nghĩ rằng nó không thể tìm thấy div bên trong div, vì vậy tôi cần thu hẹp mọi thứ bằng trình bao bọc.
Tony Stark

8
Chà, không thể trả lời câu hỏi của bạn, quả cầu pha lê không phải là một cách gỡ lỗi đáng tin cậy. :)
Lukáš Lalinský

1
Tôi đã thử mã này. div có <embed> và tôi không thể in phần nhúng bên trong nó.
Vincent

13
hoặc đơn giản hơndiv = soup.find(id="articlebody")
jfs

4
hoặcsoup.find('div', id='articlebody')
Trevor Boyd Smith

71

Để tìm một phần tử của nó id:

div = soup.find(id="articlebody")

15

Beautiful Soup 4 hỗ trợ hầu hết các bộ chọn CSS với .select()phương thức , do đó bạn có thể sử dụng idbộ chọn như:

soup.select('#articlebody')

Nếu bạn cần chỉ định loại phần tử, bạn có thể thêm bộ chọn loại trước idbộ chọn:

soup.select('div#articlebody')

Các .select()phương pháp sẽ trả về một tập hợp các yếu tố, có nghĩa là nó sẽ trả lại kết quả tương tự như sau .find_all()phương pháp ví dụ:

soup.find_all('div', id="articlebody")
# or
soup.find_all(id="articlebody")

Nếu bạn chỉ muốn chọn một yếu tố duy nhất, thì bạn chỉ có thể sử dụng .find()phương thức :

soup.find('div', id="articlebody")
# or
soup.find(id="articlebody")

13

Tôi nghĩ rằng có một vấn đề khi các thẻ 'div' được lồng quá nhiều. Tôi đang cố phân tích một số liên hệ từ tệp html trên facebook và Beautifulsoup không thể tìm thấy thẻ "div" với lớp "fcontent".

Điều này xảy ra với các lớp khác là tốt. Khi tôi tìm kiếm div nói chung, nó chỉ biến những thứ không được lồng vào nhau.

Mã nguồn html có thể là bất kỳ trang nào từ facebook của danh sách bạn bè của một người bạn của bạn (không phải là một trong những người bạn của bạn). Nếu ai đó có thể kiểm tra nó và đưa ra một số lời khuyên tôi sẽ thực sự đánh giá cao nó.

Đây là mã của tôi, nơi tôi chỉ cố gắng in số lượng thẻ "div" với lớp "fcontent":

from BeautifulSoup import BeautifulSoup 
f = open('/Users/myUserName/Desktop/contacts.html')
soup = BeautifulSoup(f) 
list = soup.findAll('div', attrs={'class':'fcontent'})
print len(list)

9

Hầu hết có lẽ là do trình phân tích cú pháp beautifulsoup mặc định có vấn đề. Thay đổi một trình phân tích cú pháp khác, như 'lxml' và thử lại.


Điều này làm việc cho tôi, cảm ơn! Tôi đã sử dụngsoup = BeautifulSoup(data, parser="html.parser")
will-hart

8

Trong nguồn beautifulsoup, dòng này cho phép các div được lồng trong các div; vì vậy mối quan tâm của bạn trong nhận xét của lukas sẽ không có giá trị.

NESTABLE_BLOCK_TAGS = ['blockquote', 'div', 'fieldset', 'ins', 'del']

Những gì tôi nghĩ bạn cần làm là chỉ định các attrs bạn muốn, chẳng hạn như

source.find('div', attrs={'id':'articlebody'})

5

bạn đã thử chưa soup.findAll("div", {"id": "articlebody"}) chưa

Nghe có vẻ điên rồ, nhưng nếu bạn đang tìm kiếm thứ gì đó từ tự nhiên, bạn không thể loại trừ nhiều div ...


4

Tôi đã sử dụng:

soup.findAll('tag', attrs={'attrname':"attrvalue"})

Như cú pháp của tôi để tìm / findall; điều đó nói rằng, trừ khi có các tham số tùy chọn khác giữa danh sách thẻ và thuộc tính, điều này không nên khác nhau.


4

Đã xảy ra với tôi trong khi cố gắng để cạo Google.
Tôi đã kết thúc bằng cách sử dụng pyquery.
Tải về:

pip install pyquery

Sử dụng:

from pyquery import PyQuery    
pq = PyQuery('<html><body><div id="articlebody"> ... </div></body></html')
tag = pq('div#articlebody')

3

Đây là một đoạn mã

soup = BeautifulSoup(:"index.html")
titleList = soup.findAll('title')
divList = soup.findAll('div', attrs={ "class" : "article story"})

Như bạn có thể thấy tôi tìm thấy tất cả các thẻ và sau đó tôi tìm thấy tất cả các thẻ có class = "article" bên trong


0

Tài Idsản luôn được xác định duy nhất. Điều đó có nghĩa là bạn có thể sử dụng nó trực tiếp mà không cần chỉ định thành phần. Do đó, nó là một điểm cộng nếu các yếu tố của bạn có nó để phân tích nội dung.

divEle = soup.find(id = "articlebody")
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.