WebページのTITLEタグの中身の文字列を抜き出したい。 への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 るきお  (社会人)
投稿日時
2011/3/1 22:28:49
おっしゃるように文字コードが異なると文字化けします。
>文字コードなども設定してみましたがうまく行きません。
今回のように「○○したが、うまくいかない」という場合は、その○○したうまくうごかないプログラムを載せていただくようお願いします。
「○○すればできますよ」という回答と、具体的なプログラムが書いてある回答とでは具体的なプログラムが書いてある回答の方がありがたいことが多いと思いますが、
質問でも同じです。
回答者が太郎さんが困っていることを推理してゼロから回答を組み立てなければいけないか、既に目の前にあるものを直せばいいだけかの違いは大きいです。
さて、本題ですが、文字コードを気にせずに正確なhtmlをダウンロードするにはバイト型の配列としてhtmlを取得します。それにはDownloadDataメソッドを使用します。
そのあと、System.Text.Encodingを使用してそのバイト型の配列を適切な文字コードで翻訳すればよいのですが、この「適切な文字コード」が何かを取得するところが一癖あります。
ひょっとすると、バイト型の配列から文字コードを判別する簡単な方法があるかもしれません。知っている方がいたら教えてください。
とりあえず、htmlのMETAタグに記載されている文字コードはhtmlの上の方にあり半角英数で構成されているタグですので、まずutf-8と仮定して読み込んで、文字コードを確認後utf-8でなければ改めて出コードしなおすという方式をとりました。
プログラムが複雑になったのでこの部分をHtmlDocumentクラスにカプセル化しました。
>文字コードなども設定してみましたがうまく行きません。
今回のように「○○したが、うまくいかない」という場合は、その○○したうまくうごかないプログラムを載せていただくようお願いします。
「○○すればできますよ」という回答と、具体的なプログラムが書いてある回答とでは具体的なプログラムが書いてある回答の方がありがたいことが多いと思いますが、
質問でも同じです。
回答者が太郎さんが困っていることを推理してゼロから回答を組み立てなければいけないか、既に目の前にあるものを直せばいいだけかの違いは大きいです。
さて、本題ですが、文字コードを気にせずに正確なhtmlをダウンロードするにはバイト型の配列としてhtmlを取得します。それにはDownloadDataメソッドを使用します。
そのあと、System.Text.Encodingを使用してそのバイト型の配列を適切な文字コードで翻訳すればよいのですが、この「適切な文字コード」が何かを取得するところが一癖あります。
ひょっとすると、バイト型の配列から文字コードを判別する簡単な方法があるかもしれません。知っている方がいたら教えてください。
とりあえず、htmlのMETAタグに記載されている文字コードはhtmlの上の方にあり半角英数で構成されているタグですので、まずutf-8と仮定して読み込んで、文字コードを確認後utf-8でなければ改めて出コードしなおすという方式をとりました。
プログラムが複雑になったのでこの部分をHtmlDocumentクラスにカプセル化しました。
Imports System.Text.RegularExpressions
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim url1 As String = "http://rucio.cloudapp.net/ThreadDetail.aspx?ThreadId=10062"
Dim url2 As String = "http://homepage1.nifty.com/rucio/main/material/UpDate.htm"
Dim html1 As New HtmlDocument(url1)
Dim html2 As New HtmlDocument(url2)
MsgBox(html1.Title & vbNewLine & html1.EncodeName)
MsgBox(html2.Title & vbNewLine & html2.EncodeName)
End Sub
End Class
Public Class HtmlDocument
Public Source As String 'VB2010ならPublic Propertyと書きたい。
Public Sub New(ByVal url As String)
DownloadHtml(url)
End Sub
Public Function DownloadHtml(ByVal url As String) As String
Dim bytes() As Byte
Using client As New Net.WebClient
bytes = client.DownloadData(url)
End Using
'まずutf-8ででコードしてみる
Dim utf8 = System.Text.Encoding.UTF8
Me.Source = utf8.GetString(bytes)
'utf8じゃなかったら指定された文字コードでデコードしなおす
Select Case Me.EncodeName
Case "UTF-8", "UTF8"
Case Else
Dim encode = System.Text.Encoding.GetEncoding(Me.EncodeName)
Me.Source = encode.GetString(bytes)
End Select
Return Me.Source
End Function
Public ReadOnly Property EncodeName As String
Get
Dim pattern As String = "\<meta.*?charset\=(.*?)\"""
Dim results = ExtractAsMatch(pattern)
Dim value As String = Nothing
If results.Count > 0 Then
For Each result As System.Text.RegularExpressions.Match In results
If result.Groups.Count > 0 Then
value = result.Groups(1).Value
Exit For
End If
Next
End If
If value Is Nothing Then
value = "utf-8"
End If
Return value
End Get
End Property
Public ReadOnly Property Title As String
Get
Dim regop As RegexOptions = RegexOptions.IgnoreCase Or RegexOptions.Singleline
Dim pattern As String = "<title.*?>(.*?)</title>"
Dim regex As New Regex(pattern, regop)
Dim match As Match = regex.Match(Me.Source)
If match.Success Then
Return match.Groups(1).Value
Else
Return ""
End If
End Get
End Property
Public Function ExtractAsMatch(ByVal expression As String) As System.Text.RegularExpressions.MatchCollection
Dim re As New Regex(expression, RegexOptions.IgnoreCase Or RegexOptions.Multiline)
Dim results = re.Matches(Me.Source)
Return results
End Function
End Class
投稿者 太郎  (社会人)
投稿日時
2011/2/25 13:23:21
すみません。
るきおさんのやり方でやると時々文字化けを起こしてしまいます。
文字コードなども設定してみましたがうまく行きません。
もしよかったらアドバイスお願いします。
るきおさんのやり方でやると時々文字化けを起こしてしまいます。
文字コードなども設定してみましたがうまく行きません。
もしよかったらアドバイスお願いします。
投稿者 太郎  (社会人)
投稿日時
2011/2/23 20:01:47
るきおさんありがとうございました。
大分早くなりました。
大分早くなりました。
投稿者 るきお  (社会人)
投稿日時
2011/2/22 22:18:08
titleタグの内容を抜き出すサンプルです。
この例ではインターネットのサイトにアクセスしてhtmlを取得していますが、
html取得までの部分はローカルのドキュメントから取得してもよいし、ほかの方法で生成してもよいです。
一般的でない書き方でtitleタグが埋め込まれている場合は、抽出条件に合致せず取得できない可能性はありますが、ほとんどのサイトでこの方法で取得できると思います。
この手法はタイトルだけ取得するのにWebページ全体を読み込んでいる点で効率はあまりよくありません。titleタグはWebページのかなり上のほうにあるはずなので、実際にはWebページを少しだけ読めばtitleタグを探せるはずです。
StreamReaderを使ってhtmlを少しずつ読んでいけば効率化は図れますが、プログラムは複雑になるでしょう。htmlをWebから取得する場合はSystem.Net.WebClient.OpenReadメソッドでStreamを取得できます。
この例ではインターネットのサイトにアクセスしてhtmlを取得していますが、
html取得までの部分はローカルのドキュメントから取得してもよいし、ほかの方法で生成してもよいです。
Dim internet As New Net.WebClient
'プロキシーを通してWebにアクセスする場合は以下の2行を復活させプロキシーのアドレスとユーザー名・パスワードを指定してください。
'internet.Proxy = New Net.WebProxy("198.100.99.99", 8080)
'internet.Credentials = New Net.NetworkCredential("rucio", "mypass")
Dim html As String = internet.DownloadString("http://www.nifty.com/")
internet.Dispose()
Dim regop As System.Text.RegularExpressions.RegexOptions = System.Text.RegularExpressions.RegexOptions.IgnoreCase Or System.Text.RegularExpressions.RegexOptions.Singleline
Dim pattern As String = "<title.*?>(.*?)</title>"
Dim regex As New System.Text.RegularExpressions.Regex(pattern, regop)
Dim match As System.Text.RegularExpressions.Match = regex.Match(html)
Dim title As String
If match.Success Then
title = match.Groups(1).Value
Else
title = ""
End If
MsgBox(title)
一般的でない書き方でtitleタグが埋め込まれている場合は、抽出条件に合致せず取得できない可能性はありますが、ほとんどのサイトでこの方法で取得できると思います。
この手法はタイトルだけ取得するのにWebページ全体を読み込んでいる点で効率はあまりよくありません。titleタグはWebページのかなり上のほうにあるはずなので、実際にはWebページを少しだけ読めばtitleタグを探せるはずです。
StreamReaderを使ってhtmlを少しずつ読んでいけば効率化は図れますが、プログラムは複雑になるでしょう。htmlをWebから取得する場合はSystem.Net.WebClient.OpenReadメソッドでStreamを取得できます。
投稿者 るきお  (社会人)
投稿日時
2011/2/22 17:19:30
<TITLE>~</TITLE>の ~ の部分を抜き出すには、
Net.WebClient.DownloadStringでhtmlを取得して、RegExでTitleを抜き出せばできます。
後で具体的なサンプルを紹介します。
Net.WebClient.DownloadStringでhtmlを取得して、RegExでTitleを抜き出せばできます。
後で具体的なサンプルを紹介します。
投稿者 太郎  (社会人)
投稿日時
2011/2/22 14:40:40
この掲示板に題名と同じような質問があったので参照してみたのですが、Webbrowserコントロールを使っており、TITLE内のテキストを抜き出そうとしたところ、物凄く時間がかかってしまいました。
Webbrowserコントロール以外の方法でTITLE内のテキストを抜き出したいのですが、方法はないでしょうか?
お願いします。
Webbrowserコントロール以外の方法でTITLE内のテキストを抜き出したいのですが、方法はないでしょうか?
お願いします。
前にも書きましたが、タグを抜き出す条件判断がとりあえずのものなので、
私が想定した書き方でタグを書いていないサイトがあれば正しいhtmlでもタイトルを抜き出せないことがあります。
この条件は正規表現で書いている部分ですので、必要であれば適宜変更してください。
また、Webブラウザはhtmlが正しくなくても表示してくれる場合が多々ありますが、私のプログラムは少なくともTitleタグと文字コードのMetaタグ近辺が正しく書かれていないとタイトルが抜き出せません。
このあたりをちゃんとやるのはかなり大変です。