2010-12-13 14 views
8

Tengo HTML que contiene entradas como esta:biblioteca de Python para hacer una extracción de texto similar a jQuery?

<div class="entry"> 
    <h3 class="foo"> 
    <a href="http://www.example.com/blog-entry-slug" 
    rel="bookmark">Blog Entry</a> 
    </h3> 
    ... 
</div> 

y me gustaría extraer el texto "entrada de blog" (y un número de otros atributos, así que estoy en busca de una respuesta genérica) .

En jQuery, lo haría

$('.entry a[rel=bookmark]').text() 

más cerca que he podido conseguir en Python es:

from BeautifulSoup import BeautifulSoup 
import soupselect as soup 

rawsoup = BeautifulSoup(open('fname.html').read()) 

for entry in rawsoup.findAll('div', 'entry'): 
    print soup.select(entry, 'a[rel=bookmark]')[0].string.strip() 

soupselect de http://code.google.com/p/soupselect/.

Soupselect no comprende la sintaxis completa del selector CSS3, como lo hace jQuery. ¿Hay tal bestia en Python?

Respuesta

11

Es posible que desee echar un vistazo a la clase lxmlCSSSelector que intenta implementar selectores CSS como se describe en la especificación w3c. Como nota al margen, manyfolksrecommend lxml para analizar HTML/XML sobre BeautifulSoup ahora, por rendimiento y por otros motivos.

Creo que el CSSSelector de lxml usa XPath para la selección de elementos, pero es posible que desee verificar la documentación por usted mismo. Aquí está su ejemplo con lxml:

>>> from lxml.cssselect import CSSSelector 
>>> from lxml.html import fromstring 
>>> html = '<div class="entry"><h3 class="foo"><a href="http://www.example.com/blog-entry-slug" rel="bookmark">Blog Entry</a></h3></div>' 
>>> h = fromstring(html) 
>>> sel = CSSSelector("a[rel=bookmark]") 
>>> [e.text for e in sel(h)] 
['Blog Entry'] 
+1

Eso no funcionó para mí por alguna razón (fromstring parece querer html * lol * válido), pero uno de los enlaces que me diste me llevó a pyquery. La motivación para pyquery fue "Hey vamos a hacer jquery en python", y de mis pruebas preliminares he podido confiar en mi conocimiento de jQuery en lugar de leer los documentos (!) – thebjorn

+2

Use "de lxml.html import fromstring" para html con formato incorrecto – Saurav

2

Es muy fácil usar argumentos de palabra clave.

>>> from BeautifulSoup import BeautifulSoup 
>>> soup = BeautifulSoup('''<div class="entry"> 
... <h3 class="foo"> 
...  <a href="http://www.example.com/blog-entry-slug" 
...  rel="bookmark">Blog Entry</a> 
... </h3> 
... ... 
... </div> 
... ''') 
>>> soup.find('div', 'entry').find(rel='bookmark').text 
u'Blog Entry' 

Alternativamente,

>>> for entry in soup('div', 'entry'): 
...  for bookmark in entry(rel='bookmark'): 
...   print bookmark.text 
... 
Blog Entry 

También puede utilizar attrs para efectuar un selector de .entry en lugar de div.entry:

>>> for entry in soup(attrs={'class': 'entry'}): 
...  for bookmark in entry(rel='bookmark'): 
...   print bookmark.text 
... 
Blog Entry 

(Nota llamando a la sopa o parte de la sopa es equivalente a .findAll().)

Como una lista de comprensión, eso es [b.text for e in soup('div', 'entry') for b in e(rel='bookmark')] (produce [u'Blog Entry']).

Si quiere selectores de CSS3 reales, no estoy al tanto de nada parecido para BeautifulSoup. Todo (o si no casi, casi todo) se puede hacer con anidamiento simple, condiciones y expresiones regulares (también podría usar entry(rel=re.compile('^bookmark$'))). Si quieres algo así, ¡considéralo tu próximo proyecto! Podría ser útil para aplanar el código y hacerlo más comprensible para la gente de la web.

+0

Eso no se ve muy mal. El problema que tengo con BeautifulSoup es que tengo que volver a aprender la interfaz cada vez que lo uso. Uso jQuery con mucha más frecuencia, por lo que estoy buscando algo similar. – thebjorn

+1

Es realmente bastante simple. Casi todo lo que querrás es 'findAll (tag_name, class_name, attr1 = value)', etc., con los valores siendo 'None' for not set,' True' for set, 'str' for a value o regular expresión de 're.compile'. Entonces solo usa estructuras de iteración normales de Python. Es diferente de los selectores de CSS, pero no es difícil de entender y recordar y ofrece más potencia en algunas situaciones. –

3

Es posible que también desee echarle un vistazo a pyquery. pyquery es una biblioteca similar a jquery para python. Encontrar here

Cuestiones relacionadas