2010-11-06 6 views
15

J'essaye d'analyser du HTML en Python. Il y avait quelques méthodes qui fonctionnaient réellement avant ... mais de nos jours je ne peux rien utiliser sans solutions de contournement.Python html analyse qui fonctionne réellement

  • beautifulsoup a des problèmes après SGMLParser est parti
  • html5lib ne peut pas analyser la moitié de ce qui est « là-bas »
  • lxml essaie d'être « trop correct » pour html typique (attributs et les balises ne peuvent pas contenir des espaces de noms inconnus, ou une exception est levée, ce qui signifie que presque aucune page avec Facebook connect ne peut être analysée)

Quelles sont les autres options disponibles ces jours-ci? (si elles supportent xpath, ce serait génial)

+0

Vous devez nous donner des exemples de pages sur lesquelles vos approches actuelles échouent. Sinon, comment saurons-nous si nos solutions proposées résoudront vos problèmes? Aussi, n'oubliez pas de signaler les bugs html5lib à http://code.google.com/p/html5lib/issues/entry –

Répondre

20

Assurez-vous que vous utilisez le module html lorsque vous analysez HTML avec lxml:

>>> from lxml import html 
>>> doc = """<html> 
... <head> 
... <title> Meh 
... </head> 
... <body> 
... Look at this interesting use of <p> 
... rather than using <br /> tags as line breaks <p> 
... </body>""" 
>>> html.document_fromstring(doc) 
<Element html at ...> 

Toutes les erreurs & exceptions se dissiperont, vous serez à gauche avec un analyseur incroyablement rapide qui traite souvent avec HTML soupe mieux que BeautifulSoup.

+0

C'est intéressant. J'ai toujours utilisé lxml via un treebuilder. J'étais assez sûr que HTMLParser utilisé de cette façon le mode html forcé. Apparemment non. lxml.html analyse les choses comme ' 'correctement. (où lxml a jeté une exception) – viraptor

+0

Suis content d'entendre que ça marche bien pour toi! Merci d'avoir accepté la réponse. –

+1

s/pense/choses –

1

Je pense que le problème est que la plupart du HTML est mal formé. XHTML a essayé de résoudre ce problème, mais il n'a jamais vraiment pris le dessus - d'autant plus que la plupart des navigateurs font des «solutions de contournement intelligentes» pour le code mal formé.

Il y a quelques années, j'ai essayé d'analyser HTML pour une application primitive de type araignée, et j'ai trouvé les problèmes trop difficiles. Je pense que l'écriture de votre propre pourrait être sur les cartes, bien que nous ne pouvons pas être les seules personnes avec ce problème!

10

J'ai utilisé le pyparage pour un certain nombre de projets de grattage de pages HTML. C'est une sorte d'intermédiaire entre BeautifulSoup et les parseurs HTML complets à une extrémité, et l'approche trop basse des expressions régulières (de cette façon, c'est de la folie). Avec pyparsing, vous pouvez souvent obtenir de bons résultats de grattage HTML en identifiant le sous-ensemble spécifique de la page ou des données que vous essayez d'extraire. Cette approche évite les problèmes d'essayer d'analyser tout sur la page, car certains HTML problématiques en dehors de votre région d'intérêt pourraient jeter un analyseur HTML complet.

Bien que cela ressemble à une approche regex glorifiée, pyparsing propose des builtins pour travailler avec du texte HTML ou XML. Pyparsing évite la plupart des pièges qui frustrent les solutions regex:

  • accepte les espaces sans jeter des ordures « \ s * » dans toute votre expression
  • gère les attributs inattendus dans les balises
  • poignées attributs dans l'ordre
  • poignées majuscules/minuscules dans les balises
  • poignées avec les noms d'attribut namespaces
  • poignées attribuent des valeurs entre guillemets, guillemets simples ou pas citations
  • poignées balises vides (celles de la forme <blah />)
  • retours analysables données avec d'accès attribut objet attributs de la balise

Voici un exemple simple du wiki pyparsing qui obtient <a href=xxx> balises d'un page Web:

from pyparsing import makeHTMLTags, SkipTo 

# read HTML from a web page 
page = urllib.urlopen("http://www.yahoo.com") 
htmlText = page.read() 
page.close() 

# define pyparsing expression to search for within HTML  
anchorStart,anchorEnd = makeHTMLTags("a") 
anchor = anchorStart + SkipTo(anchorEnd).setResultsName("body") + anchorEnd 

for tokens,start,end in anchor.scanString(htmlText): 
    print tokens.body,'->',tokens.href 

Cela tire les balises <a>, même s'il y a d'autres parties de la page contenant HTML problématique.Il existe d'autres exemples HTML au wiki pyparsing:

pyparsing est pas une solution à toute épreuve totale à ce problème, mais en exposant les processus d'analyse, vous pouvez mieux contrôler les parties du HTML qui vous intéressent, les traiter et ignorer du repos.

4

Si vous êtes un contenu de grattage, un excellent moyen de contourner les détails irritants est le package sitescraper. Il utilise l'apprentissage automatique pour déterminer le contenu à récupérer pour vous.

la page d'accueil:

>>> from sitescraper import sitescraper 
>>> ss = sitescraper() 
>>> url = 'http://www.amazon.com/s/ref=nb_ss_gw?url=search-alias%3Daps&field-keywords=python&x=0&y=0' 
>>> data = ["Amazon.com: python", 
      ["Learning Python, 3rd Edition", 
      "Programming in Python 3: A Complete Introduction to the Python Language (Developer's Library)", 
      "Python in a Nutshell, Second Edition (In a Nutshell (O'Reilly))"]] 
>>> ss.add(url, data) 
>>> # we can add multiple example cases, but this is a simple example so 1 will do (I generally use 3) 
>>> # ss.add(url2, data2) 
>>> ss.scrape('http://www.amazon.com/s/ref=nb_ss_gw?url=search-alias%3Daps&field- keywords=linux&x=0&y=0') 
["Amazon.com: linux", ["A Practical Guide to Linux(R) Commands, Editors, and Shell Programming", 
"Linux Pocket Guide", 
"Linux in a Nutshell (In a Nutshell (O'Reilly))", 
'Practical Guide to Ubuntu Linux (Versions 8.10 and 8.04), A (2nd Edition)', 
'Linux Bible, 2008 Edition: Boot up to Ubuntu, Fedora, KNOPPIX, Debian, openSUSE, and 11 Other Distributions']] 
5

html5lib ne peut pas analyser la moitié de ce qui est "là-bas"

Cela semble très peu plausible. html5lib utilise exactement le même algorithme qui est également implémenté dans les versions récentes de Firefox, Safari et Chrome. Si cet algorithme a cassé la moitié du web, je pense que nous aurions entendu. Si vous avez des problèmes particuliers, faites des bogues.

+0

Ok - peut-être pas la moitié, mais il a cassé sur certains tags de script (ne me souviens pas du site), manque un gros morceau de youtube (parfois) et d'autres sites avec lesquels j'ai essayé de l'utiliser. Je vais rapporter des choses que je peux reproduire. – viraptor

+1

Les tags de script sont vraiment un gâchis horrible, mais leur manipulation a changé assez récemment. J'espère que vous trouverez que ça fonctionne mieux maintenant. – Ms2ger