2009-03-22 8 views
1

私はPythonでアプリケーションを構築しています。すべてのリンクのURLを1つのWebページで取得する必要があります。 urllibを使ってhtmlファイルをWebからダウンロードし、readlines()で文字列のリストに変換する関数をすでに持っています。<a>すべてのhref属性の値をPythonのhtmlファイルのタグに取得する

現在、私はすべてのライン内のリンクを検索するために正規表現を使用しています(私はそれで非常に良好ではないよ)このコードを持っている:それだけのために「None」を印刷しないよう

for line in lines: 
    result = re.match ('/href="(.*)"/iU', line) 
    print result 

これは、動作していませんファイル内のすべての行が表示されますが、少なくとも私が開いているファイルには3つのリンクがあることを確信しています。

誰かが私にこのことに関するヒントを与えることができますか?事前

+2

* Sigh *、正規表現でHTML/XMLを解析しようとしているもう1つの質問。参考までに、これはお勧めしません、eduffyが提案したようにパーサを使用してください。 –

+0

なぜ正規表現を使用する必要がありますか?なぜhtmllibはオプションではないのですか? –

+0

ほとんどの場合、私はいくつかの正規表現を学ぼうとしていたので、 – rogeriopvl

答えて

1

まあ、単に完全性のため、私は最良の答えであることが判明何ここに追加されます、と私はマーク・ピルグリムから、本飛び込むのPythonでそれを発見した。

ここでは、すべてのURLのからを一覧表示するためのコードを次のウェブページ:

from sgmllib import SGMLParser 

class URLLister(SGMLParser): 
    def reset(self):        
     SGMLParser.reset(self) 
     self.urls = [] 

    def start_a(self, attrs):      
     href = [v for k, v in attrs if k=='href'] 
     if href: 
      self.urls.extend(href) 

import urllib, urllister 
usock = urllib.urlopen("http://diveintopython.net/") 
parser = urllister.URLLister() 
parser.feed(usock.read())   
usock.close()  
parser.close()      
for url in parser.urls: print url 

すべての返信ありがとうございます。

4

おかげで、Pythonで標準装備されているHTMLパーサがあります。チェックアウトhtmllib

+0

htmllibはpython 3.0で廃止されました。将来の互換性のために、私はそれを避けたいと思います。 – rogeriopvl

11

Beautiful Soupはほとんど自明これを行うことができます:

from BeautifulSoup import BeautifulSoup as soup 

html = soup('<body><a href="123">qwe</a><a href="456">asd</a></body>') 
print [tag.attrMap['href'] for tag in html.findAll('a', {'href': True})] 
+0

それは完全にそれを行います。ありがとう – rogeriopvl

1

を単一のラインであり、多分複数の一致として、ラインにHTMLコンテンツを分割しないでください。また、URLの周りに常に引用符があると仮定しないでください。

このような何か:

links = re.finditer(' href="?([^\s^"]+)', content) 

for link in links: 
    print link 
8

BeautifulSoupの別の方法は、lxmlの(http://lxml.de/)です。他の人があなたに言っていない何

import lxml.html 
links = lxml.html.parse("http://stackoverflow.com/").xpath("//a/@href") 
for link in links: 
    print link 
3

はこのために正規表現を使用すると、信頼性の高いソリューションではないということです。
< A>タグがコメントアウトされているか、または文字列「href =」を含むテキストがページにある場合、または<テキストエリアがある場合は>の正規表現を使用すると、その中にhtmlコードを持つ要素、その他多くの要素が含まれています。さらに、href属性は、アンカータグ以外のタグにも存在する可能性があります。

これはDOMツリーのクエリ言語であるXPathです。つまり、指定した条件を満たす任意のノードセット(HTML属性はDOMのノード)を取得できます。
XPathは今やよく標準化された言語です(W3C)、すべての主要言語で十分サポートされています。 XPathを使用して正規表現を使用しないことを強くお勧めします。
adwの回答は、特定のケースでXPathを使用した例を示しています。

3

前述のとおり、regexにはHTMLを解析する機能がありません。 HTMLの解析に正規表現を使用しないでください。行かないでください。 £200を徴収しないでください。

HTMLパーサーを使用します。

しかし、完全を期すために、主要な問題は次のとおりです。

あなたはPythonで正規表現を飾るための「/.../flags」構文を使用していない
re.match ('/href="(.*)"/iU', line) 

。代わりにフラグを別の引数に入れてください:

re.match('href="(.*)"', line, re.I|re.U) 

もう1つの問題は、欲張りな「*」パターンです。一行に2つの輪郭がある場合は、最初の試合の開始と2回目の試合の終了の間に、すべてのコンテンツを喜んで吸います。

しかし、HTMLを解析するためにregexesを使用しないでください。本当に、あなたは貪欲でない '。*?'またはより簡単に '[^ "] *'を使用して最初の終了引用符までマッチさせることができます。

関連する問題