正規表現を使用してHTMLリンクを抽出する方法
このチュートリアルでは、HTMLページからハイパーリンクを抽出する方法を示します。 たとえば、次のコンテンツからリンクを取得するには:
this is text1 hello this is text2...
-
最初に
a
タグから「値」を取得します–結果:a href='example.com' target='_blank'
-
後で上記の抽出値から「リンク」を取得します–結果:
example.com
1. 正規表現パターン
タグの正規表現パターンを抽出する
(?i)]+)>(.+?)
タグの正規表現パターンからリンクを抽出
\s*(?i)href\s*=\s*(\"([^"]*\")|'[^']*'|([^'">\s]+));
説明
( #start of group #1 ?i # all checking are case insensive ) #end of group #1 ]+ # anything except (">"), at least one character ) # end of group #2 > # follow by ">" (.+?) # match anything # end with "
\s* #can start with whitespace (?i) # all checking are case insensive href # follow by "href" word \s*=\s* # allows spaces on either side of the equal sign, ( # start of group #1 "([^"]*") # allow string with double quotes enclosed - "string" | # ..or '[^']*' # allow string with single quotes enclosed - 'string' | # ..or ([^'">]+) # can't contains one single quotes, double quotes ">" ) # end of group #1
2. Java Link Extractorの例
これは、1番目のパターンからa
タグ値を抽出し、2番目のパターンを使用して1番目のパターンからリンクを抽出する簡単なJavaリンク抽出の例です。
HTMLLinkExtractor.java
package com.example.crawler.core; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; public class HTMLLinkExtractor { private Pattern patternTag, patternLink; private Matcher matcherTag, matcherLink; private static final String HTML_A_TAG_PATTERN = "(?i)]+)>(.+?)"; private static final String HTML_A_HREF_TAG_PATTERN = "\\s*(?i)href\\s*=\\s*(\"([^\"]*\")|'[^']*'|([^'\">\\s]+))"; public HTMLLinkExtractor() { patternTag = Pattern.compile(HTML_A_TAG_PATTERN); patternLink = Pattern.compile(HTML_A_HREF_TAG_PATTERN); } /** * Validate html with regular expression * * @param html * html content for validation * @return Vector links and link text */ public VectorgrabHTMLLinks(final String html) { Vector result = new Vector (); matcherTag = patternTag.matcher(html); while (matcherTag.find()) { String href = matcherTag.group(1); // href String linkText = matcherTag.group(2); // link text matcherLink = patternLink.matcher(href); while (matcherLink.find()) { String link = matcherLink.group(1); // link HtmlLink obj = new HtmlLink(); obj.setLink(link); obj.setLinkText(linkText); result.add(obj); } } return result; } class HtmlLink { String link; String linkText; HtmlLink(){}; @Override public String toString() { return new StringBuffer("Link : ").append(this.link) .append(" Link Text : ").append(this.linkText).toString(); } public String getLink() { return link; } public void setLink(String link) { this.link = replaceInvalidChar(link); } public String getLinkText() { return linkText; } public void setLinkText(String linkText) { this.linkText = linkText; } private String replaceInvalidChar(String link){ link = link.replaceAll("'", ""); link = link.replaceAll("\"", ""); return link; } } }
3. 単体テスト
TestNGを使用した単体テスト。 @DataProvider
を介してHTMLコンテンツをシミュレートします。
TestHTMLLinkExtractor.java
package com.example.crawler.core; import java.util.Vector; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import com.example.crawler.core.HTMLLinkExtractor.HtmlLink; /** * HTML link extrator Testing * * @author example * */ public class TestHTMLLinkExtractor { private HTMLLinkExtractor htmlLinkExtractor; String TEST_LINK = "http://www.google.com"; @BeforeClass public void initData() { htmlLinkExtractor = new HTMLLinkExtractor(); } @DataProvider public Object[][] HTMLContentProvider() { return new Object[][] { new Object[] { "abc hahaha google" }, new Object[] { "abc hahaha google" }, new Object[] { "abc hahaha google , " + "abc hahaha google" }, new Object[] { "abc hahaha google" }, new Object[] { "abc hahaha google" }, new Object[] { "abc hahaha google" }, new Object[] { "abc hahaha google" }, }; } @Test(dataProvider = "HTMLContentProvider") public void ValidHTMLLinkTest(String html) { Vectorlinks = htmlLinkExtractor.grabHTMLLinks(html); //there must have something Assert.assertTrue(links.size() != 0); for (int i = 0; i < links.size(); i++) { HtmlLink htmlLinks = links.get(i); //System.out.println(htmlLinks); Assert.assertEquals(htmlLinks.getLink(), TEST_LINK); } } }
結果
[TestNG] Running: /private/var/folders/w8/jxyz5pf51lz7nmqm_hv5z5br0000gn/T/testng-eclipse--530204890/testng-customsuite.xml PASSED: ValidHTMLLinkTest("abc hahaha google") PASSED: ValidHTMLLinkTest("abc hahaha google") PASSED: ValidHTMLLinkTest("abc hahaha google , abc hahaha google") PASSED: ValidHTMLLinkTest("abc hahaha google") PASSED: ValidHTMLLinkTest("abc hahaha google") PASSED: ValidHTMLLinkTest("abc hahaha google") PASSED: ValidHTMLLinkTest("abc hahaha google")