Beautifulsoup ile bir öznitelik değeri çıkarma


112

Bir web sayfasındaki belirli bir "giriş" etiketindeki tek bir "değer" özniteliğinin içeriğini çıkarmaya çalışıyorum. Aşağıdaki kodu kullanıyorum:

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)

TypeError alıyorum: liste indeksleri tamsayı olmalı, str değil

Beautifulsoup belgelerinden dizelerin burada bir sorun olmaması gerektiğini anlıyorum ... ama bir uzman değilim ve yanlış anlamış olabilirim.

Herhangi bir öneri büyük beğeni topluyor! Şimdiden teşekkürler.

Yanıtlar:


150

.find_all() bulunan tüm öğelerin listesini döndürür, bu nedenle:

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

input_tagbir listedir (muhtemelen yalnızca bir öğe içerir). Tam olarak ne istediğine bağlı olarak ya yapmalısın:

 output = input_tag[0]['value']

veya .find()yalnızca bir (ilk) bulunan öğeyi döndüren yöntemi kullanın :

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

Harika şeyler! Teşekkürler. şimdi ASCII olmayan uzun bir grup karakter olan çıktıyı ayrıştırmakla ilgili bir sorum var ama bunu ayrı bir soruda soracağım.
Barnabe

3
stackoverflow.com/questions/2616659/… uyarınca 'değere' erişilmemelidir . Yukarıdaki kodun bu durumda çalışmasını sağlayan nedir? Bunu yaparak değere erişmeniz gerektiğini düşündümoutput = inputTag[0].contents
Seth

@Seth - hayır, çünkü girdi-etiketinin 'değerini' arıyor ve .contents etiketiyle kapsüllenmiş metni döndürüyor (<span> Ben .içindeyim </span>) - (sadece şimdi neler olup bittiğini tekrar kontrol etmek için; başka birinin bundan yararlanabileceğini
düşünün

1
mükemmel cevap. ancak, etiketin değer özniteliği olmaması durumunda hiçbir işaretçiyi önlemek için inputTag[0].get('value') yerine kullanırdıminputTag[0]['value']
amfibient

Ziyaret edilen web sitesinin ana sayfasına doğrudan bağlı olmayan bağlantılara ne dersiniz? Web sayfasına doğrudan veya dolaylı olarak bağlantılı tüm bağlantılar nasıl alınır.
Rink16

26

İçinde Python 3.x, kullandığınız get(attr_name)etiket nesnenizi kullanmanız yeterlidir 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)

conf//test1.xmlgibi görünen XML dosyasına karşı :

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

baskılar:

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

Bunu PEP 8'i takip edecek ve daha modern dize biçimlendirme yöntemlerini kullanacak şekilde düzenlesem sorun olur mu?
AMC

Sorun değil, devam edin
amfibi

6

Yukarıdaki kaynaktan birden çok öznitelik değeri findAllalmak istiyorsanız, ihtiyacınız olan her şeyi elde etmek için ve bir liste anlama özelliğini kullanabilirsiniz :

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

Aslında, bu niteliklerin ne tür etiketlere sahip olduğunu bildiğinizi varsayarak, size zaman kazandıran bir yol öneririm.

bir xyz etiketinin "staininfo" adlı atritube'ye sahip olduğunu varsayalım ..

full_tag = soup.findAll("xyz")

Ve tam etiketin bir liste olduğunu anlamanı istemiyorum

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

Böylece tüm xyz etiketleri için staininfo'nun tüm attrb değerlerini alabilirsiniz.


3

bunu da kullanabilirsiniz:

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)

Bu, zaten burada olan daha eski cevaplardan nasıl farklıdır?
AMC

0

Bunu Beautifulsoup 4.8.1 ile belirli öğelerin tüm sınıf özelliklerinin değerini elde etmek için kullanıyorum:

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

Öznitelik tek bir değere sahip olduğunda bile öznitelik anahtarının bir listeyi aldığını unutmamak önemlidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.