2012-01-24 52 views
1

這裏是我的html的開始:如何使用Nokogiri訪問此節點?

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
<meta name="Generator" content="Microsoft Word 12 (filtered medium)"> 
<!--[if !mso]><style>v\\:* {behavior:url(#default#VML);}\no\\:* {behavior:url(#default#VML);}\nw\\:* {behavior:url(#default#VML);}\n.shape {behavior:url(#default#VML);}\n</style><![endif]--><style><!--\n/* Font Definitions */\[email protected]\n\t{font-family:"Cambria Math";\n\tpanose-1:2 4 5 3 5 4 6 3 2 4;}\[email protected]\n\t{font-family:Calibri;\n\tpanose-1:2 15 5 2 2 2 4 3 2 4;}\[email protected]\n\t{font-family:Tahoma;\n\tpanose-1:2 11 6 4 3 5 4 4 2 4;}\n/* Style Definitions */\np.MsoNormal, li.MsoNormal, div.MsoNormal\n\t{margin:0in;\n\tmargin-bottom:.0001pt;\n\tfont-size:12.0pt;\n\tfont-family:"Times New Roman","serif";}\na:link, span.MsoHyperlink\n\t{mso-style-priority:99;\n\tcolor:blue;\n\ttext-decoration:underline;}\na:visited, span.MsoHyperlinkFollowed\n\t{mso-style-priority:99;\n\tcolor:purple;\n\ttext-decoration:underline;}\np\n\t{mso-style-priority:99;\n\tmso-margin-top-alt:auto;\n\tmargin-right:0in;\n\tmso-margin-bottom-alt:auto;\n\tmargin-left:0in;\n\tfont-size:12.0pt;\n\tfont-family:"Times New Roman","serif";}\nspan.EmailStyle18\n\t{mso-style-type:personal-reply;\n\tfont-family:"Calibri","sans-serif";\n\tcolor:#1F497D;}\n.MsoChpDefault\n\t{mso-style-type:export-only;\n\tfont-size:10.0pt;}\[email protected] WordSection1\n\t{size:8.5in 11.0in;\n\tmargin:1.0in 1.0in 1.0in 1.0in;}\ndiv.WordSection1\n\t{page:WordSection1;}\n--> </style> 
<!--[if gte mso 9]><xml>\n<o:shapedefaults v:ext="edit" spidmax="1026" />\n</xml><![endif]--> <!--[if gte mso 9]> <xml>\n<o:shapelayoutv:ext="edit">\n<o:idmapv:ext="edit"data="1"/>\n</o:shapelayout></xml><![endif]--> 

</head> 
<body lang="EN-US" link="blue" vlink="purple"> 
<div class="WordSection1"> 
<p class="MsoNormal"><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><p>&nbsp;</p></span></p> 
<p class="MsoNormal"><a name="_MailEndCompose"><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><p>&nbsp;</p></span></a></p> 
<div><div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in"><p class="MsoNormal"><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> EMAIL SENDER NAME [mailto:[email protected]] <br><b>Sent:</b>!! DATE I NEED TO GRAB HERE !! <br><b>To:</b> EMAIL ADDRESS HERE <br><b>Subject:</b> SUBJECT LINE HERE <p></p></span></p></div></div> 

我需要獲取電子郵件的發送日期。以下是我已經試過:

label_tag_name = 'div div p span br b' 
if label_tag = @doc.at_css(%Q{#{label_tag_name}:contains("#{label}:")}) 
    @attributes[field] = label_tag.text.gsub("#{label}:",'').gsub("\\n", "").strip 
end 

我也嘗試了一些更短的路徑在label_tag_name,基本上添加另一個HTML標記的開始。

雖然每次都發送日期回來nil

+1

當您添加示例數據時,請將其作爲示例所需的裸露數量。更多的東西,你會浪費時間回答這些不必要的東西。 –

回答

2

源的你感興趣的位(爲清楚起見,我已刪除的屬性):

<div> 
    <div> 
    <p> 
     <b> 
     <span>From:</span> 
     </b> 
     <span> EMAIL SENDER NAME [mailto:[email protected]] <br> 
     <b>Sent:</b>!! DATE I NEED TO GRAB HERE !! <br> 
     <b>To:</b> EMAIL ADDRESS HERE <br> 
     <b>Subject:</b> SUBJECT LINE HERE <p></p> 
     </span></p></div></div> 

請注意,br在HTML中的標籤是自閉的,所以它沒有意義尋找它們的子元素。

目標可以用CSS div div p span描述,但要注意,有匹配的兩個節點,並at_css返回第一。您可以使用div div p>span指定p上的即時子女span。實際目標是該元素內的文本節點(現在文檔中只有一個匹配範圍)。特別是它是第一個b標籤之後的下一個元素。因此,如果我們的CSS選擇器擴大到div div p>span b,我們可以使用引入nokogiri next方法來獲取目標字符串:

date_string = @doc.at_css('div div p>span b').next 

如果你想在其他領域,你可以使用css代替at_css

date_string = @doc.css('div div p>span b')[0].next 
to_string = @doc.css('div div p>span b')[1].next 
subject_string = @doc.css('div div p>span b')[2].next 

我會留下發件人的名字給你做的事!

1

在那個文檔中沒有太多東西要導航。使用選擇,讓你到最近的點可靠然後抓住一個正則表達式的文本:

> doc.css("div.WordSection1 p.MsoNormal span").text[/Sent:\n(.*)/, 1] 
=> "   !! DATE I NEED TO GRAB HERE !! To:" 
1

我這個啓動:

require 'nokogiri' 

doc = Nokogiri::HTML(<<EOT) 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html> 
<head> 
    <title></title> 
</head> 

<body> 
    <div class="WordSection1"> 

     <div> 
      <div> 
       <b>Sent:</b>!! DATE I NEED TO GRAB HERE !!<br> 
       <b>To:</b> EMAIL ADDRESS HERE<br> 
       <b>Subject:</b> SUBJECT LINE HERE</span></p> 
      </div> 
     </div> 
    </div> 
</body> 
</html> 
EOT 

text = doc.at('div.WordSection1').text 
sent_date = text[/Sent:(.+)To:/, 1].strip 
puts sent_date 

它輸出這樣的:

!! DATE I NEED TO GRAB HERE !! 

樣本HTML是一個爛攤子,所以你不能輕易看到你在森林想要的特定樹。將所有不是導航必不可少的東西都去掉,然後建立搜索。

而且,雖然解析器是一個很好的工具,但有時使用它可以更容易地獲取所需的文本,然後通過字符串搜索來獲取特定的東西。