web-dev-qa-db-ja.com

HTMLタイトルタグを解析するためのpythonの正規表現パターン

python=でreモジュールとurllibモジュールの両方を使用することを学び、簡単なWebスクレイパーを作成しようとしています。ここに私が作成したコードがありますウェブサイトのタイトルだけをこする:

_#!/usr/bin/python

import urllib
import re

urls=["http://google.com","https://facebook.com","http://reddit.com"]

i=0

these_regex="<title>(.+?)</title>"
pattern=re.compile(these_regex)

while(i<len(urls)):
        htmlfile=urllib.urlopen(urls[i])
        htmltext=htmlfile.read()
        titles=re.findall(pattern,htmltext)
        print titles
        i+=1
_

これは、GoogleとRedditには正しい出力を提供しますが、Facebookには提供しません。

_['Google']
[]
['reddit: the front page of the internet']
_

これは、Facebookのページでtitleタグが_<title id="pageTitle">_であることを発見したためです。追加の_id=_に対応するために、_these_regex_変数を次のように変更しました:these_regex="<title.+?>(.+?)</title>"。しかし、これは次の出力を与えます:

_[]
['Welcome to Facebook \xe2\x80\x94 Log in, sign up or learn more']
[]
_

titleタグ内で渡される追加のパラメーターを考慮できるように、両方を組み合わせるにはどうすればよいですか?

9
rahuL

正規表現を使用していて、HTMLをそのような表現と照合すると、複雑になりすぎて、速くなりすぎます。

代わりにHTMLパーサーを使用してください。Pythonにはいくつかの選択肢があります。人気のあるサードパーティライブラリである BeautifulSoup を使用することをお勧めします。

BeautifulSoupの例:

from bs4 import BeautifulSoup

response = urllib2.urlopen(url)
soup = BeautifulSoup(response.read(), from_encoding=response.info().getparam('charset'))
title = soup.find('title').text

titleタグ自体には他のタグが含まれていないため、ここでは正規表現を使用できますが、ネストされたタグを解析するとすぐに、になります非常に複雑な問題が発生します。

特定の問題は、オプションでtitleタグ内の追加の文字を照合することで解決できます。

r'<title[^>]*>([^<]+)</title>'

これは、終了>ブラケットではないではない0個以上の文字に一致します。ここで「0以上」を使用すると、追加の属性とプレーンな<title>タグの両方を照合できます。

18
Martijn Pieters

Beautiful Soup またはその他のパーサーを使用してHTMLを解析することをお勧めしますが、badex regexを使用すると、次のコードでうまくいきます。

正規表現コード:

<title.*?>(.+?)</title>

仕組み:

Regular expression visualization

農産物:

['Google']
['Welcome to Facebook - Log In, Sign Up or Learn More']
['reddit: the front page of the internet']
27
K DawG

すべてのhtmlタグを識別したい場合は、これを使用できます

batRegex = re.compile(r'(<[a-z]*>)')
m1=batRegex.search(html)
print batRegex.findall(yourstring)
1
Harsh Gupta