2009-08-18 8 views
0

Eh bien, je dois trouver un moyen d'extraire tous les liens entre <div id="links"> et </table> tags. Et s'il y a plus d'un lien, il faut ajouter le caractère '\ n' entre les URL: "$ URL1 \ n $ URL2".Extrait tous les liens entre les balises HTML spécifié à partir d'un fichier html avec sed

<div id="links"> 
<table> 
<td><a href="URL">url</a></td> 
<td><a href="URL">url</a></td> 
</table> 
<table> 
.. 
</table> 
</div> 

Ceux <div> entre tag et la première balise </table>. Existe-t-il d'autres moyens que Sed?

Merci.

+0

Il serait utile si vous pouviez être plus précis. À quoi ressemble votre entrée d'échantillon? –

Répondre

2

Comme il est affiché chaque jour sur le SO: Vous ne pouvez pas traiter HTML avec des expressions régulières. Can you provide some examples of why it is hard to parse XML and HTML with a regex?

qui va double pour un outil aussi limité que sed, avec ses expressions régulières de base.

Si le type d'entrée que vous avez est très limité de telle sorte que chaque lien est dans le format exact même, il pourrait être possible, dans ce cas, vous auriez à poster un exemple de ce format. Mais pour les pages HTML générales, cela ne peut pas être fait.

ETA donné votre exemple: au niveau le plus simple, puisque chaque URL est déjà sur sa propre ligne, vous pouvez sélectionner ceux qui ont l'air à droite et jeter les bits que vous ne voulez pas:

#!/bin/sed -f 
s/^<td><a href="\(.*\)">.*<\/a><\/td>$/\1/p 
d 

Notez toutefois que cela laisserait toujours les URL sous leur forme codée en HTML. Si le script qui a produit ce fichier code correctement ses URL, vous devrez alors remplacer toutes les occurrences de l'entité lt/gt/quot/amp par leur caractère simple '<> "&". Un seul de ceux que vous êtes susceptible de rencontrer est &/amp, ce qui est très courant dans les URLs

Mais! Ce n'est pas tout l'encodage HTML qui pourrait avoir eu lieu. , comme eacute (qui serait valide maintenant nous avons des IRIs), ou des références de caractères numériques (en décimal et hexadécimal) Il y a deux millions de formes potentielles d'encodage pour les caractères incluant Unicode ... en remplaçant chacun individuellement dans sed un exercice massif dans l'ennui.

Alors que

vous pourriez sortir avec elle si vous savez que le script générateur ne sera jamais sortie l'un de ceux, un analyseur HTML est toujours préférable vraiment. (Ou, si vous savez qu'il est bien formé XHTML, vous pouvez utiliser un analyseur XML plus simple, qui a tendance à être intégré dans les bibliothèques standard des langues modernes.)

+0

sed est complète, donc c'est possible. Probablement le mauvais outil pour le travail, mais possible. – Triptych

+0

Un de mes amis m'a dit que c'est possible grâce à perl mais je n'ai pas les privilèges pour l'installer ... –

+0

Alors, comment je suis censé faire ça? Je peux dire que chaque lien est exactement dans le même format car ils sont générés automatiquement. –

0

Si vous avez accès à Python, je recommande BeautifulSoup. Une belle bibliothèque python pour manipuler le HTML. Le code suivant recueille les liens d'une ressource donnée, qui est un nom complet à une page Web comme http://www.foo.com, et les stocke dans le fichier. J'espère que cela t'aides.

import sys, os 
from urllib import urlopen 
from BeautifulSoup import BeautifulSoup 

fileLinksName = "links.dat" 

if __name__ == "__main__": 
    try: 
     # get all links so far 
     fileLinks = open(fileLinksName) 

     links = fileLinks.read().split('\n') 

     fileLinks.close() 

     htmlFileSoup = BeautifulSoup(urlopen(sys.argv[1]).read()) 

     anchorList = htmlFileSoup.findAll('a') 

     for htmlAnchor in anchorList: 
      print htmlAnchor 
      if 'href' in htmlAnchor: 
       links.append(htmlAnchor) 

     for link in links: 
      print link 
    except: 
     print sys.exc_info() 
     exit() 
0

Cela peut être possible si au lieu d'essayer de regarder les balises, vous recherchez simplement les URL.

Si ce sont les seules URL de la page que vous pouvez écrire un modèle pour rechercher des URL entre guillemets, quelque chose comme:

"[a-z]+://[^"]+" 
0

Avez-vous accès à AWK?Une combinaison de sed et awk pourrait faire ce que vous voulez, à condition que:

  • Le html est relativement simple
  • Le code HTML ne change pas tout d'un coup (je veux dire dans la forme, pas dans le contenu)
  • Le html n'est pas excessivement alambiqué.

Il est faux que vous ne puissiez pas traiter du HTML avec des expressions régulières. Il est vrai que dans le cas général, vous ne pouvez pas traiter HTML (ou XML) avec des regex, car ils permettent une imbrication arbitraire et les regex ne font pas bien la récursivité - ou pas du tout -. Mais si votre HTML est relativement "plat", vous pouvez certainement faire beaucoup avec les expressions rationnelles.

Je ne peux pas vous dire exactement ce qu'il faut faire, parce que je l'ai oublié ce que peu sed et awk, j'ai appris au collège, mais ce qui me frappe comme quelque chose faisable:

  • Trouver la chaîne <div id="links">
  • Maintenant trouver la chaîne <table>
  • Maintenant trouver la chaîne <td>...</td> et d'obtenir un lien (c'est la partie regex).
  • Append à var $links
  • Jusqu'à ce que vous trouverez la chaîne </table>
  • Enfin, imprimer $links séparant chaque lien avec \n.

Encore une fois, ceci est juste pseudocode pour le cas simple. Mais ça pourrait juste marcher. Je mentionne AWK parce que, même si vous n'avez pas accès à Perl, sed et AWK ont tendance à être installés tous les deux. Enfin, pour une solution pure sed, vous pouvez également jeter un oeil à this sed recipe et l'adapter à vos besoins.

Questions connexes