برگزیده های پرشین تولز

پیدا کردن یک تگ خاص در سورس HtML

shervin

ASP.net
کاربر قدیمی پرشین تولز
تاریخ عضویت
26 ژوئن 2005
نوشته‌ها
6,353
لایک‌ها
261
سن
38
محل سکونت
تهران
من میخوام یه فایل اچ تی ام ال رو براوز کنم
بعد سورسشو بخونم

1- کل سورس صفحه رو بگیرم و تو دیتا بیس ذخیره کنم
2- داخل اون سورس یک تگ خاص که مد نظر من h3 هست رو پیدا کنم و متن بین دو تگ رو بخونم
ینی خود تگ رو نمیخوام بلکه متن بین دو تگ و انتهای تگ رو میخوام
مثلا اگه تگ اینجوری باشه
<h3>salam</h3>
میخوام salam رو بگیرم
ممنون میشم یه راهنمایی بکنید
 

Graveworm

Registered User
تاریخ عضویت
23 می 2005
نوشته‌ها
1,071
لایک‌ها
12
محل سکونت
Tehran
من میخوام یه فایل اچ تی ام ال رو براوز کنم
بعد سورسشو بخونم

1- کل سورس صفحه رو بگیرم و تو دیتا بیس ذخیره کنم
2- داخل اون سورس یک تگ خاص که مد نظر من h3 هست رو پیدا کنم و متن بین دو تگ رو بخونم
ینی خود تگ رو نمیخوام بلکه متن بین دو تگ و انتهای تگ رو میخوام
مثلا اگه تگ اینجوری باشه
<h3>salam</h3>
میخوام salam رو بگیرم
ممنون میشم یه راهنمایی بکنید

شما باید ابتدا فایل html رو به صورت متنی بخونی :

کد:
   Dim mypath As String = Server.MapPath("ToRead.htm")
        Dim myreader As IO.StreamReader = IO.File.OpenText(mypath)
        Dim tempsource As String = myreader.ReadToEnd()
        myreader.Close()

حالا با توابع string ، کار های لازم رو انجام میدی
 

shervin

ASP.net
کاربر قدیمی پرشین تولز
تاریخ عضویت
26 ژوئن 2005
نوشته‌ها
6,353
لایک‌ها
261
سن
38
محل سکونت
تهران
ممنون
ولی قسمت اصلی سوال من این بود که چجوری متن بین تگ رو بخونم
چون تگ ممکنه پراپرتی های مختلفی هم داشته باشه
یه جوری باید بشناسه که این کد html هست
 

H_R

مدیر بازنشسته
تاریخ عضویت
30 مارس 2005
نوشته‌ها
3,298
لایک‌ها
17
سن
42
محل سکونت
North Pole
والا من تا به حال توي دوتا پروژه اين كار رو كردم يكي پروژه اي كه مربوط به بورس بود يكي هم سايت خودم http://www.movie-friends.com/ كه در بار اولي كه يم فيلم رو درخواست ميكني اطلاعاتش رو در لحظه از سايت IMDB ميخونه ، بذار برات توضيح بدم كه چيكار كردم :

ببين معمولا برنامه هاي اينطوري (حالا فكر كنم اصولا ميخوايم يه سري اطلاعات خاص رو از يه سري صفحه استخراج كنيم ) اطلاعاتشون به صورت منظمه چون بالاخره بايه لوپي توليد ميشه پس شما اولين كاري كه ميكنيد نظم رعايت شده رو ميكنيد .

بعد همونطوري كه در بالا اشاره شد بايد متن رو به استرينگ تبديل كني يه حالا اگر لوكال بود به صورت استريم ميخونيش اگر روي وب بود از webclient استفاده كنيد !

بعد متد IndexOf استرينگ استفاده ميكني و قسمتهايي كه لازم داري رو پيدا ميكني ! حالا بالا و پايين اين قسمت ها رو حذف ميكني بعد (با متد هاي استرينگ ) با چند تا replace و substring و يه كمي خلاقيت ميتوني اطلاعاتت رو استخراج كني !

ولي يه روش ديگه هم هست كه همانا استفاده XML اه كه من دنبالش نرفتم تا حالا براي اين كار !
 

shervin

ASP.net
کاربر قدیمی پرشین تولز
تاریخ عضویت
26 ژوئن 2005
نوشته‌ها
6,353
لایک‌ها
261
سن
38
محل سکونت
تهران
ممنون حسین جان
آخه این کاری که من میکنم هیچ نظمی نداره
ینی صفحات از جاهای مختله و شبیه هم نیست
تو یکی میخوام تگ h3 بخونم یکی h2 یکی دایو و ......
بعد میگم کل تگ رو نمیخوام بخونم فقط متن بینشو و به خود تگ هیچ نیازی نیست
ینی هرچی فکر میکنم راهی جز این نیست که یه جوری بتونم این متن رو به عنوان یک متن اچ تی ام ال معرفی کنم بعد بگم حالا تگ فلان رو پیدا کن
به خاطر مختلف بودن فایل ها و تگ های مورد نیاز نمیشه توش بگردم و بقیه رو حذف کنم
نمیدونم منظورمو خوب رسوندم یا نه
 

H_R

مدیر بازنشسته
تاریخ عضویت
30 مارس 2005
نوشته‌ها
3,298
لایک‌ها
17
سن
42
محل سکونت
North Pole
خوب دیگه ببین تو باید حد اقل یه چیزی گیر بیاری که توی اون قسمتی که میخواد یونیک باشه !
حالا با داشتن این چیز یونیک میتونی دقیقا ایندکس اون قسمت رو پیدا کنی بعد بشمری بینی اون تگ (یا حتی تگ ها ) چند کاراکتره ! مثلا فرض میکنیم تو فهمیدی که این توی صفحه:

کد:
<fieldset class="fieldset">
     <legend>Thread Subscription</legend>
     <table cellpadding="0" cellspacing="3" border="0">
     <tr>
      <td>Notification Type:<br /><select name="emailupdate" tabindex="1">
       <option value="9999" selected="selected">Do not subscribe</option>
       <option value="0" >No email notification</option>
       <option value="1" >Instant email notification</option>
       <option value="2" >Daily email notification</option>

این یونیکه
کد:
<fieldset class="fieldset">

خوب حالا مثلا No email notification رو میخوای ! خوب اول میای ایدکس <fieldset class="fieldset"> رو پیدا میکنی بعد میشمری میبینی تا اونجایی که میخوای چند کاراکتر داری ( به شرطی که اون قسمت توی همه صفحه هات ثابت باشه حالا همه چی رو تا سر No email notification پاک میکنی تا اشتباه نا خواسته ای پیش نیاد بعد میای ایندکس اولین تگ بعدش رو رو میگیری مثلا ایندکس > رو و بومب (!) تمومه حالا میتونی یه ساب استرینگ بگیری از اول متن ( که شروع جایی اه که نیاز داری تا ایندکس جدید اولین تگ HTML و من به تجربه میدونم که همیشه میشه این کار رو کرد ممکنه کمی سخت به نظر بیاد ولی اگر خلاقیتت رو به کار بندازی حتما انجام میشه !
 

balabala

کاربر قدیمی پرشین تولز
کاربر قدیمی پرشین تولز
تاریخ عضویت
22 می 2005
نوشته‌ها
8,362
لایک‌ها
5,745
سن
41
محل سکونت
یه خورده اونورتر
با توابع string میشه. با InStr ابتدا و انتهاش رو پیدا کن بعد با تابع Mid وسطش رو بخون.
 

m3hrz4d

Registered User
تاریخ عضویت
21 سپتامبر 2005
نوشته‌ها
620
لایک‌ها
1
محل سکونت
اصفهان
برای این کار حداقل 2 تا هست. یکی استفاده از Regular Expressions و یکی هم استفاده از شی HtmlFile.
البته فکر کنم خود .Net هم کلاس هایی واسه این کار داشته باشه اما من باش کار نکردم.
راه RegExp احتمال خطاش هست(اما خیلی کم) ولی سریع تر از HtmlFile هست.
با HtmlFile شما کل صفحه رو توی یک Object از نوع Html Document داری و میتونی با استفاده از اندیس آرایه به همه ی Tag هاش و محتویات اون ها دسترسی پیدا کنی, مثل وقتی که داری جاوااسکریپت مینویسی :
کد:
<%@Page Language="VB"  aspcompat=true %>

<script language="VB" runat="Server">

Dim Doc As Object, MDoc As Object


Private Sub Page_Load(Sender As Object, E as EventArgs)

	Dim strHtml As String =  "<html><body>hello<h1 att1=val1></h1><h2 attr2=val2>This <b>Is</b> H2</h2>bye</body></html>"

	If ( InitialiseDocs(strHtml) ) Then
		Response.Write(GetTagContents("H2"))
		Call UninitialiseDocs()
	Else
		Response.Write("Unable To Initialise!")
	End If


End Sub

Private Function InitialiseDocs(Byref HtmlCode As String) As Boolean

	If (HtmlCode.Length = 0) Then Return False

	Call UninitialiseDocs()

	Try	
		Doc = Server.CreateObject("HtmlFile")
		Doc.Write(HtmlCode)
		MDoc = Doc.documentElement
	Catch
		Call UninitialiseDocs()
		Return False
	End Try
	
	Return True

End Function

Private Sub UninitialiseDocs()

	MDoc = Nothing	
	Doc = Nothing

End Sub

' Utility Functions...

Private Function GetTagContents(TagName As String) As String
	
	Dim i As Integer
	
	Try
	
		For i = 0 to Mdoc.all.length - 1 Step 1
	
			If (Mdoc.all(i).tagName = TagName) Then Return Mdoc.all(i).innerHtml
			
		Next
	Catch
		
	End Try
	
	Return ""

End Function


</script>

<form runat="Server">
</form>

اینجا تابع GetTagContents محتویات (InnerHtml) اولین تگی رو که اسمش TagName باشه رو پیدا میکنه...خودت با استفاده از این الگو میتونی شرایط رو عوض کنی.

برای استفاده از Regular Expressions هم باید بگی دقیقا چی میخوای(اولین تگ؟ همه؟...) تا بنویسم برات.
 

shervin

ASP.net
کاربر قدیمی پرشین تولز
تاریخ عضویت
26 ژوئن 2005
نوشته‌ها
6,353
لایک‌ها
261
سن
38
محل سکونت
تهران
حسین جان خود شما تو پرانتز گفتی که به شرطی که اون قسمت تو همه صفحات یکسان باشه
درصورتی که من گفتم یکسان نیست
ینی هر دو فایل با هم فرق دارن
خب با این روش من برای هر فایل باید این کارو بکنم
خب اینجوری میرم دستی میخونم اون تگ رو دیگه , نه؟
 

shervin

ASP.net
کاربر قدیمی پرشین تولز
تاریخ عضویت
26 ژوئن 2005
نوشته‌ها
6,353
لایک‌ها
261
سن
38
محل سکونت
تهران
با توابع string میشه. با InStr ابتدا و انتهاش رو پیدا کن بعد با تابع Mid وسطش رو بخون.

برای این کار حداقل 2 تا هست. یکی استفاده از Regular Expressions و یکی هم استفاده از شی HtmlFile.
البته فکر کنم خود .Net هم کلاس هایی واسه این کار داشته باشه اما من باش کار نکردم.
راه RegExp احتمال خطاش هست(اما خیلی کم) ولی سریع تر از HtmlFile هست.
با HtmlFile شما کل صفحه رو توی یک Object از نوع Html Document داری و میتونی با استفاده از اندیس آرایه به همه ی Tag هاش و محتویات اون ها دسترسی پیدا کنی, مثل وقتی که داری جاوااسکریپت مینویسی :
کد:
<%@Page Language="VB"  aspcompat=true %>

<script language="VB" runat="Server">

Dim Doc As Object, MDoc As Object


Private Sub Page_Load(Sender As Object, E as EventArgs)

	Dim strHtml As String =  "<html><body>hello<h1 att1=val1></h1><h2 attr2=val2>This <b>Is</b> H2</h2>bye</body></html>"

	If ( InitialiseDocs(strHtml) ) Then
		Response.Write(GetTagContents("H2"))
	Else
		Response.Write("Unable To Initalise!")
	End If
	Call UninitialiseDocs()

End Sub

Private Function InitialiseDocs(Byref HtmlCode As String) As Boolean

	If (HtmlCode.Length = 0) Then Return False

	Call UninitialiseDocs()

	Try	
		Doc = Server.CreateObject("HtmlFile")
		Doc.Write(HtmlCode)
		MDoc = Doc.documentElement
	Catch
		Call UninitialiseDocs()
		Return False
	End Try
	
	Return True

End Function

Private Sub UninitialiseDocs()

	MDoc = Nothing	
	Doc = Nothing

End Sub

' Utility Functions...

Private Function GetTagContents(TagName As String) As String
	
	Dim i As Integer
	
	Try
	
		For i = 0 to Mdoc.all.length Step 1
	
			If (Mdoc.all(i).tagName = TagName) Then Return Mdoc.all(i).innerHtml
			
		Next
	Catch
		
	End Try
	
	Return ""

End Function


</script>

<form runat="Server">
</form>

اینجا تابع GetTagContents محتویات (InnerHtml) اولین تگی رو که اسمش TagName باشه رو پیدا میکنه...خودت با استفاده از این الگو میتونی شرایط رو عوض کنی.

برای استفاده از Regular Expressions هم باید بگی دقیقا چی میخوای(اولین تگ؟ همه؟...) تا بنویسم برات.
ممنون میرم رو هر سه روش تحقیق میکنم ببینم به کجا میرسم
 

shervin

ASP.net
کاربر قدیمی پرشین تولز
تاریخ عضویت
26 ژوئن 2005
نوشته‌ها
6,353
لایک‌ها
261
سن
38
محل سکونت
تهران
آقا من گشتم ولی چیزی پیدا نکردم در مورد این htmlfile که گفتید
این کد که وی بی دات نت نبود که بتونم استفاده کنم هیچ چیزی هم هر چی سرچ کردم نتونستم پیدا کنم
میشه وی بی دات نتش بزارید برام؟
البته اگه زحمتی نیست
 

m3hrz4d

Registered User
تاریخ عضویت
21 سپتامبر 2005
نوشته‌ها
620
لایک‌ها
1
محل سکونت
اصفهان
این کد که من گذاشتم ASP.NET به زبان VB بود و شما هم توی قسمت ASP.NET پست زدی!! کل کد رو توی یک فایل ASPX کپی کن ببین کار میکنه...
اگه VB Application میخواستی باید توی برنامه نویسی پست میزدی..من که سر در نمی آرم! :D
اینClass اونقدر ها هم رایج نیست که با یه سرچ کلی چیز بتونی پیدا کنی.

حالا VB Application میخوای بگو تا بنویسم (توابع همون هستن فقط نحوی ی نشون دادن نتیجه فرق میکنه!) اما جاش اینجا نیست ها..
 

shervin

ASP.net
کاربر قدیمی پرشین تولز
تاریخ عضویت
26 ژوئن 2005
نوشته‌ها
6,353
لایک‌ها
261
سن
38
محل سکونت
تهران
این کد که من گذاشتم ASP.NET به زبان VB بود و شما هم توی قسمت ASP.NET پست زدی!! کل کد رو توی یک فایل ASPX کپی کن ببین کار میکنه...
اگه VB Application میخواستی باید توی برنامه نویسی پست میزدی..من که سر در نمی آرم! :D
اینClass اونقدر ها هم رایج نیست که با یه سرچ کلی چیز بتونی پیدا کنی.

حالا VB Application میخوای بگو تا بنویسم (توابع همون هستن فقط نحوی ی نشون دادن نتیجه فرق میکنه!) اما جاش اینجا نیست ها..
آخه معمولا کد هایی که تو وب کار میکنه توی ویندوز اپ هم کار میکنه و از اونجایی که اینجا فعال تره گفتم در قالب وب اپ بپرسم و تو وین استفاده کنم
حالا هم مشکلی ندارم چون این کارو برای کار خودم میخوام میتونم به صورت وب اپ درست کنم و لوکال باهاش کار کنم
ولی اگه اون مدلیشم بزارید ممنون میشم ولی نزاریدم همونجوری میتونم استفادش کنم
شرمنده که اذیت کردم:D
 

balabala

کاربر قدیمی پرشین تولز
کاربر قدیمی پرشین تولز
تاریخ عضویت
22 می 2005
نوشته‌ها
8,362
لایک‌ها
5,745
سن
41
محل سکونت
یه خورده اونورتر
این کد ویبی 6 چیزی که گفتم:

کد:
Dim txt As String
Dim txt2 As String
txt = "stuff<h1>testing</h1>"
i = InStr(txt, "<h1>") + 4 ' 4 = len of <h1>
i2 = InStr(i, txt, "</h1>")
txt2 = Mid(txt, i, i2 - i)
 

m3hrz4d

Registered User
تاریخ عضویت
21 سپتامبر 2005
نوشته‌ها
620
لایک‌ها
1
محل سکونت
اصفهان
یک TextBox از نوع MultiLine توی فرم به اسم txtHtmlCode و یک TextBox به اسم txtTagName و یک دکمه به اسم btnGetTagContents توی فرم بساز:
کد:
Public Class Form1

    Dim Doc As Object, MDoc As Object

    Private Sub btnGetTagContents_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetTagContents.Click

        If (InitialiseDocs(txtHtmlCode.Text) = True) Then

            MsgBox(GetTagContents(txtTagName.Text), MsgBoxStyle.Information)

        Else

            MsgBox("Unable to initialise Objects", MsgBoxStyle.Exclamation, "Error")

        End If

        UninitialiseDocs()


    End Sub

    Private Function InitialiseDocs(ByRef HtmlCode As String) As Boolean

        If (HtmlCode.Length = 0) Then Return False

        Call UninitialiseDocs()

        Try
            Doc = CreateObject("HtmlFile")
            Doc.Write(HtmlCode)
            MDoc = Doc.documentElement
        Catch
            Call UninitialiseDocs()
            Return False
        End Try

        Return True

    End Function

    Private Sub UninitialiseDocs()

        MDoc = Nothing
        Doc = Nothing

    End Sub

    ' Utility Functions...

    Private Function GetTagContents(ByVal TagName As String) As String

        Dim i As Integer

        TagName = TagName.ToUpper()

        Try

            For i = 0 To Mdoc.all.length - 1 Step 1

                If (MDoc.all(i).tagName = TagName) Then Return MDoc.all(i).innerHtml

            Next
        Catch

        End Try

        Return ""

    End Function

End Class
با زدن دکمه, محتوای اولین تگ با نوعی که توی txtTagName نوشتی (مثلا h3) رو از توی کدی که توی txtHtmlCode نوشتی رو نشون میده..
ضمن اینکه اینجا چون هر بار دکمه زده میشه ممکنه HtmlCode تغییر کرده باشه, هر دفعه Initialise و Uninitialise فراخوانی میشه, اگه روی یک کد میخوای کار های مختلف رو انجام بدی فقط 1 بار باید Initialise رو فراخوانی کنی, چون این تابع هرچی کمتر Call بشه بهتره.
 

shervin

ASP.net
کاربر قدیمی پرشین تولز
تاریخ عضویت
26 ژوئن 2005
نوشته‌ها
6,353
لایک‌ها
261
سن
38
محل سکونت
تهران
آقا دست گلت درد نکنه
ترکوندی
 

miladkdz

کاربر تازه وارد
تاریخ عضویت
30 آگوست 2003
نوشته‌ها
172
لایک‌ها
0
سن
35
محل سکونت
Tehran, Ekbatan
کسی Regexp رو پیشنهاد نکرده! چرا؟!
 

m3hrz4d

Registered User
تاریخ عضویت
21 سپتامبر 2005
نوشته‌ها
620
لایک‌ها
1
محل سکونت
اصفهان
کسی Regexp رو پیشنهاد نکرده! چرا؟!

من پیشنهاد کردم به دوستمون گفتم اگه میخواد مینویسم منتها RegExp برای Parse کردن یک کد Html هر جوری هم که نوشته بشه احتمال خطاش وجود داره, گرچه سرعتش بیشتره! اونی که میخواد استفاده کنه باید ببینه سرعت مهمتره یا دقت.خودم توی یک پروژه بخاطر سرعت مجبور شدم قید دقت 100% رو بزنم..
 
بالا