Trích xuất một giá trị thuộc tính với beautifulsoup


110

Tôi đang cố gắng trích xuất nội dung của một thuộc tính "giá trị" trong thẻ "đầu vào" cụ thể trên một trang web. Tôi sử dụng mã sau:

import urllib
f = urllib.urlopen("http://58.68.130.147")
s = f.read()
f.close()

from BeautifulSoup import BeautifulStoneSoup
soup = BeautifulStoneSoup(s)

inputTag = soup.findAll(attrs={"name" : "stainfo"})

output = inputTag['value']

print str(output)

Tôi nhận được lỗi TypeError: chỉ số danh sách phải là số nguyên, không phải str

mặc dù từ tài liệu Beautifulsoup, tôi hiểu rằng chuỗi không phải là vấn đề ở đây ... nhưng tôi không có chuyên gia và tôi có thể đã hiểu nhầm.

Bất kỳ đề nghị được đánh giá rất cao! Cảm ơn trước.

Câu trả lời:


147

.find_all() trả về danh sách tất cả các phần tử được tìm thấy, vì vậy:

input_tag = soup.find_all(attrs={"name" : "stainfo"})

input_taglà một danh sách (có thể chỉ chứa một phần tử). Tùy thuộc vào những gì bạn muốn chính xác, bạn nên làm:

 output = input_tag[0]['value']

hoặc sử dụng .find()phương thức chỉ trả về một phần tử tìm thấy (đầu tiên):

 input_tag = soup.find(attrs={"name": "stainfo"})
 output = input_tag['value']

Công cụ tuyệt vời! Cảm ơn. bây giờ tôi có một câu hỏi về việc phân tích cú pháp đầu ra có một loạt dài các ký tự không phải ASCII nhưng tôi sẽ hỏi điều này trong một câu hỏi riêng.
Barnabe

3
không nên truy cập 'giá trị' theo stackoverflow.com/questions/2616659/… . Điều gì làm cho đoạn mã trên hoạt động trong trường hợp này? Tôi nghĩ bạn sẽ phải truy cập giá trị bằng cách làmoutput = inputTag[0].contents
Seth

@Seth - không, bởi vì anh ấy đang tìm kiếm 'giá trị thuộc về' của thẻ input và .contents trả về văn bản được bao bọc bởi thẻ (<span> Tôi là .contents </span>) - (chỉ trả lời ngay bây giờ vì tôi đã để kiểm tra lại những gì đang diễn ra; con số người khác có thể có lợi)
Dolan Antenucci

1
câu trả lời chính xác. tuy nhiên, tôi sẽ sử dụng inputTag[0].get('value') thay vì inputTag[0]['value']để ngăn không có con trỏ nào trong trường hợp thẻ là thuộc tính không có giá trị
lưỡng cư

Những gì về các liên kết không được liên kết trực tiếp đến trang chủ của trang web đang truy cập, Làm thế nào để nhận được tất cả các liên kết dù được liên kết trực tiếp hay gián tiếp đến trang web.
Rink 16

26

Trong Python 3.x, chỉ cần sử dụng get(attr_name)trên đối tượng thẻ của bạn mà bạn đang sử dụng find_all:

xmlData = None

with open('conf//test1.xml', 'r') as xmlFile:
    xmlData = xmlFile.read()

xmlDecoded = xmlData

xmlSoup = BeautifulSoup(xmlData, 'html.parser')

repElemList = xmlSoup.find_all('repeatingelement')

for repElem in repElemList:
    print("Processing repElem...")
    repElemID = repElem.get('id')
    repElemName = repElem.get('name')

    print("Attribute id = %s" % repElemID)
    print("Attribute name = %s" % repElemName)

chống lại tệp XML conf//test1.xmltrông giống như:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <singleElement>
        <subElementX>XYZ</subElementX>
    </singleElement>
    <repeatingElement id="11" name="Joe"/>
    <repeatingElement id="12" name="Mary"/>
</root>

bản in:

Processing repElem...
Attribute id = 11
Attribute name = Joe
Processing repElem...
Attribute id = 12
Attribute name = Mary

Bạn có phiền nếu tôi chỉnh sửa điều này để tuân theo PEP 8 và sử dụng các phương pháp định dạng chuỗi hiện đại hơn không?
AMC

Đó là tốt, đi cho nó
amphibient

6

Nếu bạn muốn truy xuất nhiều giá trị của các thuộc tính từ nguồn ở trên, bạn có thể sử dụng findAllvà hiểu danh sách để có được mọi thứ bạn cần:

import urllib
f = urllib.urlopen("http://58.68.130.147")
s = f.read()
f.close()

from BeautifulSoup import BeautifulStoneSoup
soup = BeautifulStoneSoup(s)

inputTags = soup.findAll(attrs={"name" : "stainfo"})
### You may be able to do findAll("input", attrs={"name" : "stainfo"})

output = [x["stainfo"] for x in inputTags]

print output
### This will print a list of the values.

4

Tôi thực sự sẽ gợi ý cho bạn một cách tiết kiệm thời gian để thực hiện điều này giả sử rằng bạn biết loại thẻ nào có những thuộc tính đó.

giả sử một thẻ xyz có tập tin đính kèm tên là "staininfo" ..

full_tag = soup.findAll("xyz")

Và tôi không thể hiểu rằng full_tag là một danh sách

for each_tag in full_tag:
    staininfo_attrb_value = each_tag["staininfo"]
    print staininfo_attrb_value

Vì vậy, bạn có thể nhận được tất cả các giá trị attrb của staininfo cho tất cả các thẻ xyz


3

bạn cũng có thể sử dụng cái này:

import requests
from bs4 import BeautifulSoup
import csv

url = "http://58.68.130.147/"
r = requests.get(url)
data = r.text

soup = BeautifulSoup(data, "html.parser")
get_details = soup.find_all("input", attrs={"name":"stainfo"})

for val in get_details:
    get_val = val["value"]
    print(get_val)

Điều này khác với các câu trả lời cũ hơn nhiều đã có ở đây như thế nào?
AMC

0

Tôi đang sử dụng điều này với Beautifulsoup 4.8.1 để nhận giá trị của tất cả các thuộc tính lớp của các phần tử nhất định:

from bs4 import BeautifulSoup

html = "<td class='val1'/><td col='1'/><td class='val2' />"

bsoup = BeautifulSoup(html, 'html.parser')

for td in bsoup.find_all('td'):
    if td.has_attr('class'):
        print(td['class'][0])

Điều quan trọng cần lưu ý là khóa thuộc tính truy xuất danh sách ngay cả khi thuộc tính chỉ có một giá trị duy nhất.

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.