Python: BeautifulSoup - nhận một giá trị thuộc tính dựa trên thuộc tính tên


96

Tôi muốn in một giá trị thuộc tính dựa trên tên của nó, lấy ví dụ

<META NAME="City" content="Austin">

Tôi muốn làm một cái gì đó như thế này

soup = BeautifulSoup(f) //f is some HTML containing the above meta tag
for meta_tag in soup('meta'):
    if meta_tag['name'] == 'City':
         print meta_tag['content']

Đoạn mã trên đưa ra một KeyError: 'name', tôi tin rằng điều này là do tên được sử dụng bởi BeatifulSoup nên nó không thể được sử dụng làm đối số từ khóa.

Câu trả lời:


160

Nó khá đơn giản, sử dụng như sau:

>>> from bs4 import BeautifulSoup
>>> soup = BeautifulSoup('<META NAME="City" content="Austin">')
>>> soup.find("meta", {"name":"City"})
<meta name="City" content="Austin" />
>>> soup.find("meta", {"name":"City"})['content']
u'Austin'

Để lại bình luận nếu có gì chưa rõ.


1
làm cách nào để thực hiện việc này nếu tôi muốn tìm tất cả các trường hợp, tức là ngay bây giờ, soup.find ("meta", {"name": "City"}) ['content'] đưa ra kết quả đầu tiên, nhưng có một kết quả khác dòng trong món súp là <META NAME = 'City "content =" San Francisco ">. Làm cách nào để tôi có thể sửa đổi mã để tôi có được' Austin 'và' San Francisco '?
tràn tên

1
Cũ câu hỏi, nhưng đây là một giải pháp đơn giản trong trường hợp bất cứ ai khác đi kèm tìm kiếm nó: soup.findAll("meta", {"name":"City"})['content']. Điều này sẽ trả lại tất cả các lần xuất hiện.
Hannon César

làm cách nào để lấy giá trị của một thuộc tính cụ thể? có nghĩa là tôi chỉ có thuộc tính ...
Phaneendra Charyulu Kanduri

28

theharshest đã trả lời câu hỏi nhưng đây là một cách khác để làm điều tương tự. Ngoài ra, trong ví dụ của bạn, bạn có NAME được viết hoa và trong mã của bạn, bạn có tên được viết thường.

s = '<div class="question" id="get attrs" name="python" x="something">Hello World</div>'
soup = BeautifulSoup(s)

attributes_dictionary = soup.find('div').attrs
print attributes_dictionary
# prints: {'id': 'get attrs', 'x': 'something', 'class': ['question'], 'name': 'python'}

print attributes_dictionary['class'][0]
# prints: question

print soup.find('div').get_text()
# prints: Hello World

Sự không khớp trong trường hợp có thể là do cố ý vì BeautifulSoup chuyển đổi thẻ thành chữ thường theo mặc định. Trong trường hợp này: BeautifulSoup ( '<META NAME = "City" content = "Austin">') trả về <meta content = "Austin" name = "Thành phố" />
tuckermi

9

Dự tiệc muộn 6 năm nhưng tôi đã tìm kiếm cách trích xuất giá trị thuộc tính thẻ của phần tử html , vì vậy:

<span property="addressLocality">Ayr</span>

Tôi muốn "addressLocality". Tôi tiếp tục được hướng dẫn trở lại đây, nhưng câu trả lời không thực sự giải quyết được vấn đề của tôi.

Cuối cùng thì tôi đã làm được như thế nào:

>>> from bs4 import BeautifulSoup as bs

>>> soup = bs('<span property="addressLocality">Ayr</span>', 'html.parser')
>>> my_attributes = soup.find().attrs
>>> my_attributes
{u'property': u'addressLocality'}

Vì nó là một chính tả, bạn cũng có thể sử dụng keysvà 'giá trị'

>>> my_attributes.keys()
[u'property']
>>> my_attributes.values()
[u'addressLocality']

Hy vọng rằng nó sẽ giúp ai đó khác!


8

Các hoạt động sau:

from bs4 import BeautifulSoup

soup = BeautifulSoup('<META NAME="City" content="Austin">', 'html.parser')

metas = soup.find_all("meta")

for meta in metas:
    print meta.attrs['content'], meta.attrs['name']

7

Câu trả lời của theharshest là giải pháp tốt nhất, nhưng FYI vấn đề bạn gặp phải liên quan đến thực tế là đối tượng Tag trong Beautiful Soup hoạt động giống như một từ điển Python. Nếu bạn truy cập thẻ ['name'] trên một thẻ không có thuộc tính 'name', bạn sẽ nhận được KeyError.


1

Người ta cũng có thể thử giải pháp này:

Để tìm giá trị, được viết trong khoảng của bảng

htmlContent


<table>
    <tr>
        <th>
            ID
        </th>
        <th>
            Name
        </th>
    </tr>


    <tr>
        <td>
            <span name="spanId" class="spanclass">ID123</span>
        </td>

        <td>
            <span>Bonny</span>
        </td>
    </tr>
</table>

Mã Python


soup = BeautifulSoup(htmlContent, "lxml")
soup.prettify()

tables = soup.find_all("table")

for table in tables:
   storeValueRows = table.find_all("tr")
   thValue = storeValueRows[0].find_all("th")[0].string

   if (thValue == "ID"): # with this condition I am verifying that this html is correct, that I wanted.
      value = storeValueRows[1].find_all("span")[0].string
      value = value.strip()

      # storeValueRows[1] will represent <tr> tag of table located at first index and find_all("span")[0] will give me <span> tag and '.string' will give me value

      # value.strip() - will remove space from start and end of the string.

     # find using attribute :

     value = storeValueRows[1].find("span", {"name":"spanId"})['class']
     print value
     # this will print spanclass

1
If tdd='<td class="abc"> 75</td>'
In Beautifulsoup 

if(tdd.has_attr('class')):
   print(tdd.attrs['class'][0])


Result:  abc

1
Mặc dù mã này có thể trả lời câu hỏi, nhưng việc cung cấp ngữ cảnh bổ sung về cách thức và / hoặc lý do tại sao nó giải quyết vấn đề sẽ cải thiện giá trị lâu dài của câu trả lời.
shaunakde
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.