2012-04-24 7 views
3

lxmlのiterparseをHTMLに使用すると問題が発生しています。私は<title>のテキストを取得しようとしているが、このシンプルな機能は、完全なWebページ上では動作しません:グラブ<title>タグとlxmlのiterparse

def get_title(str): 
    titleIter = etree.iterparse(StringIO(str), tag="title") 
    try: 
     for event, element in titleIter: 
      return element.text 
     # print "Script goes here when it doesn't work" 
    except etree.XMLSyntaxError: 
     return None 

この機能は、 『<title>test</title>』のような簡単な入力で正常に動作しますが、私はそれを完全なを与えるときページではタイトルを抽出できません。

UPDATE:

また
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html dir="ltr" lang="it" xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<link rel="icon" href="http://www.tricommerce.it/tricommerce.ico" /> 
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> 
<title>Tricommerce - Informazioni sulla privacy</title> 
<meta name="description" content="Info sulla privacy" /> 
<meta name="keywords" content="Accessori notebook Alimentatori Case Cavi e replicatori Controllo ventole Lettori e masterizzatori Modding Pannelli &amp; display Dissipatori Tastiere e mouse Ventole Griglie e filtri Hardware Accessori vari Box esterni Casse e cuffie Sistemi a liquido Paste termiche vendita modding thermaltake vantec vantecusa sunmbeam sunbeamtech overclock thermalright xmod aerocool arctic cooling arctic silver zalman colorsit colors-it sharkoon mitron acmecom Info sulla privacy" /> 
<meta name="robots" content="index, follow" /> 
<link rel="stylesheet" href="http://www.tricommerce.it/css/tricommerce.css" /> 
<link rel="stylesheet" href="css/static.css" /> 
<script type="text/javascript" src="http://www.tricommerce.it/javascript/vertical_scroll.js"></script> 

<script type="text/javascript"> 
//<![CDATA[ 
function MM_preloadImages() { //v3.0 
var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array(); 
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++) 
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}} 
} 
//]]> 
</script> 

<link rel="stylesheet" type="text/css" href="http://www.tricommerce.it/css/chromestyle.css" /> 

<script type="text/javascript" src="http://www.tricommerce.it/javascript/chrome.js"> 
/*********************************************** 
* AnyLink CSS Menu script- ? Dynamic Drive DHTML code library (www.dynamicdrive.com) 
* This notice MUST stay intact for legal use 
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code 
***********************************************/ 
</script> 

</head> 
</html> 

、私はちょうど全体のDOMにロードしたくないので、それはだiterparse--を使用している理由について簡単なメモ:ここでは私が働いているHTMLです文書の中で早く1つのタグを取得する。

答えて

2

データの一部を投稿して、実際には を解析したい場合があります。その情報がない場合、ここには推測があります。 <html>要素でデフォルトのXML名前空間が定義されている場合は、要素を検索するときに を使用する必要があります。たとえば、この単純な 文書を見て:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml11.xsd" 
    xml:lang="en"> 
    <head>    
    <title>Document Title</title> 
    </head> 
    <body> 
    </body> 
</html> 

は、この入力を考えると、以下の結果が返されません。私たちは指定 なし<title>要素を探しているので

>>> doc = etree.parse(open('foo.html')) 
>>> doc.xpath('//title') 
[] 

これは失敗しました名前空間が存在しないと、パーサーは と一致しません(foo:titlebar:titleと異なるため、foo:bar:がXML 0として定義されているとします)名前空間)。

あなたは明示的に このようElementTreeのインターフェイスで名前空間を使用することができます。

>>> doc.xpath('//html:title', 
... namespaces={'html': 'http://www.w3.org/1999/xhtml'}) 
[<Element {http://www.w3.org/1999/xhtml}title at 0x1087910>] 

そして、我々の試合があります。

あなたもiterparseのtag引数に名前空間接頭辞を渡すことができます。これは、あなたの問題を解決するため、いくつかのサンプル入力を投稿し、我々はそこからうまくいくしない場合

>>> titleIter = etree.iterparse(StringIO(str), 
... tag='{http://www.w3.org/1999/xhtml}title') 
>>> list(titleIter) 
[(u'end', <Element {http://www.w3.org/1999/xhtml}title at 0x7fddb7c4b8c0>)] 

+0

iterparseを使ってこれを行う方法はありますか?解析して全文書を読み込もうとしません。 PSさんがサンプルのHTMLを追加しました – babonk

+0

ええと。名前空間プレフィックスを持つtitleタグを指定するだけです。答えを例で更新しました。 – larsks

+0

Gotcha。私がたくさんのページをクロールしている場合は、毎回適切な名前空間の接頭辞を指定する必要がありますか、それとも 'tag = '{http://www.w3.org/1999/xhtml} title' '? – babonk