2010-04-10 14 views
53

J'essaie d'extraire le contenu d'un seul attribut "value" dans une balise "input" spécifique sur une page Web. J'utilise le code suivant:Extraction d'une valeur d'attribut avec beautifulsoup

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) 

Je reçois TypeError: indices de la liste doivent être des nombres entiers, pas str

même si de la documentation beautifulsoup je comprends que les chaînes ne devraient pas être un problème ici ... mais Je n'ai pas de spécialiste et j'ai peut-être mal compris.

Toute suggestion est grandement appréciée! Merci d'avance.

Répondre

81

.findAll() rendements liste de tous les éléments présents, de sorte que:

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

inputTag est une liste (contenant probablement un seul élément). En fonction de ce que vous voulez exactement vous soit devriez faire:

output = inputTag[0]['value'] 

ou utiliser la méthode .find() qui retourne un seul (premier) élément trouvé:

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

Great stuff! Merci. Maintenant, j'ai une question à propos de l'analyse de la sortie que j'ai un long tas de caractères non-ASCII, mais je vais poser cette question dans une autre question. – Barnabe

+1

ne devrait pas l'accès à la «valeur» selon http://stackoverflow.com/questions/2616659/extracting-value-in-beautifulsoup. Qu'est-ce qui fait que le code ci-dessus fonctionne dans ce cas? Je pensais que vous deviez accéder à la valeur en faisant 'output = inputTag [0].contents' – Seth

+0

@Seth - non, parce qu'il cherche la valeur 'attrib' de tag d'entrée, et .contents retourne le texte encapsulé par l'étiquette ( je suis .contents) - (juste répondre maintenant parce que je devais doubler vérifier ce qui se passait, trouver quelqu'un d'autre peut en bénéficier) –

1

je réellement vous suggérer une façon de gagner du temps pour aller avec cela en supposant que vous savez quel genre de balises ont ces attributs.

Supposons que dire xyz tag a que attritube nommé "staininfo" ..

full_tag = soup.findAll("xyz") 

Et je vous wan't à comprendre que full_tag est une liste

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

Ainsi, vous pouvez obtenir tous les valeurs attrb de staininfo pour tous les tags xyz

3

Si vous souhaitez récupérer plusieurs valeurs d'attributs à partir de la source ci-dessus, vous pouvez utiliser findAll et une liste de compréhension à g et tout ce dont vous avez besoin:

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. 
1

En Python 3.x, utilisez simplement get(attr_name) sur votre objet tag que vous obtenez en utilisant 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) 

contre fichier XML conf//test1.xml qui ressemble à:

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

estampes:

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

vous pouvez également utiliser:

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)