2009-11-09 5 views
2

BeautifulSoup newbe ... Besoin d'aideBeautifulSoup omet le corps de la page

Voici l'exemple de code ...

from mechanize import Browser 
from BeautifulSoup import BeautifulSoup 

mec = Browser() 
#url1 = "http://www.wines.com/catalog/index.php?cPath=21" 
url2 = "http://www.wines.com/catalog/product_info.php?products_id=4866" 
page = mec.open(url2) 
html = page.read() 
soup = BeautifulSoup(html) 

print soup.prettify() 

Quand j'utilise url1 je reçois une belle décharge de la page. Quand j'utilise url2 (celui dont j'ai besoin). Je reçois une sortie sans le corps.

<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html dir="LTR" lang="en"> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <title> 
    2005 Jordan Cabernet Sauvignon Sonoma 2005 
    </title> 
</head> 
</html> 

Des idées?

+0

Je vois que c'est tronquer le tout après la tête, mais je ne vois pas pourquoi - il n'y a littéralement pas de balise 'body' dans l'objet' soup'. –

Répondre

2

Oui. Le HTML est mauvais.

Étape 1a, print soup.prettify() et de voir où il arrête indentation correctement.

Étape 1b (si 1a ne fonctionne pas). Imprimez simplement le brut à travers n'importe quel HTML. J'utilise BBEdit pour des choses qui confondent Beautiful Soup.

Regardez de près le code HTML. Il y aura une sorte d'erreur horrible. Les caractères " mal placés sont communs. En outre, l'image de fond CSS lorsqu'elle est donnée en tant que style a de mauvaises citations.

<tag style="background-image:url("something")"> 

Notez les citations "incorrectes". Vous aurez besoin d'écrire une regex pour les trouver et les corriger. Étape 2. Écrivez une expression régulière «massage» et utilisez-la pour résoudre ce problème. Lisez la section http://www.crummy.com/software/BeautifulSoup/documentation.html#Sanitizing%20Bad%20Data%20with%20Regexps pour savoir comment créer un massage de balisage.

Voici ce que j'utilise souvent

# Fix background-image:url("some URI") 
# to replace the quotes with &quote; 
background_image = re.compile(r'background-image:url\("([^"]+)"\)') 
def fix_background_image(match): 
    return 'background-image:url(&quote;%s&quote;)' % (match.group(1)) 
# Fix <img src="some URI name="someString""> -- note the out-of-place quotes 
bad_img = re.compile(r'src="([^ ]+) name="([^"]+)""') 
def fix_bad_img(match): 
    return 'src="%s" name="%s"' % (match.group(1), match.group(2)) 
fix_style_quotes = [ 
    (background_image, fix_background_image), 
    (bad_img, fix_bad_img), 
] 
+0

Arrête d'avoir du contenu juste après la tête ...! -) –

0

Fonctionnant sur le code HTML en question une validator montre 116 erreurs - trop nombreux pour traquer lequel BeautifulSoup se révèle incapable de récupérer, je suppose :-(Semble survivre à l'épreuve de l'analyse de cette page d'horreur, et laisse beaucoup de choses dans (le pretudy a à peu près toute la page d'origine, il me semble, lorsque vous utilisez l'analyseur de html5lib pour produire un objet BeautifulSoup Difficile à dire si l'arbre d'analyse qui en résultera fera ce dont vous avez besoin, puisque nous ne savoir ce que est ;-).

Remarque: J'ai installé html5lib directement à partir des sources hg clone (juste python setup.py install du répertoire html5lib/python), puisque la dernière version officielle est un peu longue dans la dent.

+0

html5lib semble être le chemin que le créateur de BeautifulSoup aimerait que nous poursuivions. Il dit "... en ce moment c'est plus lent que SGMLParser ou HTMLParser", mais le recommande quand même comme une alternative puisqu'il "n'aime plus travailler sur Beautiful Soup, mais trop de gens en dépendent pour moi laisser mourir le projet juste parce que cela dépend du code qui a été enlevé de la bibliothèque standard de Python ": http://www.crummy.com/software/BeautifulSoup/3.1-problems.html –

1

Le HTML est en effet horrible :-) BeautifulSoup 3.0.7 est beaucoup mieux à la manipulation de HTML malformé que la version actuelle. Le site web du projet avertit: "Actuellement, la série 3.0.x est meilleure pour analyser le mauvais HTML que la série 3.1." ... et il y a une bonne page devoted to the reason why, qui se résume au fait que SGMLParser a été supprimé dans Python 3, et BS 3.1.x a été écrit pour être convertible en Py3k.

La bonne nouvelle est que vous pouvez toujours télécharger 3.0.7a (la dernière version), qui sur ma machine parse l'URL que vous avez mentionné parfaitement: http://www.crummy.com/software/BeautifulSoup/download/3.x/

2

Il semble se disjoncté par ce mauvais tag:

<META NAME="description" CONTENT="$49 at Wines.com "Deep red. Red- and blackcurrant, cherry and menthol on the nose, with subtle vanilla, cola and tobacco notes adding complexity. Tightly wound red berry and bitter cherry flavors are framed by dusty..."> 

De toute évidence ici, ils ont échoué à échapper à une citation à l'intérieur de la valeur de l'attribut (uh-oh ... site peut être vulnérable aux scripts inter-sites?), et cela fait penser à l'analyseur que le reste du contenu de la page est dans les valeurs des attributs. (Il faudrait un autre " ou un > dans l'une des valeurs d'attributs réels pour lui faire réaliser l'erreur, je pense.)

Malheureusement, c'est une erreur assez difficile à réparer après. Vous pourriez essayer un analyseur légèrement différent, peut-être? par exemple. essayez Soup 3.0.x au lieu de 3.1.x si vous utilisez cette version, ou vice-versa. Ou essayez html5lib.

+0

@bobince, bon repérage! J'ai renoncé à ce désordre de potage trop tôt après avoir réussi à lancer html5lib dessus, il semble - n'a pas repéré l'erreur très tôt de la double-citation supplémentaire. +1 pour les yeux de faucon! -) –

+0

C'est pourquoi Beautiful Soup a une fonction "Markup Massage". Vous pouvez fournir un RE pour repérer ce problème spécifique et réparer les devis endommagés. –

+0

Pour être honnête, je ne sais pas comment les parseurs des navigateurs parviennent à y faire face! – bobince

Questions connexes