למה עברית בדפי Web הופכת לג'יבריש?

נוסף ב-20/08/2007 08:54 על ידי דניאל כץ

למרות שהמאמר הזה כבר פורסם באדיבות בבלוג של ג'סטין אנג'ל, אביא אותו אצלי בשנית, בעיקר בגלל שראיתי את השאלה הזאת עולה שוב ושוב בפורומים השונים.

הפתרון הבא עוסק בזיהוי נכון של קידוד דף הWeb בשימוש במחלקות כמו WebRequest. הבעיה במקרים אלו היא שלא תמיד בוני האתרים טורחים לשלוח עם הדפים שהם כותבים את הHeader (כותרת http) שמזהה את קידוד הדף, ולכן במקרים אלו צריך קודם לקרוא את הדף עד הסוף, ורק אז לשלוף את כותרת הmeta המתאימה מהדף עצמו ולקודד איתה את הדף.

זהו תסריט השימוש הרצוי:

    Sub Test()

 

        Dim connection As New CWebConnection(New Uri("http://www.tapuz.co.il/"))

        connection.SendRequest()

 

        Dim distortedContent As String = connection.GetContent

        Dim readableContent As String = connection.GetDecodedContent

 

    End Sub

וזוהי מחלקה שממשת את הדרישות והתהליך שתיארנו:

Imports System.Text

Imports System.Text.RegularExpressions

Imports System.Net

Imports System.IO

 

Public Class CWebConnection

 

    Private m_request As HttpWebRequest

    Private m_response As HttpWebResponse

    Private m_content As String

 

 

    Public Sub New(ByVal url As Uri)

        m_content = Nothing

 

        m_request = WebRequest.Create(url)

        m_request.Credentials = CredentialCache.DefaultCredentials

        m_request.Timeout = 30000

    End Sub

 

    Public Sub SendRequest()

        m_response = m_request.GetResponse()

    End Sub

 

    Public Function GetContent() As String

        If m_content = Nothing Then

            Dim dataStream As Stream = m_response.GetResponseStream()

            Using reader As New StreamReader(dataStream, Encoding.Default)

 

                m_content = reader.ReadToEnd() + vbCrLf

            End Using

        End If

 

        Return m_content

    End Function

 

    Public Function GetDecodedContent() As String

        Dim raw As String = GetContent()

        Dim dest_enc As Encoding = GetEncoding()

 

        Return ConvertEncoding(raw, Encoding.Default, dest_enc)

    End Function

 

    Public Function GetEncoding() As Encoding

        Dim pattern As String = "<\s*meta\s*http-equiv=\s*[""']content-type\s*[""']\s*content\s*=\s*[""']\s*[\w/\\]*\s*;\s*charset\s*=\s*(?<encoding>[^""';>]*)\s*[""']\s*/?\s*>"

        Dim m_RegEx As Regex

        Dim encMatch As Match

        Dim enc As Encoding = Encoding.GetEncoding("windows-1255")

 

        If m_content = Nothing Then

            Throw New Exception("First call GetContent()")

        End If

 

        If GetEncodingHeader() IsNot Nothing Then

            Return GetEncodingHeader()

        Else

            m_RegEx = New Regex(pattern, RegexOptions.IgnoreCase Or RegexOptions.Compiled)

            encMatch = m_RegEx.Match(m_content)

 

            If encMatch.Success Then

                Try

                    enc = Encoding.GetEncoding(encMatch.Groups("encoding").ToString.ToLower)

                Catch

                End Try

            End If

        End If

 

        Return enc

    End Function

 

    Public Function GetEncodingHeader() As Encoding

        Dim output As Encoding = Nothing

        If m_response.ContentEncoding <> "" Then

            Try

                output = Encoding.GetEncoding(m_response.ContentEncoding)

            Catch

                output = Nothing

            End Try

        End If

 

        Return output

    End Function

 

    Public Shared Function ConvertEncoding(ByVal raw As String, ByVal src_enc As Encoding, ByVal dest_enc As Encoding) As String

 

        Return src_enc.GetChars(Encoding.Convert(dest_enc, src_enc, src_enc.GetBytes(raw)))

 

    End Function

 

End Class

במחלקה הזאת אנו שולחים בקשה לדף ע"י המתודה SendRequest, אח"כ יכולים לקבל את הדף כמו שהוא (קידוד ברירת מחדל) ע"י הפונקציה GetContent, או לקבל את הדף בקידוד הנכון ע"י GetDecodedContent.

GetDecodedContent עובד בשני שלבים:

  1. בודק אם נשלחה כותרת הhttp, אם כן אז משתמשים בה, אם לא אז ממשיכים לשלב 2.
  2. מחפש ע"י ביטוי רגולרי את כותרת הmeta של הדף עצמו ושולפים משם את הקידוד (אם יש).

Tags: , , ,

.NET

הערות

08/11/2009 12:01:49 #

פומה

למה לא להשתמש פשוט ב UTF8?

פומה Israel

הוסף תגובה


(יציג את האייקון ה-Gravatar שלך)

  Country flag

biuquote
  • הערה
  • תצוגה מקדימה
Loading