2010-01-07 3 views
2

J'ai un petit script qui utilise urllib2 pour obtenir le contenu d'un site, trouver toutes les balises de lien, ajoute un petit morceau de HTML dans le haut et le bas, puis j'essaie de l'alléger . Il continue à renvoyer TypeError: séquence élément 1: chaîne attendue, balise trouvée. J'ai regardé autour de moi, je ne peux pas vraiment trouver le problème. Comme toujours, toute aide, très appréciée.Je ne peux pas prétendre html gratté dans BeautifulSoup

import urllib2 
from BeautifulSoup import BeautifulSoup 
import re 

reddit = 'http://www.reddit.com' 
pre = '<html><head><title>Page title</title></head>' 
post = '</html>' 
site = urllib2.urlopen(reddit) 
html=site.read() 
soup = BeautifulSoup(html) 
tags = soup.findAll('a') 
tags.insert(0,pre) 
tags.append(post) 
soup1 = BeautifulSoup(''.join(tags)) 
print soup1.prettify() 

Ceci est le retraçage:

Traceback (most recent call last): File "C:\Python26\bea.py", line 21, in <module> 
     soup1 = BeautifulSoup(''.join(tags)) 
TypeError: sequence item 1: expected string, Tag found 
+0

Eh oui, c'est le retraçage: retraçage (appel le plus récent en dernier): Fichier "C: \ Python26 \ bea.py", ligne 21, dans soup1 = BeautifulSoup (''. Join (balises)) TypeError: élément de séquence 1: chaîne attendue, balise trouvée – Kevin

Répondre

2

Cela fonctionne pour moi:

soup1 = BeautifulSoup(''.join(str(t) for t in tags)) 

Cette solution pyparsing donne une sortie décente aussi:

from pyparsing import makeHTMLTags, originalTextFor, SkipTo, Combine 

# makeHTMLTags defines HTML tag patterns for given tag string 
aTag,aEnd = makeHTMLTags("A") 

# makeHTMLTags by default returns a structure containing 
# the tag's attributes - we just want the original input text 
aTag = originalTextFor(aTag) 
aEnd = originalTextFor(aEnd) 

# define an expression for a full link, and use a parse action to 
# combine the returned tokens into a single string 
aLink = aTag + SkipTo(aEnd) + aEnd 
aLink.setParseAction(lambda tokens : ''.join(tokens)) 

# extract links from the input html 
links = aLink.searchString(html) 

# build list of strings for output 
out = [] 
out.append(pre) 
out.extend([' '+lnk[0] for lnk in links]) 
out.append(post) 

print '\n'.join(out) 

impressions:

<html><head><title>Page title</title></head> 
    <a href="http://www.reddit.com/r/pics/" >pics</a> 
    <a href="http://www.reddit.com/r/reddit.com/" >reddit.com</a> 
    <a href="http://www.reddit.com/r/politics/" >politics</a> 
    <a href="http://www.reddit.com/r/funny/" >funny</a> 
    <a href="http://www.reddit.com/r/AskReddit/" >AskReddit</a> 
    <a href="http://www.reddit.com/r/WTF/" >WTF</a> 
    . 
    . 
    . 
    <a href="http://reddit.com/help/privacypolicy" >Privacy Policy</a> 
    <a href="#" onclick="return hidecover(this)">close this window</a> 
    <a href="http://www.reddit.com/feedback" >volunteer to translate</a> 
    <a href="#" onclick="return hidecover(this)">close this window</a> 
</html> 
0
soup1 = BeautifulSoup(''.join(unicode(tag) for tag in tags)) 
+0

J'ai ajouté votre ligne, et il donne maintenant une erreur de type je n BeautifulSoup.py TypeError: chaîne attendue ou buffer – Kevin

0

Un peu d'une erreur de syntaxe sur la réponse Jonathans, voici le correct:

soup1 = BeautifulSoup(''.join([unicode(tag) for tag in tags])) 
+2

plutôt que d'en faire une réponse, peut-être qu'un commentaire sous la réponse de Jonathan serait plus approprié. –

Questions connexes