Estrazione di un valore di attributo con beautifulsoup


112

Sto cercando di estrarre il contenuto di un singolo attributo "value" in un tag "input" specifico su una pagina web. Uso il codice seguente:

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)

Ottengo un'eccezione TypeError: gli indici della lista devono essere numeri interi, non str

anche se dalla documentazione di Beautifulsoup capisco che le stringhe non dovrebbero essere un problema qui ... ma non uno specialista e potrei aver capito male.

Ogni suggerimento è molto apprezzato! Grazie in anticipo.

Risposte:


150

.find_all() restituisce l'elenco di tutti gli elementi trovati, quindi:

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

input_tagè una lista (probabilmente contenente un solo elemento). A seconda di cosa vuoi esattamente, dovresti fare:

 output = input_tag[0]['value']

o usa il .find()metodo che restituisce solo un (primo) elemento trovato:

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

Roba fantastica! Grazie. ora ho una domanda sull'analisi dell'output che è un lungo mucchio di caratteri non ASCII ma lo chiederò in una domanda separata.
Barnabe

3
non si dovrebbe accedere al 'valore' come da stackoverflow.com/questions/2616659/… . Cosa fa funzionare il codice sopra in questo caso? Ho pensato che avresti dovuto accedere al valore facendooutput = inputTag[0].contents
Seth

@Seth - no, perché sta cercando l'attrib 'value' del tag di input, e .contents restituisce il testo incapsulato dal tag (<span> Sono .contents </span>) - (solo rispondendo ora perché avevo per ricontrollare cosa stava succedendo; immagina che qualcun altro possa trarne vantaggio)
Dolan Antenucci

1
Bella risposta. tuttavia, userei inputTag[0].get('value') invece di inputTag[0]['value']evitare nessun puntatore nel caso in cui il tag come attributo senza valore
amphibient

per quanto riguarda i collegamenti che non sono direttamente collegati alla home page del sito Web in visita, come ottenere tutti i collegamenti collegati alla pagina Web direttamente o indirettamente.
Pista

26

In Python 3.x, usa semplicemente get(attr_name)sul tuo oggetto tag che usi 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)

contro il file XML conf//test1.xmlche assomiglia a:

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

stampe:

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

Ti dispiacerebbe se modifico questo per seguire PEP 8 e utilizzare i metodi di formattazione delle stringhe più moderni?
AMC

Va bene,
fallo

6

Se desideri recuperare più valori di attributi dalla fonte sopra, puoi utilizzare findAlle una comprensione dell'elenco per ottenere tutto ciò di cui hai bisogno:

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

In realtà ti suggerirei un modo per risparmiare tempo con questo assumendo che tu sappia che tipo di tag hanno quegli attributi.

supponiamo che un tag xyz abbia quell'attritube chiamato "staininfo" ..

full_tag = soup.findAll("xyz")

E non voglio che tu capisca che full_tag è un elenco

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

Quindi puoi ottenere tutti i valori attrb di staininfo per tutti i tag xyz


3

puoi anche usare questo:

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)

In che cosa differisce dalle risposte molto più vecchie che erano già qui?
AMC

0

Lo sto usando con Beautifulsoup 4.8.1 per ottenere il valore di tutti gli attributi di classe di determinati elementi:

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

È importante notare che la chiave dell'attributo recupera un elenco anche quando l'attributo ha un solo valore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.