DirtyなHTMLなのにXHTMLと名乗っているページをC#でスクレイピングする
C#でスクレイピング - DENKENを参考にやってみた。
元ネタはGoogleが吐いたHTMLを処理してたので(比較的キレイなHTMLなんだろう)、HTMLtoXHTMLは無事にXHTMLに変換できていたが、とある有名なブログのページを変換しようとしたら、XHTMLの宣言部が下記のように見事に壊れて、XDocument.Parse(xhtml)でXmlExceptionで落ちる。
<?xml version="1.0" encoding="Shift_JIS"="=" ?> <!DOCTYPE html="html" PUBLIC="PUBLIC" -="-" xmlns="http://www.w3.org/1999/xhtml" /> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja" xmlns:xml="urn:xml" >
XHTMLの宣言部を削って変換を掛けたらうまくいった。
// original: http://d.hatena.ne.jp/uesama99/20080219/1203394007 using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using System.Text; using HTML2XHTMLLib; using System.Net; using System.IO; namespace ScrapingSample { class Program { static void Main(string[] args) { WebClient wc = new WebClient(); string html = wc.DownloadString("http://someblog.com/somepage.html"); html = html.Replace("<?xml version=\"1.0\" encoding=\"Shift_JIS\"?>", ""); html = html.Replace("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">", ""); html = html.Replace("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"ja\" lang=\"ja\">", "<html>"); XHTMLUtilities util = new XHTMLUtilities(); string xhtml = util.convertToXHTML(html); const string XHTML = "{http://www.w3.org/1999/xhtml}"; XDocument xdoc = XDocument.Parse(xhtml); var query = from a in xdoc.Descendants(XHTML + "a") where a.Attributes("class").FirstOrDefault(atr => atr.Value == "l") != null select a; foreach (var item in query) { Console.WriteLine("Title={0}", item.Value); } Console.WriteLine("完了しました。"); Console.Read(); } } }
「XHTMLじゃないのにXHTML宣言をするのは有害」だと、どこかのページで見たが、ここでもそれが見事に当てはまってる。
#LINQのお勉強しなきゃw