2010-03-23 6 views
7

Ho appena iniziato ad armeggiare con scrapy in collaborazione con BeautifulSoup e mi chiedo se mi manca qualcosa di molto ovvio, ma io non riesco a capire come ottenere il doctype di un restituita documento html dall'oggetto zuppa risultante.Ottenere DOCTYPE documento con BeautifulSoup

Dato il seguente codice HTML:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html lang="en"> 
<head> 
<meta charset=utf-8 /> 
<meta name="viewport" content="width=620" /> 
<title>HTML5 Demos and Examples</title> 
<link rel="stylesheet" href="/css/html5demos.css" type="text/css" /> 
<script src="js/h5utils.js"></script> 
</head> 
<body> 
<p id="firstpara" align="center">This is paragraph <b>one</b> 
<p id="secondpara" align="blah">This is paragraph <b>two</b>. 
</html> 

Qualcuno può dirmi se c'è un modo di estrarre il doctype dichiarato da esso usando BeautifulSoup?

risposta

4

Beautiful Soup 4 ha una classe per dichiarazioni DOCTYPE, in modo da poter utilizzare che per estrarre tutte le dichiarazioni a livello superiore (se sei senza dubbio in attesa di uno o nessuno!)

def doctype(soup): 
    items = [item for item in soup.contents if isinstance(item, bs4.Doctype)] 
    return items[0] if items else None 
0

Si può solo prendere la prima voce nei contenuti zuppa:

>>> soup.contents[0] 
u'DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"' 
+4

attenzione, questa sintassi si interromperà se il doctype non è il primo elemento. Ad esempio, quando c'è una dichiarazione xml nella parte superiore del documento. – karlcow

+2

Questo potrebbe restituire qualsiasi cosa, poiché doctype potrebbe mancare e lo è spesso. – zvone

3

Si può passare attraverso gli elementi di livello superiore e di controllare ogni per vedere se si tratta di una dichiarazione. Poi si può controllarla per scoprire che tipo di dichiarazione è:

for child in soup.contents: 
    if isinstance(child, BS.Declaration): 
     declaration_type = child.string.split()[0] 
     if declaration_type.upper() == 'DOCTYPE': 
      declaration = child